From 38a14c7d35e56b6fcfa08d9191e052778ffa305f Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Thu, 3 Nov 2016 22:27:01 -0400 Subject: XWorld: fix sound, hopefully for the last time Change-Id: I8df549c923c5075800c6625c36c8202e53de1d27 --- apps/plugins/xworld/mixer.c | 13 +++--- apps/plugins/xworld/sys.c | 96 ++++++++++++++++++++++++++++++--------------- 2 files changed, 70 insertions(+), 39 deletions(-) (limited to 'apps/plugins') diff --git a/apps/plugins/xworld/mixer.c b/apps/plugins/xworld/mixer.c index de7536c..a09b540 100644 --- a/apps/plugins/xworld/mixer.c +++ b/apps/plugins/xworld/mixer.c @@ -24,7 +24,7 @@ #include "serializer.h" #include "sys.h" -static int8_t ICODE_ATTR addclamp(int a, int b) { +static int8_t addclamp(int a, int b) { int add = a + b; if (add < -128) { add = -128; @@ -121,11 +121,10 @@ void mixer_stopAll(struct Mixer* mx) { /* Since there is no way to know when SDL will ask for a buffer fill, we need */ /* to synchronize with a mutex so the channels remain stable during the execution */ /* of this method. */ -static void ICODE_ATTR mixer_mix(struct Mixer* mx, int8_t *buf, int len) { +static void mixer_mix(struct Mixer* mx, int8_t *buf, int len) { int8_t *pBuf; - struct MutexStack_t ms; - MutexStack(&ms, mx->sys, mx->_mutex); + //sys_lockMutex(mx->sys, mx->_mutex); /* Clear the buffer since nothing guarantees we are receiving clean memory. */ rb->memset(buf, 0, len); @@ -170,11 +169,11 @@ static void ICODE_ATTR mixer_mix(struct Mixer* mx, int8_t *buf, int len) { } - MutexStack_destroy(&ms); + //sys_unlockMutex(mx->sys, mx->_mutex); } -static void ICODE_ATTR mixer_mixCallback(void *param, uint8_t *buf, int len) { - debug(DBG_SND, "mixer_mixCallback"); +static void mixer_mixCallback(void *param, uint8_t *buf, int len) { + //debug(DBG_SND, "mixer_mixCallback"); mixer_mix((struct Mixer*)param, (int8_t *)buf, len); } diff --git a/apps/plugins/xworld/sys.c b/apps/plugins/xworld/sys.c index 03b032c..b571ba0 100644 --- a/apps/plugins/xworld/sys.c +++ b/apps/plugins/xworld/sys.c @@ -130,13 +130,34 @@ static bool sys_do_help(void) rb->lcd_set_background(LCD_BLACK); #endif rb->lcd_setfont(FONT_UI); - char* help_text[] = {"XWorld", "", - "XWorld", "is", "an", "interpreter", "for", "Another", "World,", "a", "fantastic", "game", "by", "Eric", "Chahi." - }; + char *help_text[] = { + "XWorld", "", + "XWorld", "is", "a", "port", "of", "a", "bytecode", "interpreter", "for", "`Another", "World',", "a", "cinematic", "adventure", "game", "by", "Eric", "Chahi.", + "", + "Level", "Codes:", "", + "Level", "1:", "LDKD", "", + "Level", "2:", "HTDC", "", + "Level", "3:", "CLLD", "", + "Level", "4:", "LBKG", "", + "Level", "5:", "XDDJ", "", + "Level", "6:", "FXLC", "", + "Level", "7:", "KRFK", "", + "Level", "8:", "KFLB", "", + "Level", "9:", "DDRX", "", + "Level", "10:", "BFLX", "", + "Level", "11:", "BRTD", "", + "Level", "12:", "TFBB", "", + "Level", "13:", "TXHF", "", + "Level", "14:", "CKJL", "", + "Level", "15:", "LFCK", "", + }; struct style_text style[] = { - {0, TEXT_CENTER | TEXT_UNDERLINE}, - LAST_STYLE_ITEM + { 0, TEXT_CENTER | TEXT_UNDERLINE }, + { 2, C_RED }, + { 23, C_RED }, + { 24, C_RED }, }; + return display_text(ARRAYLEN(help_text), help_text, style, NULL, true); } @@ -149,9 +170,9 @@ static const struct opt_items scaling_settings[3] = { }; static const struct opt_items rotation_settings[3] = { - { "Disabled" , -1 }, - { "Clockwise" , -1 }, - { "Anticlockwise", -1 } + { "Disabled" , -1 }, + { "Clockwise" , -1 }, + { "Counterclockwise", -1 } }; static void do_video_settings(struct System* sys) @@ -219,15 +240,16 @@ static void do_video_settings(struct System* sys) } } -#define MAX_SOUNDBUF_SIZE 512 +#define MAX_SOUNDBUF_SIZE 256 + +/* NOTE: these are intentionally set very low in order to minimize the + * time spent in the IRQ callback. On the ipod6g, going over 512 + * samples results in a panic. */ const struct opt_items sound_bufsize_options[] = { - {"8 samples" , 8}, - {"16 samples" , 16}, - {"32 samples" , 32}, - {"64 samples" , 64}, + {"32 samples", 32}, + {"64 samples", 64}, {"128 samples", 128}, {"256 samples", 256}, - {"512 samples", 512}, }; static void do_sound_settings(struct System* sys) @@ -262,8 +284,8 @@ static void sys_reset_settings(struct System* sys) sys->settings.rotation_option = 0; sys->settings.scaling_quality = 1; sys->settings.sound_enabled = true; - sys->settings.sound_bufsize = 64; - sys->settings.showfps = true; + sys->settings.sound_bufsize = 128; // doom defaults + sys->settings.showfps = false; sys->settings.zoom = false; sys_rotate_keymap(sys); } @@ -278,11 +300,13 @@ static int mainmenu_cb(int action, const struct menu_item_ex *this_item) return action; } -static AudioCallback audio_callback; +static AudioCallback audio_callback = NULL; +static void get_more(const void** start, size_t* size); static void* audio_param; static struct System* audio_sys; /************************************** MAIN MENU ***************************************/ +/* called after game init */ void sys_menu(struct System* sys) { @@ -352,7 +376,7 @@ void sys_menu(struct System* sys) exit(PLUGIN_OK); break; default: - error("sys_menu: fall-through!"); + break; } } rb->lcd_clear_display(); @@ -669,7 +693,8 @@ static void do_pause_menu(struct System* sys) void sys_processEvents(struct System* sys) { - int btn = rb->button_get(false); + int btn = rb->button_status(); + rb->button_clear_queue(); btn &= ~BUTTON_REDRAW; debug(DBG_SYS, "button is 0x%08x", btn); @@ -789,20 +814,21 @@ uint32_t sys_getTimeStamp(struct System* sys) return (uint32_t) (*rb->current_tick * (1000/HZ)); } -static int16_t rb_soundbuf [MAX_SOUNDBUF_SIZE] IBSS_ATTR; -static int8_t temp_soundbuf[MAX_SOUNDBUF_SIZE] IBSS_ATTR; -static void ICODE_ATTR get_more(const void** start, size_t* size) +/* game provides us mono samples, we need stereo */ +static int16_t rb_soundbuf [MAX_SOUNDBUF_SIZE * 2]; +static int8_t temp_soundbuf[MAX_SOUNDBUF_SIZE]; +static void get_more(const void** start, size_t* size) { - if(audio_sys->settings.sound_enabled) + if(audio_sys->settings.sound_enabled && audio_callback) { audio_callback(audio_param, temp_soundbuf, audio_sys->settings.sound_bufsize); /* convert xworld format (signed 8-bit) to rockbox format (signed 16-bit) */ - for(int i = 0; i < audio_sys->settings.sound_bufsize; ++i) + for(int i = 0; i < audio_sys->settings.sound_bufsize; i += 2) { - rb_soundbuf[i] = temp_soundbuf[i] * 0x100; + rb_soundbuf[i] = rb_soundbuf[i+1] = temp_soundbuf[i] * 0x100; } *start = rb_soundbuf; - *size = audio_sys->settings.sound_bufsize; + *size = audio_sys->settings.sound_bufsize * 2; } else { @@ -872,13 +898,18 @@ void *sys_createMutex(struct System* sys) { if(!sys) error("sys is NULL!"); + + debug(DBG_SYS, "allocating mutex"); + + /* this bitfield works as follows: bit set = free, unset = in use */ for(int i = 0; i < MAX_MUTEXES; ++i) { + /* check that the corresponding bit is 1 (free) */ if(sys->mutex_bitfield & (1 << i)) { - rb->mutex_init(&sys->mutex_memory[i]); - sys->mutex_bitfield |= (1 << i); - return &sys->mutex_memory[i]; + rb->mutex_init(sys->mutex_memory + i); + sys->mutex_bitfield &= ~(1 << i); + return sys->mutex_memory + i; } } warning("Out of mutexes!"); @@ -888,20 +919,20 @@ void *sys_createMutex(struct System* sys) void sys_destroyMutex(struct System* sys, void *mutex) { int mutex_number = ((char*)mutex - (char*)sys->mutex_memory) / sizeof(struct mutex); /* pointer arithmetic! check for bugs! */ - sys->mutex_bitfield &= ~(1 << mutex_number); + sys->mutex_bitfield |= 1 << mutex_number; } void sys_lockMutex(struct System* sys, void *mutex) { (void) sys; - debug(DBG_SYS, "calling mutex_lock"); + debug(DBG_SYS, "calling mutex_lock in thread %d", rb->thread_self()); rb->mutex_lock((struct mutex*) mutex); } void sys_unlockMutex(struct System* sys, void *mutex) { (void) sys; - debug(DBG_SYS, "calling mutex_unlock"); + debug(DBG_SYS, "calling mutex_unlock in thread %d", rb->thread_self()); rb->mutex_unlock((struct mutex*) mutex); } @@ -937,4 +968,5 @@ void MutexStack(struct MutexStack_t* s, struct System *stub, void *mutex) void MutexStack_destroy(struct MutexStack_t* s) { sys_unlockMutex(s->sys, s->_mutex); + } -- cgit v1.1 From 1498b7ae6e37df6a03f5125e7cb7bf1a0b6ad9a5 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Fri, 4 Nov 2016 22:43:31 -0400 Subject: rewrite input handling from doom Change-Id: If42885177e30d8664429ad47820f230bb52cdcfa --- apps/plugins/xworld/sys.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) (limited to 'apps/plugins') diff --git a/apps/plugins/xworld/sys.c b/apps/plugins/xworld/sys.c index b571ba0..a136be1 100644 --- a/apps/plugins/xworld/sys.c +++ b/apps/plugins/xworld/sys.c @@ -696,10 +696,13 @@ void sys_processEvents(struct System* sys) int btn = rb->button_status(); rb->button_clear_queue(); btn &= ~BUTTON_REDRAW; + + static int oldbuttonstate = 0; + debug(DBG_SYS, "button is 0x%08x", btn); /* exit early if we can */ - if(btn == BUTTON_NONE) + if(btn == BUTTON_NONE && btn == oldbuttonstate) { return; } @@ -711,10 +714,12 @@ void sys_processEvents(struct System* sys) if(btn & 0x80000000) return; #endif + #if (CONFIG_KEYPAD == SANSA_E200_PAD) if(btn == (BUTTON_SCROLL_FWD || BUTTON_SCROLL_BACK)) return; #endif + #if (CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD) if(btn == (BUTTON_SELECT)) return; @@ -734,6 +739,72 @@ void sys_processEvents(struct System* sys) break; } + /* copied from doom which was copied from rockboy... */ + unsigned released = ~btn & oldbuttonstate; + unsigned pressed = btn & ~oldbuttonstate; + oldbuttonstate = newbuttonstate; + + if(released) + { + if(btn & BTN_FIRE) + sys->input.button = false; + if(btn & sys->keymap.up) + sys->input.dirMask &= ~DIR_UP; + if(btn & sys->keymap.down) + sys->input.dirMask &= ~DIR_DOWN; + if(btn & sys->keymap.left) + sys->input.dirMask &= ~DIR_LEFT; + if(btn & sys->keymap.right) + sys->input.dirMask &= ~DIR_RIGHT; +#ifdef BTN_DOWN_LEFT + if(btn & sys->keymap.downleft) + sys->input.dirMask &= ~(DIR_DOWN | DIR_LEFT); +#endif +#ifdef BTN_DOWN_RIGHT + if(btn & sys->keymap.downright) + sys->input.dirMask &= ~(DIR_DOWN | DIR_RIGHT); +#endif +#ifdef BTN_UP_LEFT + if(btn & sys->keymap.upleft) + sys->input.dirMask &= ~(DIR_UP | DIR_LEFT); +#endif +#ifdef BTN_UP_RIGHT + if(btn & sys->keymap.upright) + sys->input.dirMask &= ~(DIR_UP | DIR_RIGHT); +#endif + } + + if(pressed) + { + if(btn & BTN_FIRE) + sys->input.button = true; + if(btn & sys->keymap.up) + sys->input.dirMask |= DIR_UP; + if(btn & sys->keymap.down) + sys->input.dirMask |= DIR_DOWN; + if(btn & sys->keymap.left) + sys->input.dirMask |= DIR_LEFT; + if(btn & sys->keymap.right) + sys->input.dirMask |= DIR_RIGHT; +#ifdef BTN_DOWN_LEFT + if(btn & sys->keymap.downleft) + sys->input.dirMask |= (DIR_DOWN | DIR_LEFT); +#endif +#ifdef BTN_DOWN_RIGHT + if(btn & sys->keymap.downright) + sys->input.dirMask |= (DIR_DOWN | DIR_RIGHT); +#endif +#ifdef BTN_UP_LEFT + if(btn & sys->keymap.upleft) + sys->input.dirMask |= (DIR_UP | DIR_LEFT); +#endif +#ifdef BTN_UP_RIGHT + if(btn & sys->keymap.upright) + sys->input.dirMask |= (DIR_UP | DIR_RIGHT); +#endif + } + +#if 0 /* handle releases */ if(btn & BUTTON_REL) { @@ -799,6 +870,7 @@ void sys_processEvents(struct System* sys) } debug(DBG_SYS, "dirMask is 0x%02x", sys->input.dirMask); debug(DBG_SYS, "button is %s", sys->input.button == true ? "true" : "false"); +#endif } void sys_sleep(struct System* sys, uint32_t duration) -- cgit v1.1