diff options
Diffstat (limited to 'apps/plugins/pacbox/pacbox.c')
-rw-r--r-- | apps/plugins/pacbox/pacbox.c | 142 |
1 files changed, 129 insertions, 13 deletions
diff --git a/apps/plugins/pacbox/pacbox.c b/apps/plugins/pacbox/pacbox.c index badf171927..9bbc00d094 100644 --- a/apps/plugins/pacbox/pacbox.c +++ b/apps/plugins/pacbox/pacbox.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "arcade.h" | 28 | #include "arcade.h" |
29 | #include "pacbox.h" | 29 | #include "pacbox.h" |
30 | #include "pacbox_lcd.h" | 30 | #include "pacbox_lcd.h" |
31 | #include "wsg3.h" | ||
31 | #include "lib/configfile.h" | 32 | #include "lib/configfile.h" |
32 | #include "lib/playback_control.h" | 33 | #include "lib/playback_control.h" |
33 | 34 | ||
@@ -40,10 +41,12 @@ struct pacman_settings { | |||
40 | int bonus; | 41 | int bonus; |
41 | int ghostnames; | 42 | int ghostnames; |
42 | int showfps; | 43 | int showfps; |
44 | int sound; | ||
43 | }; | 45 | }; |
44 | 46 | ||
45 | static struct pacman_settings settings; | 47 | static struct pacman_settings settings; |
46 | static struct pacman_settings old_settings; | 48 | static struct pacman_settings old_settings; |
49 | static bool sound_playing = false; | ||
47 | 50 | ||
48 | #define SETTINGS_VERSION 1 | 51 | #define SETTINGS_VERSION 1 |
49 | #define SETTINGS_MIN_VERSION 1 | 52 | #define SETTINGS_MIN_VERSION 1 |
@@ -53,7 +56,7 @@ static char* difficulty_options[] = { "Normal", "Hard" }; | |||
53 | static char* numlives_options[] = { "1", "2", "3", "5" }; | 56 | static char* numlives_options[] = { "1", "2", "3", "5" }; |
54 | static char* bonus_options[] = {"10000", "15000", "20000", "No Bonus"}; | 57 | static char* bonus_options[] = {"10000", "15000", "20000", "No Bonus"}; |
55 | static char* ghostnames_options[] = {"Normal", "Alternate"}; | 58 | static char* ghostnames_options[] = {"Normal", "Alternate"}; |
56 | static char* showfps_options[] = {"No", "Yes"}; | 59 | static char* yesno_options[] = {"No", "Yes"}; |
57 | 60 | ||
58 | static struct configdata config[] = | 61 | static struct configdata config[] = |
59 | { | 62 | { |
@@ -65,7 +68,9 @@ static struct configdata config[] = | |||
65 | {TYPE_ENUM, 0, 2, { .int_p = &settings.ghostnames }, "Ghost Names", | 68 | {TYPE_ENUM, 0, 2, { .int_p = &settings.ghostnames }, "Ghost Names", |
66 | ghostnames_options}, | 69 | ghostnames_options}, |
67 | {TYPE_ENUM, 0, 2, { .int_p = &settings.showfps }, "Show FPS", | 70 | {TYPE_ENUM, 0, 2, { .int_p = &settings.showfps }, "Show FPS", |
68 | showfps_options}, | 71 | yesno_options}, |
72 | {TYPE_ENUM, 0, 2, { .int_p = &settings.sound }, "Sound", | ||
73 | yesno_options}, | ||
69 | }; | 74 | }; |
70 | 75 | ||
71 | static bool loadFile( const char * name, unsigned char * buf, int len ) | 76 | static bool loadFile( const char * name, unsigned char * buf, int len ) |
@@ -173,9 +178,21 @@ static bool pacbox_menu(void) | |||
173 | { "Alternate", -1 }, | 178 | { "Alternate", -1 }, |
174 | }; | 179 | }; |
175 | 180 | ||
181 | enum | ||
182 | { | ||
183 | PBMI_DIFFICULTY = 0, | ||
184 | PBMI_PACMEN_PER_GAME, | ||
185 | PBMI_BONUS_LIFE, | ||
186 | PBMI_GHOST_NAMES, | ||
187 | PBMI_DISPLAY_FPS, | ||
188 | PBMI_SOUND, | ||
189 | PBMI_RESTART, | ||
190 | PBMI_QUIT, | ||
191 | }; | ||
192 | |||
176 | MENUITEM_STRINGLIST(menu, "Pacbox Menu", NULL, | 193 | MENUITEM_STRINGLIST(menu, "Pacbox Menu", NULL, |
177 | "Difficulty", "Pacmen Per Game", "Bonus Life", | 194 | "Difficulty", "Pacmen Per Game", "Bonus Life", |
178 | "Ghost Names", "Display FPS", | 195 | "Ghost Names", "Display FPS", "Sound", |
179 | "Restart", "Quit"); | 196 | "Restart", "Quit"); |
180 | 197 | ||
181 | rb->button_clear_queue(); | 198 | rb->button_clear_queue(); |
@@ -189,7 +206,7 @@ static bool pacbox_menu(void) | |||
189 | 206 | ||
190 | switch(result) | 207 | switch(result) |
191 | { | 208 | { |
192 | case 0: | 209 | case PBMI_DIFFICULTY: |
193 | new_setting=settings.difficulty; | 210 | new_setting=settings.difficulty; |
194 | rb->set_option("Difficulty", &new_setting, INT, | 211 | rb->set_option("Difficulty", &new_setting, INT, |
195 | difficulty_options , 2, NULL); | 212 | difficulty_options , 2, NULL); |
@@ -198,7 +215,7 @@ static bool pacbox_menu(void) | |||
198 | need_restart=true; | 215 | need_restart=true; |
199 | } | 216 | } |
200 | break; | 217 | break; |
201 | case 1: | 218 | case PBMI_PACMEN_PER_GAME: |
202 | new_setting=settings.numlives; | 219 | new_setting=settings.numlives; |
203 | rb->set_option("Pacmen Per Game", &new_setting, INT, | 220 | rb->set_option("Pacmen Per Game", &new_setting, INT, |
204 | numlives_options , 4, NULL); | 221 | numlives_options , 4, NULL); |
@@ -207,7 +224,7 @@ static bool pacbox_menu(void) | |||
207 | need_restart=true; | 224 | need_restart=true; |
208 | } | 225 | } |
209 | break; | 226 | break; |
210 | case 2: | 227 | case PBMI_BONUS_LIFE: |
211 | new_setting=settings.bonus; | 228 | new_setting=settings.bonus; |
212 | rb->set_option("Bonus Life", &new_setting, INT, | 229 | rb->set_option("Bonus Life", &new_setting, INT, |
213 | bonus_options , 4, NULL); | 230 | bonus_options , 4, NULL); |
@@ -216,7 +233,7 @@ static bool pacbox_menu(void) | |||
216 | need_restart=true; | 233 | need_restart=true; |
217 | } | 234 | } |
218 | break; | 235 | break; |
219 | case 3: | 236 | case PBMI_GHOST_NAMES: |
220 | new_setting=settings.ghostnames; | 237 | new_setting=settings.ghostnames; |
221 | rb->set_option("Ghost Names", &new_setting, INT, | 238 | rb->set_option("Ghost Names", &new_setting, INT, |
222 | ghostname_options , 2, NULL); | 239 | ghostname_options , 2, NULL); |
@@ -225,11 +242,15 @@ static bool pacbox_menu(void) | |||
225 | need_restart=true; | 242 | need_restart=true; |
226 | } | 243 | } |
227 | break; | 244 | break; |
228 | case 4: /* Show FPS */ | 245 | case PBMI_DISPLAY_FPS: |
229 | rb->set_option("Display FPS",&settings.showfps,INT, | 246 | rb->set_option("Display FPS",&settings.showfps,INT, |
230 | noyes, 2, NULL); | 247 | noyes, 2, NULL); |
231 | break; | 248 | break; |
232 | case 5: /* Restart */ | 249 | case PBMI_SOUND: |
250 | rb->set_option("Sound",&settings.sound, INT, | ||
251 | noyes, 2, NULL); | ||
252 | break; | ||
253 | case PBMI_RESTART: | ||
233 | need_restart=true; | 254 | need_restart=true; |
234 | menu_quit=1; | 255 | menu_quit=1; |
235 | break; | 256 | break; |
@@ -252,16 +273,93 @@ static bool pacbox_menu(void) | |||
252 | restart game | 273 | restart game |
253 | usb connected | 274 | usb connected |
254 | */ | 275 | */ |
255 | return (result==6); | 276 | return (result==PBMI_QUIT); |
277 | } | ||
278 | |||
279 | /* Sound is emulated in ISR context, so not much is done per sound frame */ | ||
280 | #define NBSAMPLES 128 | ||
281 | static uint32_t sound_buf[NBSAMPLES]; | ||
282 | static int raw_buf[NBSAMPLES] IBSS_ATTR; | ||
283 | |||
284 | /* | ||
285 | Audio callback | ||
286 | */ | ||
287 | static void get_more(unsigned char **start, size_t *size) | ||
288 | { | ||
289 | int i; | ||
290 | int32_t *out; | ||
291 | int *raw; | ||
292 | |||
293 | /* Emulate the audio for the current register settings */ | ||
294 | playSound(raw_buf, NBSAMPLES); | ||
295 | |||
296 | out = sound_buf; | ||
297 | raw = raw_buf; | ||
298 | |||
299 | /* Normalize the audio and convert to stereo */ | ||
300 | for (i = 0; i < NBSAMPLES; i++) | ||
301 | { | ||
302 | uint32_t sample = (uint16_t)*raw++ << 6; | ||
303 | *out++ = sample | (sample << 16); | ||
304 | } | ||
305 | |||
306 | *start = (unsigned char *)sound_buf; | ||
307 | *size = NBSAMPLES*sizeof(sound_buf[0]); | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | Start the sound emulation | ||
312 | */ | ||
313 | static void start_sound(void) | ||
314 | { | ||
315 | int sr_index; | ||
316 | |||
317 | if (sound_playing) | ||
318 | return; | ||
319 | |||
320 | #ifndef PLUGIN_USE_IRAM | ||
321 | /* Ensure control of PCM - stopping music isn't obligatory */ | ||
322 | rb->plugin_get_audio_buffer(NULL); | ||
323 | #endif | ||
324 | |||
325 | /* Get the closest rate >= to what is preferred */ | ||
326 | sr_index = rb->round_value_to_list32(PREFERRED_SAMPLING_RATE, | ||
327 | rb->hw_freq_sampr, HW_NUM_FREQ, false); | ||
328 | |||
329 | if (rb->hw_freq_sampr[sr_index] < PREFERRED_SAMPLING_RATE | ||
330 | && sr_index > 0) | ||
331 | { | ||
332 | /* Round up */ | ||
333 | sr_index--; | ||
334 | } | ||
335 | |||
336 | wsg3_set_sampling_rate(rb->hw_freq_sampr[sr_index]); | ||
337 | |||
338 | rb->pcm_set_frequency(rb->hw_freq_sampr[sr_index]); | ||
339 | rb->pcm_play_data(get_more, NULL, 0); | ||
340 | |||
341 | sound_playing = true; | ||
256 | } | 342 | } |
257 | 343 | ||
344 | /* | ||
345 | Stop the sound emulation | ||
346 | */ | ||
347 | static void stop_sound(void) | ||
348 | { | ||
349 | if (!sound_playing) | ||
350 | return; | ||
351 | |||
352 | rb->pcm_play_stop(); | ||
353 | rb->pcm_set_frequency(HW_SAMPR_DEFAULT); | ||
354 | |||
355 | sound_playing = false; | ||
356 | } | ||
258 | 357 | ||
259 | /* | 358 | /* |
260 | Runs the game engine for one frame. | 359 | Runs the game engine for one frame. |
261 | */ | 360 | */ |
262 | static int gameProc( void ) | 361 | static int gameProc( void ) |
263 | { | 362 | { |
264 | int x; | ||
265 | int fps; | 363 | int fps; |
266 | char str[80]; | 364 | char str[80]; |
267 | int status; | 365 | int status; |
@@ -269,6 +367,9 @@ static int gameProc( void ) | |||
269 | int frame_counter = 0; | 367 | int frame_counter = 0; |
270 | int yield_counter = 0; | 368 | int yield_counter = 0; |
271 | 369 | ||
370 | if (settings.sound) | ||
371 | start_sound(); | ||
372 | |||
272 | while (1) | 373 | while (1) |
273 | { | 374 | { |
274 | /* Run the machine for one frame (1/60th second) */ | 375 | /* Run the machine for one frame (1/60th second) */ |
@@ -289,14 +390,25 @@ static int gameProc( void ) | |||
289 | || status == PACMAN_RC_MENU | 390 | || status == PACMAN_RC_MENU |
290 | #endif | 391 | #endif |
291 | ) { | 392 | ) { |
393 | bool menu_res; | ||
394 | |||
292 | end_time = *rb->current_tick; | 395 | end_time = *rb->current_tick; |
293 | x = pacbox_menu(); | 396 | |
397 | stop_sound(); | ||
398 | |||
399 | menu_res = pacbox_menu(); | ||
400 | |||
294 | rb->lcd_clear_display(); | 401 | rb->lcd_clear_display(); |
295 | #ifdef HAVE_REMOTE_LCD | 402 | #ifdef HAVE_REMOTE_LCD |
296 | rb->lcd_remote_clear_display(); | 403 | rb->lcd_remote_clear_display(); |
297 | rb->lcd_remote_update(); | 404 | rb->lcd_remote_update(); |
298 | #endif | 405 | #endif |
299 | if (x == 1) { return 1; } | 406 | if (menu_res) |
407 | return 1; | ||
408 | |||
409 | if (settings.sound) | ||
410 | start_sound(); | ||
411 | |||
300 | start_time += *rb->current_tick-end_time; | 412 | start_time += *rb->current_tick-end_time; |
301 | } | 413 | } |
302 | 414 | ||
@@ -368,6 +480,9 @@ static int gameProc( void ) | |||
368 | } | 480 | } |
369 | } | 481 | } |
370 | } | 482 | } |
483 | |||
484 | stop_sound(); | ||
485 | |||
371 | return 0; | 486 | return 0; |
372 | } | 487 | } |
373 | 488 | ||
@@ -392,6 +507,7 @@ enum plugin_status plugin_start(const void* parameter) | |||
392 | settings.bonus = 0; /* 10000 points */ | 507 | settings.bonus = 0; /* 10000 points */ |
393 | settings.ghostnames = 0; /* Normal names */ | 508 | settings.ghostnames = 0; /* Normal names */ |
394 | settings.showfps = 0; /* Do not show FPS */ | 509 | settings.showfps = 0; /* Do not show FPS */ |
510 | settings.sound = 0; /* Sound off by default */ | ||
395 | 511 | ||
396 | if (configfile_load(SETTINGS_FILENAME, config, | 512 | if (configfile_load(SETTINGS_FILENAME, config, |
397 | sizeof(config)/sizeof(*config), | 513 | sizeof(config)/sizeof(*config), |