summaryrefslogtreecommitdiff
path: root/apps/plugins/pacbox/pacbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pacbox/pacbox.c')
-rw-r--r--apps/plugins/pacbox/pacbox.c142
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
45static struct pacman_settings settings; 47static struct pacman_settings settings;
46static struct pacman_settings old_settings; 48static struct pacman_settings old_settings;
49static 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" };
53static char* numlives_options[] = { "1", "2", "3", "5" }; 56static char* numlives_options[] = { "1", "2", "3", "5" };
54static char* bonus_options[] = {"10000", "15000", "20000", "No Bonus"}; 57static char* bonus_options[] = {"10000", "15000", "20000", "No Bonus"};
55static char* ghostnames_options[] = {"Normal", "Alternate"}; 58static char* ghostnames_options[] = {"Normal", "Alternate"};
56static char* showfps_options[] = {"No", "Yes"}; 59static char* yesno_options[] = {"No", "Yes"};
57 60
58static struct configdata config[] = 61static 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
71static bool loadFile( const char * name, unsigned char * buf, int len ) 76static 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
281static uint32_t sound_buf[NBSAMPLES];
282static int raw_buf[NBSAMPLES] IBSS_ATTR;
283
284/*
285 Audio callback
286 */
287static 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*/
313static 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*/
347static 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*/
262static int gameProc( void ) 361static 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),