forked from iPodLinux-Community/iGameGear
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathporting.txt
299 lines (227 loc) · 10.8 KB
/
porting.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
You can check out the DOS specific code to get an idea of
how to port SMS Plus.
0.) Machine dependant issues
----------------------------
Everything should compile fine for big-endian platforms, however
I'm not sure the 8-bit pixel to 16-bit pixel conversion function
in 'render.c' is endian safe.
You need to either define or not define 'LSB_FIRST' in your makefile,
depending on your needs.
1.) Graphics
------------
The emulated display can be shown in either 8-bit or 16-bit color.
The following structure is used by the rendering routines to
draw the display, and you need to set it up prior to running the
emulation.
typedef struct
{
unsigned char *data;
int width;
int height;
int pitch;
int depth;
struct
{
byte color[PALETTE_MAX][3];
byte dirty[PALETTE_MAX];
byte update;
}pal;
}t_bitmap;
'data' - Pointer to a linear chunk of memory. This should be at least
256x192 pixels in size. You can modify this pointer between
frames for double buffering (if it's pointed into memory mapped
video RAM), or point it to system memory so further changes
can be made. (like special effects, or for converting the
graphics data to 24 or 32-bit format)
'width' - Width of the bitmap, in pixels.
'height' - Height of the bitmap, in pixels.
'pitch' - Width of the bitmap, in *bytes*.
'depth' - Color depth. Must be 8 or 16.
'color' - An array of 32 RGB values, each scaled up to eight bits.
'dirty' - Each entry is nonzero if the color has been modified.
'update' - Nonzero if one or more colors have been modified.
If you are using 8-bit color, please note that each pixel drawn to
the bitmap uses some extra unused bits during the rendering process.
You can either mask out these bits using the PIXEL_MASK constant
from 'system.h', or set palette ranges 20-3F, 40-5F to the same
values as 00-1F.
If you are using 16-bit color, you can ignore the members of the 'pal'
structure. Remember to adjust the MAKE_PIXEL macro in 'render.h' to
whatever format your display uses. By default it will make a 16-bit
pixel in RGB 5:6:5 format.
The macros BMP_X_OFFSET, BMP_Y_OFFSET, give the offset into the
bitmap. This is because the SMS display takes up the entire bitmap,
while the GG display is centered in the middle. These macros provide
a convenient way to get the right offset.
The PALETTE_MAX constant returns the size of the palette.
This is currently set to 32 entries.
2.) Sound
---------
Sound emulation is handled through the following structure:
typedef struct
{
int enabled;
int bufsize;
signed short *buffer[2]; /* Left and right channels */
}t_snd;
'enabled' - Nonzero if the initialization went OK. You can now use
the 'bufsize' and 'buffer' members.
'bufsize' - Size of the sound buffer, in *samples*.
'buffer' - Sound buffer. Uses 16-bit, signed, stereo samples.
You must call 'system_init()' and pass the desired sample rate as an
parameter to enable sound emulation. You can set the sample rate to
zero if you do not want sound emulation. Remember that 'snd.enabled'
will be set afterwards to indicate if any errors occured.
You also must call 'system_shutdown()' when you are done running
the virtual console emulation, so some memory used by the sound
emulation code can be freed.
3.) Input
---------
Input is handled through the following structure:
typedef struct
{
int pad[2];
int system;
}t_input;
'pad[]' - Corresponds to joystick one and joystick two.
'system' - System buttons, specifically pause, start, and reset.
During each frame, you should clear members of this structure to zero,
then update each one using the INPUT_* constants in 'system.h'.
4.) Game Images
---------------
Game images are handled through the following structure:
typedef struct
{
byte *rom;
byte pages;
byte type;
}t_cart;
'rom' - Pointer to the ROM image.
'pages' - ROM size divided by 16k.
'type' - Set to either TYPE_SMS or TYPE_GG.
Games can be identified by their extension, which is usually '.sms'
or '.gg'. Some games have an optional 512-byte header which you must
remove. Remember to adjust the file size accordingly.
5.) Battery backed RAM
----------------------
Some game cartridges can have up to 32k of battery backed RAM present.
There are two variables relating to this:
typedef struct
{
byte sram[0x8000];
byte save;
}t_sms;
'sram' - This is the data that should be saved and loaded.
'save' - This is nonzero if the contents of sram[] should be saved.
It's impossible to know if a game will use battery backed RAM, so the
emulation code waits until a game tries to read or write it, and then
sets the 'save' flag meaning the data needs to be saved.
The basic way to deal with this is:
1. Load a game file
2. If a file with the same name, and the extension .sav exists,
then load that data into 'sram' and set the 'save' flag.
3. When exiting, check if the 'save' flag is nonzero, and if so,
write the contents of sram[] to a file with the extension .sav
and the same filename as the game file loaded.
Note that when system_reset() is called, the function 'system_load_sram'
which has a prototype in 'system.h' will be called. You *must* implement
this function. All it has to do is see if any saved battery backed RAM
is present, and update the save/sram[] members accordingly.
6.) Miscellaneous
-----------------
Before running the virtual console emulation, you can set up
these two variables:
sms.use_fm : 0= No YM2413 sound, 1= YM2413 sound
sms.country : Set to TYPE_DOMESTIC (Japan), TYPE_OVERSEAS
Some games will display different text depending on the country
setting. The default value is TYPE_OVERSEAS. This is suitable for every
country but Japan.
Some games have different music if the YM2413 sound chip is present.
If the 'fm_enable' value is set to one, then games can detect it.
If you want to use FM sound, you must ensure that 'use_fm' is nonzero
before loading a game, since this variable controls if games can detect
the YM2413 chip as well as actual YM2413 output.
Some games will only enable YM2413 sound if the country type is
also set to TYPE_DOMESTIC. One such example is Wonderboy 3.
Both of these variables are preserved when system_reset() is called.
You can call load_state/save_state to save and restore the current state
of the virtual console emulation. You need to pass a file handle as
a parameter to these functions. Therefore, you are responsible for ensuring
the file exists, and the file name. The naming convention is that all
state files are named '.st0' up to '.st9'.
To log sound, set snd.log=1, and assign the snd.callback() function to
your own function that writes a byte of data to a disk file (or memory
buffer, etc.) The naming convention for sound files is that they end
with the extension '.ssl'.
7.) Function reference
----------------------
void system_init(int sound_rate);
You must set up the 'bitmap' and 'cart' structures prior to calling this
function. If you want sound emulation, pass the desired sample rate
(8000..44100). Afterwards, check the members of the 'snd' structure to see
if you can use sound emulation. You can now call sms_frame() and the like.
void system_shutdown(void);
Call this when you're done with the emulation. Not terribly important
as it only frees some memory allocated by the sound emulation routines...
void system_reset(void)
Reset the virtual console emulation. This is called internally when
the INPUT_HARD_RESET flag for 'input.system' is set.
void system_load_sram(void);
Refresh the 'sms.sram[]' and 'sms.save' variables.
You must impelement this function yourself.
void sms_frame(int skip);
You need to call this function 60 times a second. Pass zero as the
parameter to draw the current frame, otherwise pass one to omit
the drawing process. (ideal for frame skipping) Afterwards,
the 'bitmap' and 'snd' structures will be updated with the current
graphics and sound data. You should set up the 'input' structure
before calling this function.
8.) Example
-----------
Here's a brief overview of how to use all this:
- do machine dependant initialization (audio, video, init input, etc.)
- set up bitmap structure
- set up cart structure (load game)
- call system_init()
- if snd.enabled is set, we can use sound
- load sram data if it exists for the game
in a loop:
- update input structure based on gamepad/keyboard
- call sms_frame()
- play sound using 'snd.buffer'
- copy 'bitmap.data' to the video display
- quit if needed
- save sram data if the game used it
- call system_shutdown()
9.) Other notes on porting
--------------------------
- Please read the license first.
- You must release the source code to your port in accordance with the GPL.
If you have made *no* changes to the main source code, meaning everything
in the root directory, and the cpu and dos directories, then you
do not have to include those files. No point in wasting space.
Otherwise, you must include those files with the changes clearly stated.
If the changes are the kind that could benefit other ports (like a bug
fix), then just let me know so I can update the main distribution, and
don't bother releasing those files. But let me know before you release
your port, however.
If you are using some commercial libraries to take care of items like
audio output, or if you have developed some routines which you do not want
made public (i.e. an assembly optimized blitter, or some custom joypad
polling functions), then you do not have to include those files.
I prefer it where anybody can download a port of SMS Plus and compile it
themselves, but I realize this isn't always possible.
It would be nice, and is not required, that you could organize the
source in the same way I have it set up. For instance, maintaining the
same directory structure, but adding an '/myport' directory with your
specific files, and an appropriate makefile.
- You must clearly state in the executable that you are the porter,
and that I wrote the program. E-mail addresses are required, Web
site URL's are optional but preferred. This is so users will not ask
me questions on how to use a specific port, which I know nothing about.
- You need to provide documentation. Please remember to mention
the licensing stuff pertaining to SMS Plus and the MAME code that's
mentioned (for example) in the original 'readme' I wrote. Or just
include my documentation and make some additions.
Please link to my website in the documentation, so people will know
where to get the original source code.