1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Gameboy emulator based on gnuboy
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 #include "rockmacros.h"
32 /* here is a global api struct pointer. while not strictly necessary,
33 it's nice not to have to pass the api pointer in all function calls
35 const struct plugin_api
* rb
;
39 #define optionname "options"
41 void die(char *message
, ...)
47 struct options options
;
49 void *audio_bufferbase
;
50 void *audio_bufferpointer
;
51 size_t audio_buffer_free
;
53 void *my_malloc(size_t size
)
57 if (size
+ 4 > audio_buffer_free
)
59 alloc
= audio_bufferpointer
;
60 audio_bufferpointer
+= size
+ 4;
61 audio_buffer_free
-= size
+ 4;
65 /* Using #define isn't enough with GCC 4.0.1 */
67 void* memcpy(void* dst
, const void* src
, size_t size
)
69 return rb
->memcpy(dst
, src
, size
);
72 static void setoptions (void)
76 char optionsave
[sizeof(savedir
)+sizeof(optionname
)];
78 dir
=rb
->opendir(savedir
);
84 snprintf(optionsave
, sizeof(optionsave
), "%s/%s", savedir
, optionname
);
86 fd
= open(optionsave
, O_RDONLY
);
87 if(fd
< 0) /* no options to read, set defaults */
90 options
.LEFT
=BUTTON_MIDLEFT
;
91 options
.RIGHT
=BUTTON_MIDRIGHT
;
93 options
.LEFT
=BUTTON_LEFT
;
94 options
.RIGHT
=BUTTON_RIGHT
;
97 #if CONFIG_KEYPAD == IRIVER_H100_PAD
99 options
.DOWN
=BUTTON_DOWN
;
102 options
.B
=BUTTON_OFF
;
103 options
.START
=BUTTON_REC
;
104 options
.SELECT
=BUTTON_SELECT
;
105 options
.MENU
=BUTTON_MODE
;
107 #elif CONFIG_KEYPAD == IRIVER_H300_PAD
108 options
.UP
=BUTTON_UP
;
109 options
.DOWN
=BUTTON_DOWN
;
111 options
.A
=BUTTON_REC
;
112 options
.B
=BUTTON_MODE
;
113 options
.START
=BUTTON_ON
;
114 options
.SELECT
=BUTTON_SELECT
;
115 options
.MENU
=BUTTON_OFF
;
117 #elif CONFIG_KEYPAD == RECORDER_PAD
118 options
.UP
=BUTTON_UP
;
119 options
.DOWN
=BUTTON_DOWN
;
123 options
.START
=BUTTON_F3
;
124 options
.SELECT
=BUTTON_PLAY
;
125 options
.MENU
=BUTTON_OFF
;
127 #elif CONFIG_KEYPAD == IPOD_4G_PAD
128 options
.UP
=BUTTON_MENU
;
129 options
.DOWN
=BUTTON_PLAY
;
131 options
.A
=BUTTON_NONE
;
132 options
.B
=BUTTON_NONE
;
133 options
.START
=BUTTON_SELECT
;
134 options
.SELECT
=BUTTON_NONE
;
135 options
.MENU
=(BUTTON_SELECT
| BUTTON_REPEAT
);
137 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
138 options
.UP
=BUTTON_UP
;
139 options
.DOWN
=BUTTON_DOWN
;
141 options
.A
=BUTTON_PLAY
;
143 options
.START
=BUTTON_MODE
;
144 options
.SELECT
=(BUTTON_SELECT
| BUTTON_REL
);
145 options
.MENU
=(BUTTON_SELECT
| BUTTON_REPEAT
);
147 #elif CONFIG_KEYPAD == GIGABEAT_PAD
148 options
.UP
=BUTTON_UP
;
149 options
.DOWN
=BUTTON_DOWN
;
151 options
.A
=BUTTON_VOL_UP
;
152 options
.B
=BUTTON_VOL_DOWN
;
153 options
.START
=BUTTON_A
;
154 options
.SELECT
=BUTTON_SELECT
;
155 options
.MENU
=BUTTON_MENU
;
157 #elif CONFIG_KEYPAD == SANSA_E200_PAD
158 options
.UP
=BUTTON_UP
;
159 options
.DOWN
=BUTTON_DOWN
;
161 options
.A
=BUTTON_SELECT
;
162 options
.B
=BUTTON_REC
;
163 options
.START
=BUTTON_SCROLL_BACK
;
164 options
.SELECT
=BUTTON_SCROLL_FWD
;
165 options
.MENU
=BUTTON_POWER
;
167 #elif CONFIG_KEYPAD == SANSA_C200_PAD
168 options
.UP
=BUTTON_UP
;
169 options
.DOWN
=BUTTON_DOWN
;
171 options
.A
=BUTTON_SELECT
;
172 options
.B
=BUTTON_REC
;
173 options
.START
=BUTTON_VOL_DOWN
;
174 options
.SELECT
=BUTTON_VOL_UP
;
175 options
.MENU
=BUTTON_POWER
;
177 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
178 options
.UP
=BUTTON_UP
;
179 options
.DOWN
=BUTTON_DOWN
;
181 options
.A
=BUTTON_PLAY
;
182 options
.B
=BUTTON_REC
;
183 options
.START
=BUTTON_SELECT
;
184 options
.SELECT
=BUTTON_NONE
;
185 options
.MENU
=BUTTON_POWER
;
187 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
188 options
.UP
=BUTTON_SCROLL_UP
;
189 options
.DOWN
=BUTTON_SCROLL_DOWN
;
191 options
.A
=BUTTON_PLAY
;
193 options
.START
=BUTTON_REW
;
194 options
.SELECT
=BUTTON_NONE
;
195 options
.MENU
=BUTTON_POWER
;
196 #elif CONFIG_KEYPAD == MROBE500_PAD
197 options
.UP
=BUTTON_RC_PLAY
;
198 options
.DOWN
=BUTTON_RC_DOWN
;
199 options
.LEFT
=BUTTON_RC_REW
;
200 options
.RIGHT
=BUTTON_RC_FF
;
202 options
.A
=BUTTON_RC_VOL_DOWN
;
203 options
.B
=BUTTON_RC_VOL_UP
;
204 options
.START
=BUTTON_RC_HEART
;
205 options
.SELECT
=BUTTON_RC_MODE
;
206 options
.MENU
=BUTTON_POWER
;
207 #elif CONFIG_KEYPAD == COWOND2_PAD
209 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
210 options
.UP
=BUTTON_UP
;
211 options
.DOWN
=BUTTON_DOWN
;
213 options
.A
=BUTTON_VOL_UP
;
214 options
.B
=BUTTON_VOL_DOWN
;
215 options
.START
=BUTTON_PLAY
;
216 options
.SELECT
=BUTTON_SELECT
;
217 options
.MENU
=BUTTON_MENU
;
219 #error No Keymap Defined!
223 options
.UP
=BUTTON_TOPMIDDLE
;
224 options
.DOWN
=BUTTON_BOTTOMMIDDLE
;
226 options
.A
=BUTTON_MIDLEFT
;
227 options
.B
=BUTTON_MIDRIGHT
;
228 options
.START
=BUTTON_TOPRIGHT
;
229 options
.SELECT
=BUTTON_CENTER
;
230 options
.MENU
=BUTTON_TOPLEFT
;
236 #if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144)
245 read(fd
,&options
, sizeof(options
));
250 static void savesettings(void)
253 char optionsave
[sizeof(savedir
)+sizeof(optionname
)];
258 snprintf(optionsave
, sizeof(optionsave
), "%s/%s", savedir
, optionname
);
259 fd
= open(optionsave
, O_WRONLY
|O_CREAT
|O_TRUNC
);
260 write(fd
,&options
, sizeof(options
));
271 while (ev_getevent(&ev
))
273 if (ev
.type
!= EV_PRESS
&& ev
.type
!= EV_RELEASE
)
275 st
= (ev
.type
!= EV_RELEASE
);
276 pad_set(ev
.code
, st
);
280 static int gnuboy_main(const char *rom
)
282 rb
->lcd_puts(0,0,"Init video");
284 rb
->lcd_puts(0,1,"Init sound");
286 rb
->lcd_puts(0,2,"Loading rom");
290 rb
->lcd_puts(0,3,"Emu reset");
292 rb
->lcd_puts(0,4,"Emu run");
293 rb
->lcd_clear_display();
301 /* this is the plugin entry point */
302 enum plugin_status
plugin_start(const struct plugin_api
* api
, const void* parameter
)
304 PLUGIN_IRAM_INIT(api
)
306 /* if you are using a global api pointer, don't forget to copy it!
307 otherwise you will get lovely "I04: IllInstr" errors... :-) */
312 rb
->lcd_clear_display();
316 rb
->splash(HZ
*3, "Play gameboy ROM file! (.gb/.gbc)");
319 if(rb
->audio_status())
321 audio_bufferbase
= audio_bufferpointer
322 = rb
->plugin_get_buffer(&audio_buffer_free
);
327 audio_bufferbase
= audio_bufferpointer
328 = rb
->plugin_get_audio_buffer(&audio_buffer_free
);
331 #if MEM <= 8 && !defined(SIMULATOR)
332 /* loaded as an overlay plugin, protect from overwriting ourselves */
333 if ((unsigned)(plugin_start_addr
- (unsigned char *)audio_bufferbase
)
335 audio_buffer_free
= plugin_start_addr
- (unsigned char *)audio_bufferbase
;
342 #ifdef HAVE_WHEEL_POSITION
343 rb
->wheel_send_events(false);
346 gnuboy_main(parameter
);
348 #ifdef HAVE_WHEEL_POSITION
349 rb
->wheel_send_events(true);
354 rb
->splash(HZ
/2, errormsg
);
357 if(!rb
->audio_status())
359 rb
->splash(HZ
/2, "Closing Rockboy");