Bump version numbers for 3.13
[maemo-rb.git] / apps / plugins / rockboy / rockboy.c
blob78239c0a34a8b53911a77ae629e9b7d6a38dac33
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
21 #include "plugin.h"
22 #include "lib/helper.h"
23 #include "loader.h"
24 #include "rockmacros.h"
25 #include "input.h"
26 #include "emu.h"
27 #include "hw.h"
28 #include "pcm.h"
30 int shut,cleanshut;
31 char *errormsg;
33 #define optionname "options"
35 void die(char *message, ...)
37 shut=1;
38 errormsg=message;
41 struct options options;
43 void *audio_bufferbase;
44 void *audio_bufferpointer;
45 size_t audio_buffer_free;
47 void *my_malloc(size_t size)
49 void *alloc;
51 if (size + 4 > audio_buffer_free)
52 return 0;
53 alloc = audio_bufferpointer;
54 audio_bufferpointer += size + 4;
55 audio_buffer_free -= size + 4;
56 return alloc;
59 static void setoptions (void)
61 int fd;
62 DIR* dir;
63 char optionsave[sizeof(savedir)+sizeof(optionname)];
65 dir=rb->opendir(savedir);
66 if(!dir)
67 rb->mkdir(savedir);
68 else
69 rb->closedir(dir);
71 snprintf(optionsave, sizeof(optionsave), "%s/%s", savedir, optionname);
73 fd = open(optionsave, O_RDONLY);
75 int optionssize = sizeof(options);
76 int filesize = 0;
77 if(fd >= 0)
78 filesize = rb->filesize(fd);
80 /* don't read the option file if the size
81 * is not as expected to avoid crash */
82 if(fd < 0 || filesize!=optionssize)
84 /* no options to read, set defaults */
85 #ifdef HAVE_TOUCHSCREEN
86 options.LEFT = BUTTON_MIDLEFT;
87 options.RIGHT = BUTTON_MIDRIGHT;
88 #else
89 options.LEFT = BUTTON_LEFT;
90 options.RIGHT = BUTTON_RIGHT;
91 #endif
93 #if CONFIG_KEYPAD == IRIVER_H100_PAD
94 options.UP = BUTTON_UP;
95 options.DOWN = BUTTON_DOWN;
97 options.A = BUTTON_ON;
98 options.B = BUTTON_OFF;
99 options.START = BUTTON_REC;
100 options.SELECT = BUTTON_SELECT;
101 options.MENU = BUTTON_MODE;
103 #elif CONFIG_KEYPAD == IRIVER_H300_PAD
104 options.UP = BUTTON_UP;
105 options.DOWN = BUTTON_DOWN;
107 options.A = BUTTON_REC;
108 options.B = BUTTON_MODE;
109 options.START = BUTTON_ON;
110 options.SELECT = BUTTON_SELECT;
111 options.MENU = BUTTON_OFF;
113 #elif CONFIG_KEYPAD == RECORDER_PAD
114 options.UP = BUTTON_UP;
115 options.DOWN = BUTTON_DOWN;
117 options.A = BUTTON_F1;
118 options.B = BUTTON_F2;
119 options.START = BUTTON_F3;
120 options.SELECT = BUTTON_PLAY;
121 options.MENU = BUTTON_OFF;
123 #elif CONFIG_KEYPAD == IPOD_4G_PAD
124 options.UP = BUTTON_MENU;
125 options.DOWN = BUTTON_PLAY;
127 options.A = BUTTON_NONE;
128 options.B = BUTTON_NONE;
129 options.START = BUTTON_SELECT;
130 options.SELECT = BUTTON_NONE;
131 options.MENU = (BUTTON_SELECT | BUTTON_REPEAT);
133 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
134 options.UP = BUTTON_UP;
135 options.DOWN = BUTTON_DOWN;
137 options.A = BUTTON_PLAY;
138 options.B = BUTTON_EQ;
139 options.START = BUTTON_MODE;
140 options.SELECT = (BUTTON_SELECT | BUTTON_REL);
141 options.MENU = (BUTTON_SELECT | BUTTON_REPEAT);
143 #elif CONFIG_KEYPAD == GIGABEAT_PAD
144 options.UP = BUTTON_UP;
145 options.DOWN = BUTTON_DOWN;
147 options.A = BUTTON_VOL_UP;
148 options.B = BUTTON_VOL_DOWN;
149 options.START = BUTTON_A;
150 options.SELECT = BUTTON_SELECT;
151 options.MENU = BUTTON_MENU;
153 #elif CONFIG_KEYPAD == SANSA_E200_PAD
154 options.UP = BUTTON_UP;
155 options.DOWN = BUTTON_DOWN;
157 options.A = BUTTON_SELECT;
158 options.B = BUTTON_REC;
159 options.START = BUTTON_SCROLL_BACK;
160 options.SELECT = BUTTON_SCROLL_FWD;
161 options.MENU = BUTTON_POWER;
163 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
164 options.UP = BUTTON_UP;
165 options.DOWN = BUTTON_DOWN;
167 options.A = BUTTON_SELECT;
168 options.B = BUTTON_HOME;
169 options.START = BUTTON_SCROLL_BACK;
170 options.SELECT = BUTTON_SCROLL_FWD;
171 options.MENU = BUTTON_POWER;
173 #elif CONFIG_KEYPAD == SANSA_C200_PAD
174 options.UP = BUTTON_UP;
175 options.DOWN = BUTTON_DOWN;
177 options.A = BUTTON_SELECT;
178 options.B = BUTTON_REC;
179 options.START = BUTTON_VOL_DOWN;
180 options.SELECT = BUTTON_VOL_UP;
181 options.MENU = BUTTON_POWER;
183 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
184 options.UP = BUTTON_UP;
185 options.DOWN = BUTTON_DOWN;
187 options.A = BUTTON_SELECT;
188 options.B = BUTTON_HOME;
189 options.START = BUTTON_VOL_DOWN;
190 options.SELECT = BUTTON_VOL_UP;
191 options.MENU = BUTTON_POWER;
193 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
194 options.UP = BUTTON_UP;
195 options.DOWN = BUTTON_DOWN;
197 options.A = BUTTON_PLAY;
198 options.B = BUTTON_REC;
199 options.START = BUTTON_SELECT;
200 options.SELECT = BUTTON_NONE;
201 options.MENU = BUTTON_POWER;
203 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
204 options.UP = BUTTON_SCROLL_UP;
205 options.DOWN = BUTTON_SCROLL_DOWN;
207 options.A = BUTTON_PLAY;
208 options.B = BUTTON_FF;
209 options.START = BUTTON_REW;
210 options.SELECT = BUTTON_NONE;
211 options.MENU = BUTTON_POWER;
213 #elif CONFIG_KEYPAD == MROBE500_PAD
214 options.MENU = BUTTON_POWER;
216 #elif CONFIG_KEYPAD == COWON_D2_PAD
217 options.A = BUTTON_PLUS;
218 options.B = BUTTON_MINUS;
219 options.MENU = BUTTON_MENU;
221 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
222 options.UP = BUTTON_UP;
223 options.DOWN = BUTTON_DOWN;
225 options.A = BUTTON_VOL_UP;
226 options.B = BUTTON_VOL_DOWN;
227 options.START = BUTTON_PLAY;
228 options.SELECT = BUTTON_SELECT;
229 options.MENU = BUTTON_MENU;
230 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
231 options.UP = BUTTON_UP;
232 options.DOWN = BUTTON_DOWN;
234 options.A = BUTTON_CUSTOM;
235 options.B = BUTTON_PLAY;
236 options.START = BUTTON_BACK;
237 options.SELECT = BUTTON_SELECT;
238 options.MENU = BUTTON_MENU;
240 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
241 options.UP = BUTTON_UP;
242 options.DOWN = BUTTON_DOWN;
244 options.A = BUTTON_VOL_UP;
245 options.B = BUTTON_VOL_DOWN;
246 options.START = BUTTON_VIEW;
247 options.SELECT = BUTTON_SELECT;
248 options.MENU = BUTTON_MENU;
250 #elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
251 options.UP = BUTTON_UP;
252 options.DOWN = BUTTON_DOWN;
253 options.A = BUTTON_VOL_UP;
254 options.B = BUTTON_VOL_DOWN;
255 options.START = BUTTON_NEXT;
256 options.SELECT = BUTTON_PLAY;
257 options.MENU = BUTTON_MENU;
259 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
260 options.UP = BUTTON_UP;
261 options.DOWN = BUTTON_DOWN;
263 options.A = BUTTON_VOL_UP;
264 options.B = BUTTON_VOL_DOWN;
265 options.START = BUTTON_RIGHT;
266 options.SELECT = BUTTON_LEFT;
267 options.MENU = BUTTON_MENU;
269 #elif CONFIG_KEYPAD == ONDAVX747_PAD
270 options.A = BUTTON_VOL_UP;
271 options.B = BUTTON_VOL_DOWN;
272 options.MENU = BUTTON_MENU;
274 #elif CONFIG_KEYPAD == ONDAVX777_PAD
275 options.MENU = BUTTON_POWER;
277 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
278 options.UP = BUTTON_UP;
279 options.DOWN = BUTTON_DOWN;
281 options.A = BUTTON_PLAY;
282 options.B = BUTTON_FFWD;
283 options.START = BUTTON_REW;
284 options.SELECT = BUTTON_RIGHT;
285 options.MENU = BUTTON_LEFT;
287 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
288 options.UP = BUTTON_UP;
289 options.DOWN = BUTTON_DOWN;
291 options.A = BUTTON_PLAY;
292 options.B = BUTTON_REW;
293 options.START = BUTTON_REC;
294 options.SELECT = BUTTON_FFWD;
295 options.MENU = BUTTON_NONE;
297 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
298 options.UP = BUTTON_OK;
299 options.DOWN = BUTTON_CANCEL;
300 options.LEFT = BUTTON_PREV;
301 options.RIGHT = BUTTON_NEXT;
303 options.A = BUTTON_POWER;
304 options.B = BUTTON_REC;
305 options.START = BUTTON_PLAY;
306 options.SELECT = BUTTON_UP;
307 options.MENU = BUTTON_MENU;
309 #elif CONFIG_KEYPAD == MPIO_HD300_PAD
310 options.UP = BUTTON_UP;
311 options.DOWN = BUTTON_DOWN;
312 options.LEFT = BUTTON_REW;
313 options.RIGHT = BUTTON_FF;
315 options.A = BUTTON_PLAY;
316 options.B = BUTTON_REC;
317 options.START = (BUTTON_PLAY | BUTTON_REPEAT);
318 options.SELECT = BUTTON_ENTER;
319 options.MENU = BUTTON_MENU;
321 #elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
322 options.UP = BUTTON_UP;
323 options.DOWN = BUTTON_DOWN;
324 options.LEFT = BUTTON_LEFT;
325 options.RIGHT = BUTTON_RIGHT;
327 options.A = BUTTON_BACK;
328 options.B = BUTTON_PLAYPAUSE;
329 options.START = BUTTON_SELECT;
330 options.SELECT = (BUTTON_PLAYPAUSE | BUTTON_REPEAT);
331 options.MENU = (BUTTON_SELECT | BUTTON_REPEAT);
333 #elif CONFIG_KEYPAD == SANSA_CONNECT_PAD
334 options.UP = BUTTON_UP;
335 options.DOWN = BUTTON_DOWN;
336 options.LEFT = BUTTON_LEFT;
337 options.RIGHT = BUTTON_RIGHT;
339 options.A = BUTTON_VOL_UP;
340 options.B = BUTTON_VOL_DOWN;
341 options.START = BUTTON_PREV;
342 options.SELECT = BUTTON_NEXT;
343 options.MENU = BUTTON_SELECT;
345 #elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD
346 options.UP = BUTTON_UP;
347 options.DOWN = BUTTON_DOWN;
348 options.LEFT = BUTTON_LEFT;
349 options.RIGHT = BUTTON_RIGHT;
351 options.A = BUTTON_SELECT;
352 options.B = BUTTON_BACK;
353 options.START = BUTTON_POWER;
354 options.SELECT = BUTTON_USER;
355 options.MENU = BUTTON_MENU;
357 #elif CONFIG_KEYPAD == HM801_PAD
358 options.UP = BUTTON_UP;
359 options.DOWN = BUTTON_DOWN;
360 options.LEFT = BUTTON_LEFT;
361 options.RIGHT = BUTTON_RIGHT;
363 options.A = BUTTON_PREV;
364 options.B = BUTTON_NEXT;
365 options.START = BUTTON_PLAY;
366 options.SELECT = BUTTON_SELECT;
367 options.MENU = BUTTON_POWER;
369 #else
370 #error No Keymap Defined!
371 #endif
373 #ifdef HAVE_TOUCHSCREEN
374 options.UP = BUTTON_TOPMIDDLE;
375 options.DOWN = BUTTON_BOTTOMMIDDLE;
376 options.START = BUTTON_TOPRIGHT;
377 options.SELECT = BUTTON_CENTER;
378 #if CONFIG_KEYPAD == MROBE500_PAD
379 options.A = BUTTON_BOTTOMLEFT;
380 options.B = BUTTON_BOTTOMRIGHT;
381 #elif CONFIG_KEYPAD != COWON_D2_PAD
382 options.A = BUTTON_BOTTOMLEFT;
383 options.B = BUTTON_BOTTOMRIGHT;
384 options.MENU = BUTTON_TOPLEFT;
385 #endif
386 #endif
388 options.maxskip=4;
389 options.fps=0;
390 options.showstats=0;
391 #if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144)
392 options.scaling=0;
393 #else
394 options.scaling=1;
395 #endif
396 options.sound=1;
397 options.pal=0;
399 else
400 read(fd,&options, sizeof(options));
402 close(fd);
405 static void savesettings(void)
407 int fd;
408 char optionsave[sizeof(savedir)+sizeof(optionname)];
410 if(options.dirty)
412 options.dirty=0;
413 snprintf(optionsave, sizeof(optionsave), "%s/%s", savedir, optionname);
414 fd = open(optionsave, O_WRONLY|O_CREAT|O_TRUNC, 0666);
415 write(fd,&options, sizeof(options));
416 close(fd);
420 void doevents(void)
422 event_t ev;
423 int st;
425 ev_poll();
426 while (ev_getevent(&ev))
428 if (ev.type != EV_PRESS && ev.type != EV_RELEASE)
429 continue;
430 st = (ev.type != EV_RELEASE);
431 pad_set(ev.code, st);
435 static int gnuboy_main(const char *rom)
437 rb->lcd_puts(0,0,"Init video");
438 vid_init();
439 rb->lcd_puts(0,1,"Init sound");
440 rockboy_pcm_init();
441 rb->lcd_puts(0,2,"Loading rom");
442 loader_init(rom);
443 if(shut)
444 return PLUGIN_ERROR;
445 rb->lcd_puts(0,3,"Emu reset");
446 emu_reset();
447 rb->lcd_puts(0,4,"Emu run");
448 rb->lcd_clear_display();
449 rb->lcd_update();
450 if(options.autosave) sn_load();
451 emu_run();
453 /* never reached */
454 return PLUGIN_OK;
457 /* this is the plugin entry point */
458 enum plugin_status plugin_start(const void* parameter)
460 rb->lcd_setfont(FONT_SYSFIXED);
462 rb->lcd_clear_display();
464 if (!parameter)
466 rb->splash(HZ*3, "Play gameboy ROM file! (.gb/.gbc)");
467 return PLUGIN_OK;
469 if(rb->audio_status())
471 audio_bufferbase = audio_bufferpointer
472 = rb->plugin_get_buffer(&audio_buffer_free);
473 plugbuf=true;
475 else
477 audio_bufferbase = audio_bufferpointer
478 = rb->plugin_get_audio_buffer(&audio_buffer_free);
479 plugbuf=false;
481 #if MEMORYSIZE <= 8 && (CONFIG_PLATFORM & PLATFORM_NATIVE)
482 /* loaded as an overlay plugin, protect from overwriting ourselves */
483 if ((unsigned)(plugin_start_addr - (unsigned char *)audio_bufferbase)
484 < audio_buffer_free)
485 audio_buffer_free = plugin_start_addr - (unsigned char *)audio_bufferbase;
486 #endif
487 setoptions();
489 shut=0;
490 cleanshut=0;
492 #ifdef HAVE_WHEEL_POSITION
493 rb->wheel_send_events(false);
494 #endif
496 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
497 rb->lcd_set_mode(LCD_MODE_PAL256);
498 #endif
500 /* ignore backlight time out */
501 backlight_ignore_timeout();
503 gnuboy_main(parameter);
505 #ifdef HAVE_WHEEL_POSITION
506 rb->wheel_send_events(true);
507 #endif
509 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
510 rb->lcd_set_mode(LCD_MODE_RGB565);
511 #endif
513 backlight_use_settings();
515 if(!rb->audio_status())
516 rockboy_pcm_close();
518 if(shut&&!cleanshut)
520 rb->splash(HZ/2, errormsg);
521 return PLUGIN_ERROR;
524 rb->splash(HZ/2, "Closing Rockboy");
526 savesettings();
528 cleanup();
530 return PLUGIN_OK;