fix FS#8187 - charging breaks sleep timer. Now if the timer goes off and the player...
[Rockbox.git] / apps / plugins / rockboy / rockboy.c
blobd214807c2de9d6f445f7a2bd8ae212b39a468ec2
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 "loader.h"
23 #include "rockmacros.h"
24 #include "input.h"
25 #include "emu.h"
26 #include "hw.h"
27 #include "pcm.h"
29 PLUGIN_HEADER
30 PLUGIN_IRAM_DECLARE
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
34 in the plugin */
35 const struct plugin_api* rb;
36 int shut,cleanshut;
37 char *errormsg;
39 #define optionname "options"
41 void die(char *message, ...)
43 shut=1;
44 errormsg=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)
55 void *alloc;
57 if (size + 4 > audio_buffer_free)
58 return 0;
59 alloc = audio_bufferpointer;
60 audio_bufferpointer += size + 4;
61 audio_buffer_free -= size + 4;
62 return alloc;
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)
74 int fd;
75 DIR* dir;
76 char optionsave[sizeof(savedir)+sizeof(optionname)];
78 dir=rb->opendir(savedir);
79 if(!dir)
80 rb->mkdir(savedir);
81 else
82 rb->closedir(dir);
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 */
89 #ifdef HAVE_TOUCHPAD
90 options.LEFT=BUTTON_MIDLEFT;
91 options.RIGHT=BUTTON_MIDRIGHT;
92 #else
93 options.LEFT=BUTTON_LEFT;
94 options.RIGHT=BUTTON_RIGHT;
95 #endif
97 #if CONFIG_KEYPAD == IRIVER_H100_PAD
98 options.UP=BUTTON_UP;
99 options.DOWN=BUTTON_DOWN;
101 options.A=BUTTON_ON;
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;
121 options.A=BUTTON_F1;
122 options.B=BUTTON_F2;
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;
142 options.B=BUTTON_EQ;
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;
192 options.B=BUTTON_FF;
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;
218 #else
219 #error No Keymap Defined!
220 #endif
222 #ifdef HAVE_TOUCHPAD
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;
231 #endif
233 options.maxskip=4;
234 options.fps=0;
235 options.showstats=0;
236 #if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144)
237 options.scaling=0;
238 #else
239 options.scaling=1;
240 #endif
241 options.sound=1;
242 options.pal=0;
244 else
245 read(fd,&options, sizeof(options));
247 close(fd);
250 static void savesettings(void)
252 int fd;
253 char optionsave[sizeof(savedir)+sizeof(optionname)];
255 if(options.dirty)
257 options.dirty=0;
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));
261 close(fd);
265 void doevents(void)
267 event_t ev;
268 int st;
270 ev_poll();
271 while (ev_getevent(&ev))
273 if (ev.type != EV_PRESS && ev.type != EV_RELEASE)
274 continue;
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");
283 vid_init();
284 rb->lcd_puts(0,1,"Init sound");
285 pcm_init();
286 rb->lcd_puts(0,2,"Loading rom");
287 loader_init(rom);
288 if(shut)
289 return PLUGIN_ERROR;
290 rb->lcd_puts(0,3,"Emu reset");
291 emu_reset();
292 rb->lcd_puts(0,4,"Emu run");
293 rb->lcd_clear_display();
294 rb->lcd_update();
295 emu_run();
297 /* never reached */
298 return PLUGIN_OK;
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... :-) */
308 rb = api;
310 rb->lcd_setfont(0);
312 rb->lcd_clear_display();
314 if (!parameter)
316 rb->splash(HZ*3, "Play gameboy ROM file! (.gb/.gbc)");
317 return PLUGIN_OK;
319 if(rb->audio_status())
321 audio_bufferbase = audio_bufferpointer
322 = rb->plugin_get_buffer(&audio_buffer_free);
323 plugbuf=true;
325 else
327 audio_bufferbase = audio_bufferpointer
328 = rb->plugin_get_audio_buffer(&audio_buffer_free);
329 plugbuf=false;
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)
334 < audio_buffer_free)
335 audio_buffer_free = plugin_start_addr - (unsigned char *)audio_bufferbase;
336 #endif
337 setoptions();
339 shut=0;
340 cleanshut=0;
342 #ifdef HAVE_WHEEL_POSITION
343 rb->wheel_send_events(false);
344 #endif
346 gnuboy_main(parameter);
348 #ifdef HAVE_WHEEL_POSITION
349 rb->wheel_send_events(true);
350 #endif
352 if(shut&&!cleanshut)
354 rb->splash(HZ/2, errormsg);
355 return PLUGIN_ERROR;
357 if(!rb->audio_status())
358 pcm_close();
359 rb->splash(HZ/2, "Closing Rockboy");
361 savesettings();
363 cleanup();
365 return PLUGIN_OK;