disktidy: add a comment to the function
[maemo-rb.git] / apps / plugins / rockboy / rockboy.c
blobb3fccbf8d803b5594854cd36c3131f3192a10c7c
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_MENU;
316 options.B = BUTTON_ENTER;
317 options.START = BUTTON_PLAY;
318 options.SELECT = (BUTTON_ENTER | BUTTON_REPEAT);
319 options.MENU = (BUTTON_MENU | BUTTON_REPEAT);
321 #else
322 #error No Keymap Defined!
323 #endif
325 #ifdef HAVE_TOUCHSCREEN
326 options.UP = BUTTON_TOPMIDDLE;
327 options.DOWN = BUTTON_BOTTOMMIDDLE;
328 options.START = BUTTON_TOPRIGHT;
329 options.SELECT = BUTTON_CENTER;
330 #if CONFIG_KEYPAD == MROBE500_PAD
331 options.A = BUTTON_BOTTOMLEFT;
332 options.B = BUTTON_BOTTOMRIGHT;
333 #elif CONFIG_KEYPAD != COWON_D2_PAD
334 options.A = BUTTON_BOTTOMLEFT;
335 options.B = BUTTON_BOTTOMRIGHT;
336 options.MENU = BUTTON_TOPLEFT;
337 #endif
338 #endif
340 options.maxskip=4;
341 options.fps=0;
342 options.showstats=0;
343 #if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144)
344 options.scaling=0;
345 #else
346 options.scaling=1;
347 #endif
348 options.sound=1;
349 options.pal=0;
351 else
352 read(fd,&options, sizeof(options));
354 close(fd);
357 static void savesettings(void)
359 int fd;
360 char optionsave[sizeof(savedir)+sizeof(optionname)];
362 if(options.dirty)
364 options.dirty=0;
365 snprintf(optionsave, sizeof(optionsave), "%s/%s", savedir, optionname);
366 fd = open(optionsave, O_WRONLY|O_CREAT|O_TRUNC, 0666);
367 write(fd,&options, sizeof(options));
368 close(fd);
372 void doevents(void)
374 event_t ev;
375 int st;
377 ev_poll();
378 while (ev_getevent(&ev))
380 if (ev.type != EV_PRESS && ev.type != EV_RELEASE)
381 continue;
382 st = (ev.type != EV_RELEASE);
383 pad_set(ev.code, st);
387 static int gnuboy_main(const char *rom)
389 rb->lcd_puts(0,0,"Init video");
390 vid_init();
391 rb->lcd_puts(0,1,"Init sound");
392 rockboy_pcm_init();
393 rb->lcd_puts(0,2,"Loading rom");
394 loader_init(rom);
395 if(shut)
396 return PLUGIN_ERROR;
397 rb->lcd_puts(0,3,"Emu reset");
398 emu_reset();
399 rb->lcd_puts(0,4,"Emu run");
400 rb->lcd_clear_display();
401 rb->lcd_update();
402 if(options.autosave) sn_load();
403 emu_run();
405 /* never reached */
406 return PLUGIN_OK;
409 /* this is the plugin entry point */
410 enum plugin_status plugin_start(const void* parameter)
412 rb->lcd_setfont(0);
414 rb->lcd_clear_display();
416 if (!parameter)
418 rb->splash(HZ*3, "Play gameboy ROM file! (.gb/.gbc)");
419 return PLUGIN_OK;
421 if(rb->audio_status())
423 audio_bufferbase = audio_bufferpointer
424 = rb->plugin_get_buffer(&audio_buffer_free);
425 plugbuf=true;
427 else
429 audio_bufferbase = audio_bufferpointer
430 = rb->plugin_get_audio_buffer(&audio_buffer_free);
431 plugbuf=false;
433 #if MEM <= 8 && (CONFIG_PLATFORM & PLATFORM_NATIVE)
434 /* loaded as an overlay plugin, protect from overwriting ourselves */
435 if ((unsigned)(plugin_start_addr - (unsigned char *)audio_bufferbase)
436 < audio_buffer_free)
437 audio_buffer_free = plugin_start_addr - (unsigned char *)audio_bufferbase;
438 #endif
439 setoptions();
441 shut=0;
442 cleanshut=0;
444 #ifdef HAVE_WHEEL_POSITION
445 rb->wheel_send_events(false);
446 #endif
448 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
449 rb->lcd_set_mode(LCD_MODE_PAL256);
450 #endif
452 /* ignore backlight time out */
453 backlight_force_on();
455 gnuboy_main(parameter);
457 #ifdef HAVE_WHEEL_POSITION
458 rb->wheel_send_events(true);
459 #endif
461 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
462 rb->lcd_set_mode(LCD_MODE_RGB565);
463 #endif
465 backlight_use_settings();
467 if(!rb->audio_status())
468 rockboy_pcm_close();
470 if(shut&&!cleanshut)
472 rb->splash(HZ/2, errormsg);
473 return PLUGIN_ERROR;
476 rb->splash(HZ/2, "Closing Rockboy");
478 savesettings();
480 cleanup();
482 return PLUGIN_OK;