Skip to content

Commit c927f8a

Browse files
committed
Slot2: Add Slide Controller
1 parent 0b027d8 commit c927f8a

File tree

15 files changed

+357
-33
lines changed

15 files changed

+357
-33
lines changed

desmume/src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ libdesmume_a_SOURCES = \
9696
addons/slot2_rumblepak.cpp \
9797
addons/slot2_guitarGrip.cpp \
9898
addons/slot2_hcv1000.cpp \
99+
addons/slot2_slideController.cpp \
99100
addons/slot2_expMemory.cpp \
100101
addons/slot2_piano.cpp \
101102
addons/slot2_passme.cpp \
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
/*
2+
Copyright (C) 2023 DeSmuME team
3+
4+
This file is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation, either version 2 of the License, or
7+
(at your option) any later version.
8+
9+
This file is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with the this software. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
//Absolute barebones implementation of the Slide Controller add-on. Rumble is not implemented.
19+
//The game does a bunch of mystery reads of various sizes which have not been investigated at all.
20+
21+
#include "../slot2.h"
22+
#include "../emufile.h"
23+
24+
#define SC_BITIN(X, Y) \
25+
do { \
26+
X = (X << 1) | (Y & 1); \
27+
bitsWritten++; \
28+
} while (0)
29+
30+
#define SC_BITOUT(X, Y) \
31+
do { \
32+
X = ((Y >> 7 - bitsRead) & 1); \
33+
bitsRead++; \
34+
} while(0)
35+
36+
u8 motionStatus;
37+
u8 xMotion;
38+
u8 yMotion;
39+
40+
class Slot2_SlideController : public ISlot2Interface
41+
{
42+
private:
43+
u8 prevClock;
44+
u8 bitsWritten;
45+
u8 bitsRead;
46+
u8 inByte;
47+
u16 regSel;
48+
49+
u8 configBits;
50+
u8 framePeriodLower;
51+
u8 framePeriodUpper;
52+
public:
53+
54+
virtual Slot2Info const* info()
55+
{
56+
static Slot2InfoSimple info("Slide Controller", "Slide Controller add-on", 0x0A);
57+
return &info;
58+
}
59+
60+
virtual void connect()
61+
{
62+
prevClock = 0;
63+
bitsWritten = 0;
64+
bitsRead = 0;
65+
inByte = 0;
66+
regSel = 0xFFFF;
67+
68+
motionStatus = 0;
69+
xMotion = 0;
70+
yMotion = 0;
71+
configBits = 0;
72+
framePeriodLower = 0x20;
73+
framePeriodUpper = 0xD1;
74+
}
75+
76+
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val)
77+
{
78+
if (addr == 0x081E0000)
79+
{
80+
if ((prevClock == 0) && (val & 0x2) && (val & 0x8))
81+
{
82+
SC_BITIN(inByte, val);
83+
if (bitsWritten == 8)
84+
{
85+
bitsWritten = 0;
86+
if (regSel == 0xFFFF) //First byte written
87+
{
88+
regSel = inByte;
89+
}
90+
else //Second byte written
91+
{
92+
//printf("WRITE TO REG: %02X = %02X\n", regSel & 0x7F , inByte);
93+
switch (regSel & 0x7F)
94+
{
95+
case 0x0A: //Config bits
96+
configBits = inByte;
97+
break;
98+
case 0x10: //Frame period (lower)
99+
framePeriodLower = inByte;
100+
break;
101+
case 0x11: //Frame period(upper)
102+
framePeriodUpper = inByte;
103+
break;
104+
}
105+
regSel = 0xFFFF;
106+
}
107+
}
108+
}
109+
prevClock = (val & 0x2) >> 1;
110+
}
111+
112+
if (configBits & 0x80) //Reset
113+
{
114+
motionStatus = 0;
115+
xMotion = 0;
116+
yMotion = 0;
117+
configBits = 0;
118+
framePeriodLower = 0x20;
119+
framePeriodUpper = 0xD1;
120+
121+
prevClock = 0;
122+
bitsWritten = 0;
123+
bitsRead = 0;
124+
inByte = 0;
125+
regSel = 0xFFFF;
126+
}
127+
}
128+
129+
virtual u8 readByte(u8 PROCNUM, u32 addr)
130+
{
131+
if (addr == 0x080000B2)
132+
{
133+
return 0x96;
134+
}
135+
return 0xFF;
136+
}
137+
138+
virtual u16 readWord(u8 PROCNUM, u32 addr)
139+
{
140+
u16 outWord = 0;
141+
142+
if (addr < 0x08000100)
143+
{
144+
outWord = 0xFEF0;
145+
}
146+
147+
if (addr == 0x081E0000)
148+
{
149+
switch (regSel)
150+
{
151+
case 0x00: //Product ID
152+
SC_BITOUT(outWord, 0x3);
153+
break;
154+
case 0x01: //Revision ID
155+
SC_BITOUT(outWord, 0x20); //Is this correct?
156+
break;
157+
case 0x02: //Motion status
158+
SC_BITOUT(outWord, motionStatus);
159+
if (bitsRead == 8) motionStatus = 0;
160+
break;
161+
case 0x03: //X motion delta
162+
SC_BITOUT(outWord, xMotion);
163+
if (bitsRead == 8) xMotion = 0;
164+
break;
165+
case 0x04: //Y motion delta
166+
SC_BITOUT(outWord, yMotion);
167+
if (bitsRead == 8) yMotion = 0;
168+
break;
169+
case 0x05: //Surface quality
170+
SC_BITOUT(outWord, 128);
171+
break;
172+
case 0x06: //Average pixel
173+
SC_BITOUT(outWord, 32);
174+
break;
175+
case 0x07: //Maximum pixel
176+
SC_BITOUT(outWord, 63);
177+
break;
178+
case 0x0A: //Configuration bits
179+
SC_BITOUT(outWord, configBits);
180+
break;
181+
case 0x0C: //Data out (lower)
182+
SC_BITOUT(outWord, 0);
183+
break;
184+
case 0x0D: //Data out (upper)
185+
SC_BITOUT(outWord, 0);
186+
break;
187+
case 0x0E: //Shutter value (lower)
188+
SC_BITOUT(outWord, 64);
189+
break;
190+
case 0x0F: //Shutter value (upper)
191+
SC_BITOUT(outWord, 0);
192+
break;
193+
case 0x10: //Frame period (lower)
194+
SC_BITOUT(outWord, framePeriodLower);
195+
break;
196+
case 0x11: //Frame period (upper)
197+
SC_BITOUT(outWord, framePeriodUpper);
198+
break;
199+
}
200+
201+
if (bitsRead == 8)
202+
{
203+
bitsRead = 0;
204+
//printf("READ FROM REG: %02X\n", regSel);
205+
regSel = 0xFFFF;
206+
}
207+
}
208+
209+
return outWord;
210+
}
211+
212+
virtual void savestate(EMUFILE& os)
213+
{
214+
s32 version = 0;
215+
os.write_32LE(version);
216+
217+
os.write_u8(prevClock);
218+
os.write_u8(bitsWritten);
219+
os.write_u8(bitsRead);
220+
os.write_u8(inByte);
221+
os.write_16LE(regSel);
222+
223+
os.write_u8(configBits);
224+
os.write_u8(framePeriodLower);
225+
os.write_u8(framePeriodUpper);
226+
os.write_u8(motionStatus);
227+
os.write_u8(xMotion);
228+
os.write_u8(yMotion);
229+
}
230+
231+
virtual void loadstate(EMUFILE& is)
232+
{
233+
s32 version = is.read_s32LE();
234+
235+
if (version == 0)
236+
{
237+
is.read_u8(prevClock);
238+
is.read_u8(bitsWritten);
239+
is.read_u8(bitsRead);
240+
is.read_u8(inByte);
241+
is.read_16LE(regSel);
242+
243+
is.read_u8(configBits);
244+
is.read_u8(framePeriodLower);
245+
is.read_u8(framePeriodUpper);
246+
is.read_u8(motionStatus);
247+
is.read_u8(xMotion);
248+
is.read_u8(yMotion);
249+
}
250+
}
251+
};
252+
253+
ISlot2Interface* construct_Slot2_SlideController() { return new Slot2_SlideController(); }
254+
255+
void slideController_updateMotion(s8 x, s8 y)
256+
{
257+
xMotion = (u8)x;
258+
yMotion = (u8)y;
259+
if (xMotion || yMotion)
260+
motionStatus = 0x80;
261+
}
262+
263+
#undef SC_BITIN
264+
#undef SC_BITOUT

desmume/src/frontend/interface/meson.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ libdesmume_src += [
109109
'../../utils/tinyxml/tinyxmlerror.cpp',
110110
'../../utils/tinyxml/tinyxmlparser.cpp',
111111
'../../utils/colorspacehandler/colorspacehandler.cpp',
112-
'../../addons/slot2_auto.cpp', '../../addons/slot2_mpcf.cpp', '../../addons/slot2_paddle.cpp', '../../addons/slot2_gbagame.cpp', '../../addons/slot2_none.cpp', '../../addons/slot2_rumblepak.cpp', '../../addons/slot2_guitarGrip.cpp', '../../addons/slot2_hcv1000.cpp', '../../addons/slot2_expMemory.cpp', '../../addons/slot2_piano.cpp', '../../addons/slot2_passme.cpp', '../../addons/slot1_none.cpp', '../../addons/slot1_r4.cpp', '../../addons/slot1_retail_nand.cpp', '../../addons/slot1_retail_auto.cpp', '../../addons/slot1_retail_mcrom.cpp', '../../addons/slot1_retail_mcrom_debug.cpp', '../../addons/slot1comp_mc.cpp', '../../addons/slot1comp_rom.cpp', '../../addons/slot1comp_protocol.cpp',
112+
'../../addons/slot2_auto.cpp', '../../addons/slot2_mpcf.cpp', '../../addons/slot2_paddle.cpp', '../../addons/slot2_gbagame.cpp', '../../addons/slot2_none.cpp', '../../addons/slot2_rumblepak.cpp', '../../addons/slot2_guitarGrip.cpp', '../../addons/slot2_hcv1000.cpp', '../../addons/slot2_slideController.cpp', '../../addons/slot2_expMemory.cpp', '../../addons/slot2_piano.cpp', '../../addons/slot2_passme.cpp', '../../addons/slot1_none.cpp', '../../addons/slot1_r4.cpp', '../../addons/slot1_retail_nand.cpp', '../../addons/slot1_retail_auto.cpp', '../../addons/slot1_retail_mcrom.cpp', '../../addons/slot1_retail_mcrom_debug.cpp', '../../addons/slot1comp_mc.cpp', '../../addons/slot1comp_rom.cpp', '../../addons/slot1comp_protocol.cpp',
113113
'../../cheatSystem.cpp',
114114
'../../texcache.cpp', '../../rasterize.cpp',
115115
'../../metaspu/metaspu.cpp',

desmume/src/frontend/interface/windows/DeSmuME_Interface.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@
269269
<ClCompile Include="..\..\..\addons\slot2_gbagame.cpp" />
270270
<ClCompile Include="..\..\..\addons\slot2_guitarGrip.cpp" />
271271
<ClCompile Include="..\..\..\addons\slot2_hcv1000.cpp" />
272+
<ClCompile Include="..\..\..\addons\slot2_slideController.cpp" />
272273
<ClCompile Include="..\..\..\addons\slot2_none.cpp" />
273274
<ClCompile Include="..\..\..\addons\slot2_rumblepak.cpp" />
274275
<ClCompile Include="..\..\..\utils\guid.cpp" />

desmume/src/frontend/interface/windows/DeSmuME_Interface.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@
135135
<ClCompile Include="..\..\..\addons\slot2_hcv1000.cpp">
136136
<Filter>addons</Filter>
137137
</ClCompile>
138+
<ClCompile Include="..\..\..\addons\slot2_slideController.cpp">
139+
<Filter>addons</Filter>
140+
</ClCompile>
138141
<ClCompile Include="..\..\..\addons\slot2_none.cpp">
139142
<Filter>addons</Filter>
140143
</ClCompile>

desmume/src/frontend/posix/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ libdesmume_a_SOURCES = \
9898
../../utils/tinyxml/tinyxmlparser.cpp \
9999
../../utils/glcorearb.h \
100100
../../utils/colorspacehandler/colorspacehandler.cpp ../../utils/colorspacehandler/colorspacehandler.h \
101-
../../addons/slot2_auto.cpp ../../addons/slot2_mpcf.cpp ../../addons/slot2_paddle.cpp ../../addons/slot2_gbagame.cpp ../../addons/slot2_none.cpp ../../addons/slot2_rumblepak.cpp ../../addons/slot2_guitarGrip.cpp ../../addons/slot2_hcv1000.cpp ../../addons/slot2_expMemory.cpp ../../addons/slot2_piano.cpp ../../addons/slot2_passme.cpp ../../addons/slot1_none.cpp ../../addons/slot1_r4.cpp ../../addons/slot1_retail_nand.cpp ../../addons/slot1_retail_auto.cpp ../../addons/slot1_retail_mcrom.cpp ../../addons/slot1_retail_mcrom_debug.cpp ../../addons/slot1comp_mc.cpp ../../addons/slot1comp_mc.h ../../addons/slot1comp_rom.h ../../addons/slot1comp_rom.cpp ../../addons/slot1comp_protocol.h ../../addons/slot1comp_protocol.cpp \
101+
../../addons/slot2_auto.cpp ../../addons/slot2_mpcf.cpp ../../addons/slot2_paddle.cpp ../../addons/slot2_gbagame.cpp ../../addons/slot2_none.cpp ../../addons/slot2_rumblepak.cpp ../../addons/slot2_guitarGrip.cpp ../../addons/slot2_hcv1000.cpp ../../addons/slot2_slideController.cpp ../../addons/slot2_expMemory.cpp ../../addons/slot2_piano.cpp ../../addons/slot2_passme.cpp ../../addons/slot1_none.cpp ../../addons/slot1_r4.cpp ../../addons/slot1_retail_nand.cpp ../../addons/slot1_retail_auto.cpp ../../addons/slot1_retail_mcrom.cpp ../../addons/slot1_retail_mcrom_debug.cpp ../../addons/slot1comp_mc.cpp ../../addons/slot1comp_mc.h ../../addons/slot1comp_rom.h ../../addons/slot1comp_rom.cpp ../../addons/slot1comp_protocol.h ../../addons/slot1comp_protocol.cpp \
102102
../../cheatSystem.cpp ../../cheatSystem.h \
103103
../../texcache.cpp ../../texcache.h ../../rasterize.cpp ../../rasterize.h \
104104
../../metaspu/metaspu.cpp ../../metaspu/metaspu.h \

desmume/src/frontend/posix/meson.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ libdesmume_src = [
104104
'../../utils/tinyxml/tinyxmlerror.cpp',
105105
'../../utils/tinyxml/tinyxmlparser.cpp',
106106
'../../utils/colorspacehandler/colorspacehandler.cpp',
107-
'../../addons/slot2_auto.cpp', '../../addons/slot2_mpcf.cpp', '../../addons/slot2_paddle.cpp', '../../addons/slot2_gbagame.cpp', '../../addons/slot2_none.cpp', '../../addons/slot2_rumblepak.cpp', '../../addons/slot2_guitarGrip.cpp', '../../addons/slot2_hcv1000.cpp', '../../addons/slot2_expMemory.cpp', '../../addons/slot2_piano.cpp', '../../addons/slot2_passme.cpp', '../../addons/slot1_none.cpp', '../../addons/slot1_r4.cpp', '../../addons/slot1_retail_nand.cpp', '../../addons/slot1_retail_auto.cpp', '../../addons/slot1_retail_mcrom.cpp', '../../addons/slot1_retail_mcrom_debug.cpp', '../../addons/slot1comp_mc.cpp', '../../addons/slot1comp_rom.cpp', '../../addons/slot1comp_protocol.cpp',
107+
'../../addons/slot2_auto.cpp', '../../addons/slot2_mpcf.cpp', '../../addons/slot2_paddle.cpp', '../../addons/slot2_gbagame.cpp', '../../addons/slot2_none.cpp', '../../addons/slot2_rumblepak.cpp', '../../addons/slot2_guitarGrip.cpp', '../../addons/slot2_hcv1000.cpp', '../../addons/slot2_slideController.cpp', '../../addons/slot2_expMemory.cpp', '../../addons/slot2_piano.cpp', '../../addons/slot2_passme.cpp', '../../addons/slot1_none.cpp', '../../addons/slot1_r4.cpp', '../../addons/slot1_retail_nand.cpp', '../../addons/slot1_retail_auto.cpp', '../../addons/slot1_retail_mcrom.cpp', '../../addons/slot1_retail_mcrom_debug.cpp', '../../addons/slot1comp_mc.cpp', '../../addons/slot1comp_rom.cpp', '../../addons/slot1comp_protocol.cpp',
108108
'../../cheatSystem.cpp',
109109
'../../texcache.cpp', '../../rasterize.cpp',
110110
'../../metaspu/metaspu.cpp',

desmume/src/frontend/windows/DeSmuME.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
<ClCompile Include="..\..\addons\slot1_retail_nand.cpp" />
7474
<ClCompile Include="..\..\addons\slot2_mpcf.cpp" />
7575
<ClCompile Include="..\..\addons\slot2_paddle.cpp" />
76+
<ClCompile Include="..\..\addons\slot2_slideController.cpp" />
7677
<ClCompile Include="..\..\arm_instructions.cpp" />
7778
<ClCompile Include="..\..\armcpu.cpp" />
7879
<ClCompile Include="..\..\arm_jit.cpp" />

desmume/src/frontend/windows/DeSmuME.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,9 @@
933933
<ClCompile Include="..\..\addons\slot2_hcv1000.cpp">
934934
<Filter>addons</Filter>
935935
</ClCompile>
936+
<ClCompile Include="..\..\addons\slot2_slideController.cpp">
937+
<Filter>addons</Filter>
938+
</ClCompile>
936939
</ItemGroup>
937940
<ItemGroup>
938941
<ClInclude Include="..\..\utils\guid.h">

desmume/src/frontend/windows/gbaslot_config.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -526,11 +526,12 @@ u32 GBAslot_IDDs[NDS_SLOT2_COUNT] = {
526526
IDD_GBASLOT_RUMBLEPAK,
527527
IDD_GBASLOT_GBAGAME,
528528
IDD_GBASLOT_GUITARGRIP,
529-
IDD_GBASLOT_NONE, //expmem
529+
IDD_GBASLOT_NONE, //expmem
530530
IDD_GBASLOT_PIANO,
531-
IDD_GBASLOT_PADDLE, //paddle
532-
IDD_GBASLOT_NONE, //PassME
533-
IDD_GBASLOT_HCV1000, //HCV-1000
531+
IDD_GBASLOT_PADDLE, //paddle
532+
IDD_GBASLOT_NONE, //PassME
533+
IDD_GBASLOT_HCV1000, //HCV-1000
534+
IDD_GBASLOT_NONE, //Slide Controller
534535
};
535536

536537
DLGPROC GBAslot_Procs[NDS_SLOT2_COUNT] = {
@@ -540,11 +541,12 @@ DLGPROC GBAslot_Procs[NDS_SLOT2_COUNT] = {
540541
GbaSlotRumblePak,
541542
GbaSlotGBAgame,
542543
GbaSlotGuitarGrip,
543-
GbaSlotNone, //expmem
544+
GbaSlotNone, //expmem
544545
GbaSlotPiano,
545546
GbaSlotPaddle,
546-
GbaSlotNone, // PassME
547+
GbaSlotNone, // PassME
547548
GbaSlotHCV1000, //HCV-1000
549+
GbaSlotNone, //Slide Controller
548550
};
549551

550552

@@ -696,6 +698,8 @@ void GBAslotDialog(HWND hwnd)
696698
WritePrivateProfileString("Slot2.HCV1000", "barcode", tmp_hcv1000_barcode, IniName);
697699
WritePrivateProfileInt("Slot2.HCV1000", "scankey", HCV1000.SCANKEY, IniName);
698700
break;
701+
case NDS_SLOT2_SLIDECONTROLLER:
702+
break;
699703
default:
700704
return;
701705
}
@@ -708,6 +712,7 @@ void GBAslotDialog(HWND hwnd)
708712
Piano.Enabled = (slot2_GetCurrentType() == NDS_SLOT2_EASYPIANO)?true:false;
709713
Paddle.Enabled = (slot2_GetCurrentType() == NDS_SLOT2_PADDLE)?true:false;
710714
HCV1000.Enabled = (slot2_GetCurrentType() == NDS_SLOT2_HCV1000)?true:false;
715+
SlideController.Enabled = (slot2_GetCurrentType() == NDS_SLOT2_SLIDECONTROLLER)?true:false;
711716
}
712717
}
713718

0 commit comments

Comments
 (0)