diff options
Diffstat (limited to 'apps/plugins/xworld/sys.c')
-rw-r--r-- | apps/plugins/xworld/sys.c | 340 |
1 files changed, 269 insertions, 71 deletions
diff --git a/apps/plugins/xworld/sys.c b/apps/plugins/xworld/sys.c index 03b032c055..b13d4fb9ed 100644 --- a/apps/plugins/xworld/sys.c +++ b/apps/plugins/xworld/sys.c | |||
@@ -130,13 +130,32 @@ static bool sys_do_help(void) | |||
130 | rb->lcd_set_background(LCD_BLACK); | 130 | rb->lcd_set_background(LCD_BLACK); |
131 | #endif | 131 | #endif |
132 | rb->lcd_setfont(FONT_UI); | 132 | rb->lcd_setfont(FONT_UI); |
133 | char* help_text[] = {"XWorld", "", | 133 | char *help_text[] = { |
134 | "XWorld", "is", "an", "interpreter", "for", "Another", "World,", "a", "fantastic", "game", "by", "Eric", "Chahi." | 134 | "XWorld", "", |
135 | }; | 135 | "XWorld", "is", "a", "port", "of", "a", "bytecode", "interpreter", "for", "`Another", "World',", "a", "cinematic", "adventure", "game", "by", "Eric", "Chahi.", |
136 | "", | ||
137 | "", | ||
138 | "Level", "Codes:", "", | ||
139 | "Level", "1:", "LDKD", "", | ||
140 | "Level", "2:", "HTDC", "", | ||
141 | "Level", "3:", "CLLD", "", | ||
142 | "Level", "4:", "LBKG", "", | ||
143 | "Level", "5:", "XDDJ", "", | ||
144 | "Level", "6:", "FXLC", "", | ||
145 | "Level", "7:", "KRFK", "", | ||
146 | "Level", "8:", "KFLB", "", | ||
147 | "Level", "9:", "DDRX", "", | ||
148 | "Level", "10:", "BFLX", "", | ||
149 | "Level", "11:", "BRTD", "", | ||
150 | "Level", "12:", "TFBB", "", | ||
151 | "Level", "13:", "TXHF", "", | ||
152 | "Level", "14:", "CKJL", "", | ||
153 | "Level", "15:", "LFCK", "", | ||
154 | }; | ||
136 | struct style_text style[] = { | 155 | struct style_text style[] = { |
137 | {0, TEXT_CENTER | TEXT_UNDERLINE}, | 156 | { 0, TEXT_CENTER | TEXT_UNDERLINE }, |
138 | LAST_STYLE_ITEM | ||
139 | }; | 157 | }; |
158 | |||
140 | return display_text(ARRAYLEN(help_text), help_text, style, NULL, true); | 159 | return display_text(ARRAYLEN(help_text), help_text, style, NULL, true); |
141 | } | 160 | } |
142 | 161 | ||
@@ -149,19 +168,22 @@ static const struct opt_items scaling_settings[3] = { | |||
149 | }; | 168 | }; |
150 | 169 | ||
151 | static const struct opt_items rotation_settings[3] = { | 170 | static const struct opt_items rotation_settings[3] = { |
152 | { "Disabled" , -1 }, | 171 | { "Disabled" , -1 }, |
153 | { "Clockwise" , -1 }, | 172 | { "Clockwise" , -1 }, |
154 | { "Anticlockwise", -1 } | 173 | { "Counterclockwise", -1 } |
155 | }; | 174 | }; |
156 | 175 | ||
157 | static void do_video_settings(struct System* sys) | 176 | static void do_video_settings(struct System* sys) |
158 | { | 177 | { |
159 | MENUITEM_STRINGLIST(menu, "Video Settings", NULL, | 178 | MENUITEM_STRINGLIST(menu, "Video Settings", NULL, |
160 | "Negative", | 179 | "Negative", |
180 | #ifdef SYS_MOTION_BLUR | ||
181 | "Motion Blur", | ||
182 | #endif | ||
161 | "Scaling", | 183 | "Scaling", |
162 | "Rotation", | 184 | "Rotation", |
163 | "Show FPS", | 185 | "Show FPS", |
164 | "Zoom on code", | 186 | "Zoom on Code", |
165 | "Back"); | 187 | "Back"); |
166 | int sel = 0; | 188 | int sel = 0; |
167 | while(1) | 189 | while(1) |
@@ -171,7 +193,16 @@ static void do_video_settings(struct System* sys) | |||
171 | case 0: | 193 | case 0: |
172 | rb->set_bool("Negative", &sys->settings.negative_enabled); | 194 | rb->set_bool("Negative", &sys->settings.negative_enabled); |
173 | break; | 195 | break; |
196 | #ifdef SYS_MOTION_BLUR | ||
197 | case 1: | ||
198 | rb->set_bool("Motion Blur", &sys->settings.blur); | ||
199 | break; | ||
200 | #endif | ||
201 | #ifndef SYS_MOTION_BLUR | ||
174 | case 1: | 202 | case 1: |
203 | #else | ||
204 | case 2: | ||
205 | #endif | ||
175 | rb->set_option("Scaling", &sys->settings.scaling_quality, INT, scaling_settings, | 206 | rb->set_option("Scaling", &sys->settings.scaling_quality, INT, scaling_settings, |
176 | #ifdef HAVE_LCD_COLOR | 207 | #ifdef HAVE_LCD_COLOR |
177 | 3 | 208 | 3 |
@@ -186,7 +217,11 @@ static void do_video_settings(struct System* sys) | |||
186 | sys->settings.zoom = false; | 217 | sys->settings.zoom = false; |
187 | } | 218 | } |
188 | break; | 219 | break; |
220 | #ifndef SYS_MOTION_BLUR | ||
189 | case 2: | 221 | case 2: |
222 | #else | ||
223 | case 3: | ||
224 | #endif | ||
190 | rb->set_option("Rotation", &sys->settings.rotation_option, INT, rotation_settings, 3, NULL); | 225 | rb->set_option("Rotation", &sys->settings.rotation_option, INT, rotation_settings, 3, NULL); |
191 | if(sys->settings.rotation_option && | 226 | if(sys->settings.rotation_option && |
192 | sys->settings.zoom) | 227 | sys->settings.zoom) |
@@ -196,45 +231,42 @@ static void do_video_settings(struct System* sys) | |||
196 | } | 231 | } |
197 | sys_rotate_keymap(sys); | 232 | sys_rotate_keymap(sys); |
198 | break; | 233 | break; |
234 | #ifndef SYS_MOTION_BLUR | ||
199 | case 3: | 235 | case 3: |
236 | #else | ||
237 | case 4: | ||
238 | #endif | ||
200 | rb->set_bool("Show FPS", &sys->settings.showfps); | 239 | rb->set_bool("Show FPS", &sys->settings.showfps); |
201 | break; | 240 | break; |
241 | #ifndef SYS_MOTION_BLUR | ||
202 | case 4: | 242 | case 4: |
203 | rb->set_bool("Zoom on code", &sys->settings.zoom); | 243 | #else |
244 | case 5: | ||
245 | #endif | ||
246 | rb->set_bool("Zoom on Code", &sys->settings.zoom); | ||
204 | /* zoom only works with scaling and rotation disabled */ | 247 | /* zoom only works with scaling and rotation disabled */ |
205 | if(sys->settings.zoom && | 248 | if(sys->settings.zoom && (sys->settings.scaling_quality || sys->settings.rotation_option)) |
206 | ( sys->settings.scaling_quality | | ||
207 | sys->settings.rotation_option)) | ||
208 | { | 249 | { |
209 | rb->splash(HZ*2, "Scaling and rotation automatically disabled."); | 250 | rb->splash(HZ*2, "Scaling and rotation automatically disabled."); |
210 | sys->settings.scaling_quality = 0; | 251 | sys->settings.scaling_quality = 0; |
211 | sys->settings.rotation_option = 0; | 252 | sys->settings.rotation_option = 0; |
212 | } | 253 | } |
213 | break; | 254 | break; |
214 | case 5: | 255 | default: |
215 | rb->lcd_clear_display(); | ||
216 | sys_save_settings(sys); | 256 | sys_save_settings(sys); |
217 | return; | 257 | return; |
218 | } | 258 | } |
219 | } | 259 | } |
220 | } | 260 | } |
221 | 261 | ||
222 | #define MAX_SOUNDBUF_SIZE 512 | 262 | #define MAX_SOUNDBUF_SIZE 256 |
223 | const struct opt_items sound_bufsize_options[] = { | ||
224 | {"8 samples" , 8}, | ||
225 | {"16 samples" , 16}, | ||
226 | {"32 samples" , 32}, | ||
227 | {"64 samples" , 64}, | ||
228 | {"128 samples", 128}, | ||
229 | {"256 samples", 256}, | ||
230 | {"512 samples", 512}, | ||
231 | }; | ||
232 | 263 | ||
233 | static void do_sound_settings(struct System* sys) | 264 | static void do_sound_settings(struct System* sys) |
234 | { | 265 | { |
235 | MENUITEM_STRINGLIST(menu, "Sound Settings", NULL, | 266 | MENUITEM_STRINGLIST(menu, "Sound Settings", NULL, |
236 | "Enabled", | 267 | "Enabled", |
237 | "Buffer Level", | 268 | "Buffer Level", |
269 | "Volume", | ||
238 | "Back", | 270 | "Back", |
239 | ); | 271 | ); |
240 | int sel = 0; | 272 | int sel = 0; |
@@ -246,10 +278,17 @@ static void do_sound_settings(struct System* sys) | |||
246 | rb->set_bool("Enabled", &sys->settings.sound_enabled); | 278 | rb->set_bool("Enabled", &sys->settings.sound_enabled); |
247 | break; | 279 | break; |
248 | case 1: | 280 | case 1: |
249 | rb->set_option("Buffer Level", &sys->settings.sound_bufsize, INT, | 281 | rb->set_int("Buffer Level", "samples", UNIT_INT, &sys->settings.sound_bufsize, NULL, 16, 16, MAX_SOUNDBUF_SIZE, NULL); |
250 | sound_bufsize_options, ARRAYLEN(sound_bufsize_options), NULL); | ||
251 | break; | 282 | break; |
252 | case 2: | 283 | case 2: |
284 | { | ||
285 | const struct settings_list* vol = | ||
286 | rb->find_setting(&rb->global_settings->volume, NULL); | ||
287 | rb->option_screen((struct settings_list*)vol, NULL, false, "Volume"); | ||
288 | break; | ||
289 | } | ||
290 | case 3: | ||
291 | default: | ||
253 | sys_save_settings(sys); | 292 | sys_save_settings(sys); |
254 | return; | 293 | return; |
255 | } | 294 | } |
@@ -259,12 +298,13 @@ static void do_sound_settings(struct System* sys) | |||
259 | static void sys_reset_settings(struct System* sys) | 298 | static void sys_reset_settings(struct System* sys) |
260 | { | 299 | { |
261 | sys->settings.negative_enabled = false; | 300 | sys->settings.negative_enabled = false; |
262 | sys->settings.rotation_option = 0; | 301 | sys->settings.rotation_option = 0; // off |
263 | sys->settings.scaling_quality = 1; | 302 | sys->settings.scaling_quality = 1; // fast |
264 | sys->settings.sound_enabled = true; | 303 | sys->settings.sound_enabled = true; |
265 | sys->settings.sound_bufsize = 64; | 304 | sys->settings.sound_bufsize = 32; /* keep this low */ |
266 | sys->settings.showfps = true; | 305 | sys->settings.showfps = false; |
267 | sys->settings.zoom = false; | 306 | sys->settings.zoom = false; |
307 | sys->settings.blur = false; | ||
268 | sys_rotate_keymap(sys); | 308 | sys_rotate_keymap(sys); |
269 | } | 309 | } |
270 | 310 | ||
@@ -278,18 +318,32 @@ static int mainmenu_cb(int action, const struct menu_item_ex *this_item) | |||
278 | return action; | 318 | return action; |
279 | } | 319 | } |
280 | 320 | ||
281 | static AudioCallback audio_callback; | 321 | static AudioCallback audio_callback = NULL; |
322 | static void get_more(const void** start, size_t* size); | ||
282 | static void* audio_param; | 323 | static void* audio_param; |
283 | static struct System* audio_sys; | 324 | static struct System* audio_sys; |
284 | 325 | ||
285 | /************************************** MAIN MENU ***************************************/ | 326 | /************************************** MAIN MENU ***************************************/ |
327 | /* called after game init */ | ||
286 | 328 | ||
287 | void sys_menu(struct System* sys) | 329 | void sys_menu(struct System* sys) |
288 | { | 330 | { |
289 | sys_stopAudio(sys); | 331 | sys_stopAudio(sys); |
332 | |||
333 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
334 | /* boost for load */ | ||
335 | rb->cpu_boost(true); | ||
336 | #endif | ||
337 | |||
290 | rb->splash(0, "Loading..."); | 338 | rb->splash(0, "Loading..."); |
291 | sys->loaded = engine_loadGameState(sys->e, 0); | 339 | sys->loaded = engine_loadGameState(sys->e, 0); |
340 | |||
341 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
342 | rb->cpu_boost(false); | ||
343 | #endif | ||
344 | |||
292 | rb->lcd_update(); | 345 | rb->lcd_update(); |
346 | |||
293 | mainmenu_sysptr = sys; | 347 | mainmenu_sysptr = sys; |
294 | MENUITEM_STRINGLIST(menu, "XWorld Menu", mainmenu_cb, | 348 | MENUITEM_STRINGLIST(menu, "XWorld Menu", mainmenu_cb, |
295 | "Resume Game", /* 0 */ | 349 | "Resume Game", /* 0 */ |
@@ -352,19 +406,21 @@ void sys_menu(struct System* sys) | |||
352 | exit(PLUGIN_OK); | 406 | exit(PLUGIN_OK); |
353 | break; | 407 | break; |
354 | default: | 408 | default: |
355 | error("sys_menu: fall-through!"); | 409 | break; |
356 | } | 410 | } |
357 | } | 411 | } |
358 | rb->lcd_clear_display(); | 412 | |
413 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
414 | /* boost for game */ | ||
415 | rb->cpu_boost(true); | ||
416 | #endif | ||
417 | |||
359 | sys_startAudio(sys, audio_callback, audio_param); | 418 | sys_startAudio(sys, audio_callback, audio_param); |
360 | } | 419 | } |
361 | 420 | ||
362 | void sys_init(struct System* sys, const char* title) | 421 | void sys_init(struct System* sys, const char* title) |
363 | { | 422 | { |
364 | (void) title; | 423 | (void) title; |
365 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
366 | rb->cpu_boost(true); | ||
367 | #endif | ||
368 | backlight_ignore_timeout(); | 424 | backlight_ignore_timeout(); |
369 | rb_atexit(exit_handler); | 425 | rb_atexit(exit_handler); |
370 | save_sys = sys; | 426 | save_sys = sys; |
@@ -565,9 +621,9 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16 | |||
565 | int r, g, b; | 621 | int r, g, b; |
566 | fb_data pix = rb->lcd_framebuffer[y * LCD_WIDTH + x]; | 622 | fb_data pix = rb->lcd_framebuffer[y * LCD_WIDTH + x]; |
567 | #if (LCD_DEPTH == 24) | 623 | #if (LCD_DEPTH == 24) |
568 | r = pix.r; | 624 | r = 0xff - pix.r; |
569 | g = pix.g; | 625 | g = 0xff - pix.g; |
570 | b = pix.b; | 626 | b = 0xff - pix.b; |
571 | rb->lcd_framebuffer[y * LCD_WIDTH + x] = (fb_data) { b, g, r }; | 627 | rb->lcd_framebuffer[y * LCD_WIDTH + x] = (fb_data) { b, g, r }; |
572 | #else | 628 | #else |
573 | r = RGB_UNPACK_RED (pix); | 629 | r = RGB_UNPACK_RED (pix); |
@@ -582,6 +638,57 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16 | |||
582 | } | 638 | } |
583 | } | 639 | } |
584 | 640 | ||
641 | #ifdef SYS_MOTION_BLUR | ||
642 | if(sys->settings.blur) | ||
643 | { | ||
644 | static fb_data *prev_frames = NULL; | ||
645 | static fb_data *orig_fb = NULL; | ||
646 | static int prev_baseidx = 0; /* circular buffer */ | ||
647 | if(!prev_frames) | ||
648 | { | ||
649 | prev_frames = sys_get_buffer(sys, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT * BLUR_FRAMES); | ||
650 | orig_fb = sys_get_buffer(sys, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT); | ||
651 | |||
652 | rb->memset(prev_frames, 0, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT * BLUR_FRAMES); | ||
653 | } | ||
654 | if(prev_frames && orig_fb) | ||
655 | { | ||
656 | |||
657 | rb->memcpy(orig_fb, rb->lcd_framebuffer, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT); | ||
658 | /* fancy useless slow motion blur */ | ||
659 | for(int y = 0; y < LCD_HEIGHT; ++y) | ||
660 | { | ||
661 | for(int x = 0; x < LCD_WIDTH; ++x) | ||
662 | { | ||
663 | int r, g, b; | ||
664 | fb_data pix = rb->lcd_framebuffer[y * LCD_WIDTH + x]; | ||
665 | r = RGB_UNPACK_RED (pix); | ||
666 | g = RGB_UNPACK_GREEN(pix); | ||
667 | b = RGB_UNPACK_BLUE (pix); | ||
668 | r *= BLUR_FRAMES + 1; | ||
669 | g *= BLUR_FRAMES + 1; | ||
670 | b *= BLUR_FRAMES + 1; | ||
671 | for(int i = 0; i < BLUR_FRAMES; ++i) | ||
672 | { | ||
673 | fb_data prev_pix = prev_frames[ (prev_baseidx + i * (LCD_WIDTH * LCD_HEIGHT)) % (LCD_WIDTH * LCD_HEIGHT * BLUR_FRAMES) + y * LCD_WIDTH + x]; | ||
674 | r += (BLUR_FRAMES-i) * RGB_UNPACK_RED(prev_pix); | ||
675 | g += (BLUR_FRAMES-i) * RGB_UNPACK_GREEN(prev_pix); | ||
676 | b += (BLUR_FRAMES-i) * RGB_UNPACK_BLUE(prev_pix); | ||
677 | } | ||
678 | r /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1); | ||
679 | g /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1); | ||
680 | b /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1); | ||
681 | rb->lcd_framebuffer[y * LCD_WIDTH + x] = LCD_RGBPACK(r, g, b); | ||
682 | } | ||
683 | } | ||
684 | prev_baseidx -= LCD_WIDTH * LCD_HEIGHT; | ||
685 | if(prev_baseidx < 0) | ||
686 | prev_baseidx += BLUR_FRAMES * LCD_WIDTH * LCD_HEIGHT; | ||
687 | rb->memcpy(prev_frames + prev_baseidx, orig_fb, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT); | ||
688 | } | ||
689 | } | ||
690 | #endif | ||
691 | |||
585 | /*********************** SHOW FPS *************************/ | 692 | /*********************** SHOW FPS *************************/ |
586 | 693 | ||
587 | int current_time = sys_getTimeStamp(sys); | 694 | int current_time = sys_getTimeStamp(sys); |
@@ -599,6 +706,11 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16 | |||
599 | static void do_pause_menu(struct System* sys) | 706 | static void do_pause_menu(struct System* sys) |
600 | { | 707 | { |
601 | sys_stopAudio(sys); | 708 | sys_stopAudio(sys); |
709 | |||
710 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
711 | rb->cpu_boost(false); | ||
712 | #endif | ||
713 | |||
602 | int sel = 0; | 714 | int sel = 0; |
603 | MENUITEM_STRINGLIST(menu, "XWorld Menu", NULL, | 715 | MENUITEM_STRINGLIST(menu, "XWorld Menu", NULL, |
604 | "Resume Game", /* 0 */ | 716 | "Resume Game", /* 0 */ |
@@ -663,52 +775,130 @@ static void do_pause_menu(struct System* sys) | |||
663 | break; | 775 | break; |
664 | } | 776 | } |
665 | } | 777 | } |
666 | rb->lcd_clear_display(); | 778 | |
779 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
780 | rb->cpu_boost(true); | ||
781 | #endif | ||
782 | |||
667 | sys_startAudio(sys, audio_callback, audio_param); | 783 | sys_startAudio(sys, audio_callback, audio_param); |
668 | } | 784 | } |
669 | 785 | ||
670 | void sys_processEvents(struct System* sys) | 786 | void sys_processEvents(struct System* sys) |
671 | { | 787 | { |
672 | int btn = rb->button_get(false); | 788 | int btn = rb->button_status(); |
673 | btn &= ~BUTTON_REDRAW; | 789 | rb->button_clear_queue(); |
790 | |||
791 | static int oldbuttonstate = 0; | ||
792 | |||
674 | debug(DBG_SYS, "button is 0x%08x", btn); | 793 | debug(DBG_SYS, "button is 0x%08x", btn); |
675 | 794 | ||
676 | /* exit early if we can */ | 795 | /* exit early if we can */ |
677 | if(btn == BUTTON_NONE) | 796 | if(btn == oldbuttonstate) |
678 | { | 797 | { |
679 | return; | 798 | return; |
680 | } | 799 | } |
681 | 800 | ||
801 | /* handle special keys first */ | ||
802 | switch(btn) | ||
803 | { | ||
804 | case BTN_PAUSE: | ||
805 | do_pause_menu(sys); | ||
806 | sys->input.dirMask = 0; | ||
807 | sys->input.button = false; | ||
808 | /* exit early to avoid unwanted button presses being detected */ | ||
809 | return; | ||
810 | default: | ||
811 | exit_on_usb(btn); | ||
812 | break; | ||
813 | } | ||
814 | |||
682 | /* Ignore some buttons that cause errant input */ | 815 | /* Ignore some buttons that cause errant input */ |
816 | |||
817 | btn &= ~BUTTON_REDRAW; | ||
818 | |||
683 | #if (CONFIG_KEYPAD == IPOD_4G_PAD) || \ | 819 | #if (CONFIG_KEYPAD == IPOD_4G_PAD) || \ |
684 | (CONFIG_KEYPAD == IPOD_3G_PAD) || \ | 820 | (CONFIG_KEYPAD == IPOD_3G_PAD) || \ |
685 | (CONFIG_KEYPAD == IPOD_1G2G_PAD) | 821 | (CONFIG_KEYPAD == IPOD_1G2G_PAD) |
686 | if(btn & 0x80000000) | 822 | if(btn & 0x80000000) |
687 | return; | 823 | return; |
688 | #endif | 824 | #endif |
825 | |||
689 | #if (CONFIG_KEYPAD == SANSA_E200_PAD) | 826 | #if (CONFIG_KEYPAD == SANSA_E200_PAD) |
690 | if(btn == (BUTTON_SCROLL_FWD || BUTTON_SCROLL_BACK)) | 827 | if(btn == (BUTTON_SCROLL_FWD || BUTTON_SCROLL_BACK)) |
691 | return; | 828 | return; |
692 | #endif | 829 | #endif |
830 | |||
693 | #if (CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD) | 831 | #if (CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD) |
694 | if(btn == (BUTTON_SELECT)) | 832 | if(btn == (BUTTON_SELECT)) |
695 | return; | 833 | return; |
696 | #endif | 834 | #endif |
697 | 835 | ||
698 | /* handle special keys first */ | 836 | /* copied from doom which was copied from rockboy... */ |
699 | switch(btn) | 837 | unsigned released = ~btn & oldbuttonstate; |
838 | unsigned pressed = btn & ~oldbuttonstate; | ||
839 | oldbuttonstate = btn; | ||
840 | |||
841 | if(released) | ||
700 | { | 842 | { |
701 | case BTN_PAUSE: | 843 | if(released & BTN_FIRE) |
702 | do_pause_menu(sys); | 844 | sys->input.button = false; |
703 | sys->input.dirMask = 0; | 845 | if(released & sys->keymap.up) |
704 | sys->input.button = false; | 846 | sys->input.dirMask &= ~DIR_UP; |
705 | /* exit early to avoid unwanted button presses being detected */ | 847 | if(released & sys->keymap.down) |
706 | return; | 848 | sys->input.dirMask &= ~DIR_DOWN; |
707 | default: | 849 | if(released & sys->keymap.left) |
708 | exit_on_usb(btn); | 850 | sys->input.dirMask &= ~DIR_LEFT; |
709 | break; | 851 | if(released & sys->keymap.right) |
852 | sys->input.dirMask &= ~DIR_RIGHT; | ||
853 | #ifdef BTN_DOWN_LEFT | ||
854 | if(released & sys->keymap.downleft) | ||
855 | sys->input.dirMask &= ~(DIR_DOWN | DIR_LEFT); | ||
856 | #endif | ||
857 | #ifdef BTN_DOWN_RIGHT | ||
858 | if(released & sys->keymap.downright) | ||
859 | sys->input.dirMask &= ~(DIR_DOWN | DIR_RIGHT); | ||
860 | #endif | ||
861 | #ifdef BTN_UP_LEFT | ||
862 | if(released & sys->keymap.upleft) | ||
863 | sys->input.dirMask &= ~(DIR_UP | DIR_LEFT); | ||
864 | #endif | ||
865 | #ifdef BTN_UP_RIGHT | ||
866 | if(released & sys->keymap.upright) | ||
867 | sys->input.dirMask &= ~(DIR_UP | DIR_RIGHT); | ||
868 | #endif | ||
869 | } | ||
870 | |||
871 | if(pressed) | ||
872 | { | ||
873 | if(pressed & BTN_FIRE) | ||
874 | sys->input.button = true; | ||
875 | if(pressed & sys->keymap.up) | ||
876 | sys->input.dirMask |= DIR_UP; | ||
877 | if(pressed & sys->keymap.down) | ||
878 | sys->input.dirMask |= DIR_DOWN; | ||
879 | if(pressed & sys->keymap.left) | ||
880 | sys->input.dirMask |= DIR_LEFT; | ||
881 | if(pressed & sys->keymap.right) | ||
882 | sys->input.dirMask |= DIR_RIGHT; | ||
883 | #ifdef BTN_DOWN_LEFT | ||
884 | if(pressed & sys->keymap.downleft) | ||
885 | sys->input.dirMask |= (DIR_DOWN | DIR_LEFT); | ||
886 | #endif | ||
887 | #ifdef BTN_DOWN_RIGHT | ||
888 | if(pressed & sys->keymap.downright) | ||
889 | sys->input.dirMask |= (DIR_DOWN | DIR_RIGHT); | ||
890 | #endif | ||
891 | #ifdef BTN_UP_LEFT | ||
892 | if(pressed & sys->keymap.upleft) | ||
893 | sys->input.dirMask |= (DIR_UP | DIR_LEFT); | ||
894 | #endif | ||
895 | #ifdef BTN_UP_RIGHT | ||
896 | if(pressed & sys->keymap.upright) | ||
897 | sys->input.dirMask |= (DIR_UP | DIR_RIGHT); | ||
898 | #endif | ||
710 | } | 899 | } |
711 | 900 | ||
901 | #if 0 | ||
712 | /* handle releases */ | 902 | /* handle releases */ |
713 | if(btn & BUTTON_REL) | 903 | if(btn & BUTTON_REL) |
714 | { | 904 | { |
@@ -774,6 +964,7 @@ void sys_processEvents(struct System* sys) | |||
774 | } | 964 | } |
775 | debug(DBG_SYS, "dirMask is 0x%02x", sys->input.dirMask); | 965 | debug(DBG_SYS, "dirMask is 0x%02x", sys->input.dirMask); |
776 | debug(DBG_SYS, "button is %s", sys->input.button == true ? "true" : "false"); | 966 | debug(DBG_SYS, "button is %s", sys->input.button == true ? "true" : "false"); |
967 | #endif | ||
777 | } | 968 | } |
778 | 969 | ||
779 | void sys_sleep(struct System* sys, uint32_t duration) | 970 | void sys_sleep(struct System* sys, uint32_t duration) |
@@ -789,26 +980,28 @@ uint32_t sys_getTimeStamp(struct System* sys) | |||
789 | return (uint32_t) (*rb->current_tick * (1000/HZ)); | 980 | return (uint32_t) (*rb->current_tick * (1000/HZ)); |
790 | } | 981 | } |
791 | 982 | ||
792 | static int16_t rb_soundbuf [MAX_SOUNDBUF_SIZE] IBSS_ATTR; | 983 | /* game provides us mono samples, we need stereo */ |
793 | static int8_t temp_soundbuf[MAX_SOUNDBUF_SIZE] IBSS_ATTR; | 984 | static int16_t rb_soundbuf[MAX_SOUNDBUF_SIZE * 2]; |
794 | static void ICODE_ATTR get_more(const void** start, size_t* size) | 985 | static int8_t temp_soundbuf[MAX_SOUNDBUF_SIZE]; |
986 | |||
987 | static void get_more(const void** start, size_t* size) | ||
795 | { | 988 | { |
796 | if(audio_sys->settings.sound_enabled) | 989 | if(audio_sys->settings.sound_enabled && audio_callback) |
797 | { | 990 | { |
798 | audio_callback(audio_param, temp_soundbuf, audio_sys->settings.sound_bufsize); | 991 | audio_callback(audio_param, temp_soundbuf, audio_sys->settings.sound_bufsize); |
799 | /* convert xworld format (signed 8-bit) to rockbox format (signed 16-bit) */ | 992 | |
993 | /* convert xworld format (signed 8-bit) to rockbox format (stereo signed 16-bit) */ | ||
800 | for(int i = 0; i < audio_sys->settings.sound_bufsize; ++i) | 994 | for(int i = 0; i < audio_sys->settings.sound_bufsize; ++i) |
801 | { | 995 | { |
802 | rb_soundbuf[i] = temp_soundbuf[i] * 0x100; | 996 | rb_soundbuf[2*i] = rb_soundbuf[2*i+1] = temp_soundbuf[i] * 256; |
803 | } | 997 | } |
804 | *start = rb_soundbuf; | ||
805 | *size = audio_sys->settings.sound_bufsize; | ||
806 | } | 998 | } |
807 | else | 999 | else |
808 | { | 1000 | { |
809 | *start = NULL; | 1001 | rb->memset(rb_soundbuf, 0, audio_sys->settings.sound_bufsize * 2 * sizeof(int16_t)); |
810 | *size = 0; | ||
811 | } | 1002 | } |
1003 | *start = rb_soundbuf; | ||
1004 | *size = audio_sys->settings.sound_bufsize * 2 * sizeof(int16_t); | ||
812 | } | 1005 | } |
813 | 1006 | ||
814 | void sys_startAudio(struct System* sys, AudioCallback callback, void *param) | 1007 | void sys_startAudio(struct System* sys, AudioCallback callback, void *param) |
@@ -817,6 +1010,7 @@ void sys_startAudio(struct System* sys, AudioCallback callback, void *param) | |||
817 | audio_callback = callback; | 1010 | audio_callback = callback; |
818 | audio_param = param; | 1011 | audio_param = param; |
819 | audio_sys = sys; | 1012 | audio_sys = sys; |
1013 | |||
820 | rb->pcm_play_data(get_more, NULL, NULL, 0); | 1014 | rb->pcm_play_data(get_more, NULL, NULL, 0); |
821 | } | 1015 | } |
822 | 1016 | ||
@@ -872,13 +1066,18 @@ void *sys_createMutex(struct System* sys) | |||
872 | { | 1066 | { |
873 | if(!sys) | 1067 | if(!sys) |
874 | error("sys is NULL!"); | 1068 | error("sys is NULL!"); |
1069 | |||
1070 | debug(DBG_SYS, "allocating mutex"); | ||
1071 | |||
1072 | /* this bitfield works as follows: bit set = free, unset = in use */ | ||
875 | for(int i = 0; i < MAX_MUTEXES; ++i) | 1073 | for(int i = 0; i < MAX_MUTEXES; ++i) |
876 | { | 1074 | { |
1075 | /* check that the corresponding bit is 1 (free) */ | ||
877 | if(sys->mutex_bitfield & (1 << i)) | 1076 | if(sys->mutex_bitfield & (1 << i)) |
878 | { | 1077 | { |
879 | rb->mutex_init(&sys->mutex_memory[i]); | 1078 | rb->mutex_init(sys->mutex_memory + i); |
880 | sys->mutex_bitfield |= (1 << i); | 1079 | sys->mutex_bitfield &= ~(1 << i); |
881 | return &sys->mutex_memory[i]; | 1080 | return sys->mutex_memory + i; |
882 | } | 1081 | } |
883 | } | 1082 | } |
884 | warning("Out of mutexes!"); | 1083 | warning("Out of mutexes!"); |
@@ -888,20 +1087,18 @@ void *sys_createMutex(struct System* sys) | |||
888 | void sys_destroyMutex(struct System* sys, void *mutex) | 1087 | void sys_destroyMutex(struct System* sys, void *mutex) |
889 | { | 1088 | { |
890 | int mutex_number = ((char*)mutex - (char*)sys->mutex_memory) / sizeof(struct mutex); /* pointer arithmetic! check for bugs! */ | 1089 | int mutex_number = ((char*)mutex - (char*)sys->mutex_memory) / sizeof(struct mutex); /* pointer arithmetic! check for bugs! */ |
891 | sys->mutex_bitfield &= ~(1 << mutex_number); | 1090 | sys->mutex_bitfield |= 1 << mutex_number; |
892 | } | 1091 | } |
893 | 1092 | ||
894 | void sys_lockMutex(struct System* sys, void *mutex) | 1093 | void sys_lockMutex(struct System* sys, void *mutex) |
895 | { | 1094 | { |
896 | (void) sys; | 1095 | (void) sys; |
897 | debug(DBG_SYS, "calling mutex_lock"); | ||
898 | rb->mutex_lock((struct mutex*) mutex); | 1096 | rb->mutex_lock((struct mutex*) mutex); |
899 | } | 1097 | } |
900 | 1098 | ||
901 | void sys_unlockMutex(struct System* sys, void *mutex) | 1099 | void sys_unlockMutex(struct System* sys, void *mutex) |
902 | { | 1100 | { |
903 | (void) sys; | 1101 | (void) sys; |
904 | debug(DBG_SYS, "calling mutex_unlock"); | ||
905 | rb->mutex_unlock((struct mutex*) mutex); | 1102 | rb->mutex_unlock((struct mutex*) mutex); |
906 | } | 1103 | } |
907 | 1104 | ||
@@ -937,4 +1134,5 @@ void MutexStack(struct MutexStack_t* s, struct System *stub, void *mutex) | |||
937 | void MutexStack_destroy(struct MutexStack_t* s) | 1134 | void MutexStack_destroy(struct MutexStack_t* s) |
938 | { | 1135 | { |
939 | sys_unlockMutex(s->sys, s->_mutex); | 1136 | sys_unlockMutex(s->sys, s->_mutex); |
1137 | |||
940 | } | 1138 | } |