From 78c45530fff6100240d08be77858350632000de9 Mon Sep 17 00:00:00 2001 From: Karl Kurbjun Date: Sun, 24 Jun 2007 16:00:55 +0000 Subject: Sound improvements for rockboy - players now sync the sound (The gigabeat now plays at a steady 60 fps as long as the frameskip is set properly). If a new sample is not available a blank buffer is used. All devices use 44.1 kHz for gameboy sound now so no more high pitched sounds. Added a screen rotation option. Removed unscaled code for devices with a screensize smaller than the gameboy. All buttons are now configurable. Scroll wheel devices still have button configuration problems though. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13698 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/rockboy/emu.c | 16 +++- apps/plugins/rockboy/lcd.c | 154 ++++++++++++++++++++++--------------- apps/plugins/rockboy/menu.c | 66 +++++++++------- apps/plugins/rockboy/pcm.h | 2 +- apps/plugins/rockboy/rbsound.c | 64 ++++----------- apps/plugins/rockboy/rockboy.c | 146 +++++++++++++++++++++-------------- apps/plugins/rockboy/rockmacros.h | 5 +- apps/plugins/rockboy/sound.c | 129 +++++++++++++++++++------------ apps/plugins/rockboy/sound.h | 1 + apps/plugins/rockboy/sys_rockbox.c | 43 +++-------- 10 files changed, 345 insertions(+), 281 deletions(-) (limited to 'apps') diff --git a/apps/plugins/rockboy/emu.c b/apps/plugins/rockboy/emu.c index 7f24bde01e..02e5fa0b1c 100644 --- a/apps/plugins/rockboy/emu.c +++ b/apps/plugins/rockboy/emu.c @@ -35,7 +35,7 @@ void emu_run(void) /*void *timer = sys_timer();*/ int framesin=0,frames=0,timeten=*rb->current_tick, timehun=*rb->current_tick; - setvidmode(options.fullscreen); + setvidmode(); vid_begin(); lcd_begin(); #ifdef HAVE_ADJUSTABLE_CPU_FREQ @@ -49,9 +49,19 @@ void emu_run(void) emu_step(); rtc_tick(); /* RTC support not implemented */ - - if(options.sound || !plugbuf) + + if (options.sound || !plugbuf) + { sound_mix(); + pcm_submit(); + } + else + { +/* delay = framelen - sys_elapsed(timer); + sys_sleep(delay); + sys_elapsed(timer); +*/ + } doevents(); vid_begin(); diff --git a/apps/plugins/rockboy/lcd.c b/apps/plugins/rockboy/lcd.c index 7fe531041c..bf44ccf136 100644 --- a/apps/plugins/rockboy/lcd.c +++ b/apps/plugins/rockboy/lcd.c @@ -833,40 +833,67 @@ void spr_scan(void) #define DY ((LCD_HEIGHT<<16) / 144) #define DYI ((144<<16) / LCD_HEIGHT) +#define DXR ((LCD_WIDTH<<16) / 144) +#define DXIR ((144<<16) / LCD_WIDTH) +#define DYR ((LCD_HEIGHT<<16) / 160) +#define DYIR ((160<<16) / LCD_HEIGHT) + void lcd_begin(void) { #if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144) #define S1 ((LCD_HEIGHT-144)/2)*LCD_WIDTH + ((LCD_WIDTH-160)/2) #define S2 0 +#define S1R ((LCD_HEIGHT-160)/2)*LCD_WIDTH + ((LCD_WIDTH-144)/2)+144 +#define S2R (LCD_WIDTH-1) #elif (LCD_WIDTH>=160) && (LCD_HEIGHT<=144) -#define S1 ((LCD_WIDTH-160)/2) -#define S2 ((LCD_WIDTH-160)/2) +#define S1 0 +#define S2 0 +#define S1R LCD_WIDTH-1 +#define S2R LCD_WIDTH-1 #elif (LCD_WIDTH<=160) && (LCD_HEIGHT>=144) #define S1 ((LCD_HEIGHT-144)/2)*LCD_WIDTH #define S2 ((LCD_HEIGHT-144)/2)*LCD_WIDTH +#define S1R LCD_WIDTH-1 +#define S2R LCD_WIDTH-1 #else #define S1 0 #define S2 0 +#define S1R LCD_WIDTH-1 +#define S2R LCD_WIDTH-1 #endif #if (LCD_WIDTH>LCD_HEIGHT) -#define S3 ((LCD_WIDTH-(160*LCD_HEIGHT/144))/2) +#define S3 ((LCD_WIDTH-((160*DY)>>16))/2) +#define S3R LCD_WIDTH-1 #else -#define S3 ((LCD_HEIGHT-(144*LCD_WIDTH/160))/2)*LCD_WIDTH +#define S3 ((LCD_HEIGHT-((144*DX)>>16))/2)*LCD_WIDTH +#define S3R ((LCD_HEIGHT-((160*DXR)>>16))/2)*LCD_WIDTH+LCD_WIDTH-1 #endif - + set_pal(); - if(options.fullscreen == 0) - vdest=fb.ptr+S1; - else if (options.fullscreen == 1) - vdest=fb.ptr+S2; + if(options.rotate) + { + if(options.fullscreen == 0) + vdest=fb.ptr+S2R; + else if (options.fullscreen == 1) + vdest=fb.ptr+S3R; + else + vdest=fb.ptr+S1R; + } else - vdest=fb.ptr+S3; + { + if(options.fullscreen == 0) + vdest=fb.ptr+S2; + else if (options.fullscreen == 1) + vdest=fb.ptr+S3; + else + vdest=fb.ptr+S1; + } WY = R_WY; } @@ -874,50 +901,63 @@ int SCALEWL IDATA_ATTR=1<<16; int SCALEWS IDATA_ATTR=1<<16; int SCALEHL IDATA_ATTR=1<<16; int SCALEHS IDATA_ATTR=1<<16; -int swidth IDATA_ATTR=160; +int swidth IDATA_ATTR=160; int sremain IDATA_ATTR=LCD_WIDTH-160; -void setvidmode(int mode) +void setvidmode(void) { - switch(mode) + switch(options.fullscreen) { - case 1: -#if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144) /* Full screen scale */ - SCALEWL=DX; - SCALEWS=DXI; - SCALEHL=DY; - SCALEHS=DYI; -#elif (LCD_WIDTH>=160) && (LCD_HEIGHT<144) /* scale the height */ - SCALEWL=1<<16; - SCALEWS=1<<16; - SCALEHL=DY; - SCALEHS=DYI; -#elif (LCD_WIDTH<160) && (LCD_HEIGHT>=144) /* scale the width */ - SCALEWL=DX; - SCALEWS=DXI; - SCALEHL=1<<16; - SCALEHS=1<<16; -#else - SCALEWL=DX; - SCALEWS=DXI; - SCALEHL=DY; - SCALEHS=DYI; -#endif - break; - case 2: /* Maintain Ratio */ - if (DY>16; - sremain=LCD_WIDTH-swidth; + + if(options.rotate) + sremain=-(((160*SCALEWL)>>16)*LCD_WIDTH+1); + else + sremain=LCD_WIDTH-swidth; } void lcd_refreshline(void) @@ -1015,24 +1059,14 @@ void lcd_refreshline(void) register unsigned int remain=sremain; while(wcount--) { -#if LCD_HEIGHT<144 /* cut off the bottom part of the screen that won't fit */ - if (options.fullscreen==0 && (hpt>>16)>LCD_HEIGHT) - break; -#endif + *vdest = PAL[BUF[srcpt>>16]]; + if (options.rotate) + vdest+=LCD_WIDTH; + else + vdest++; -#if LCD_WIDTH<160 /* cut off the right part of the screen that won't fit */ - if(options.fullscreen==0 && wcount<(160-LCD_WIDTH)) { - vdest+=wcount; - wcount = 0; - } -#endif - - *vdest++ = PAL[BUF[srcpt>>16]]; srcpt+=SCALEWS; } -#if LCD_HEIGHT<144 - if (options.fullscreen!=0 || (hpt>>16)<(LCD_HEIGHT)) -#endif vdest+=remain; } diff --git a/apps/plugins/rockboy/menu.c b/apps/plugins/rockboy/menu.c index ca15cba7b9..e358bafbb9 100644 --- a/apps/plugins/rockboy/menu.c +++ b/apps/plugins/rockboy/menu.c @@ -38,11 +38,14 @@ static void munge_name(char *buf, size_t bufsiz); int getbutton(char *text) { - rb->lcd_putsxy(0, 0, text); + int fw, fh; + rb->lcd_clear_display(); + rb->font_getstringsize(text, &fw, &fh,0); + rb->lcd_putsxy(LCD_WIDTH/2-fw/2, LCD_HEIGHT/2-fh/2, text); rb->lcd_update(); rb->sleep(30); - while (rb->button_get(false) != BUTTON_NONE) + while (rb->button_get(false) != BUTTON_NONE) rb->yield(); int button; @@ -51,31 +54,24 @@ int getbutton(char *text) button = rb->button_get(true); button=button&0x00000FFF; - switch(button) - { - case MENU_BUTTON_LEFT: - case MENU_BUTTON_RIGHT: - case MENU_BUTTON_UP: - case MENU_BUTTON_DOWN: - break; - default: - return button; - break; - } + return button; } } void setupkeys(void) { - options.A=getbutton("Press A"); + options.UP=getbutton ("Press Up"); + options.DOWN=getbutton ("Press Down"); + options.LEFT=getbutton ("Press Left"); + options.RIGHT=getbutton ("Press Right"); - options.B=getbutton("Press B"); - - options.START=getbutton("Press Start"); + options.A=getbutton ("Press A"); + options.B=getbutton ("Press B"); + options.START=getbutton ("Press Start"); options.SELECT=getbutton("Press Select"); - options.MENU=getbutton("Press Menu"); + options.MENU=getbutton ("Press Menu"); } /* @@ -330,12 +326,17 @@ static void do_opt_menu(void) }; static const struct opt_items fullscreen[]= { - { "Unscaled", -1 }, { "Scaled", -1 }, { "Scaled - Maintain Ratio", -1 }, +#if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144) + { "Unscaled", -1 }, +#endif }; static const struct opt_items frameskip[]= { + { "0 Max", -1 }, + { "1 Max", -1 }, + { "2 Max", -1 }, { "3 Max", -1 }, { "4 Max", -1 }, { "5 Max", -1 }, @@ -368,7 +369,8 @@ static void do_opt_menu(void) { "Max Frameskip", NULL }, { "Sound" , NULL }, { "Stats" , NULL }, - { "Screen Options" , NULL }, + { "Screen Size" , NULL }, + { "Screen Rotate" , NULL }, { "Set Keys (Buggy)", NULL }, #ifdef HAVE_LCD_COLOR { "Set Palette" , NULL }, @@ -377,6 +379,8 @@ static void do_opt_menu(void) m = menu_init(rb,items, sizeof(items) / sizeof(*items), NULL, NULL, NULL, NULL); + options.dirty=1; /* Just assume that the settings have been changed */ + while(!done) { @@ -385,9 +389,8 @@ static void do_opt_menu(void) switch (result) { case 0: /* Frameskip */ - options.maxskip-=3; - rb->set_option(items[0].desc, &options.maxskip, INT, frameskip, 4, NULL ); - options.maxskip+=3; + rb->set_option(items[0].desc, &options.maxskip, INT, frameskip, + sizeof(frameskip)/sizeof(*frameskip), NULL ); break; case 1: /* Sound */ if(options.sound>1) options.sound=1; @@ -397,16 +400,21 @@ static void do_opt_menu(void) case 2: /* Stats */ rb->set_option(items[2].desc, &options.showstats, INT, onoff, 2, NULL ); break; - case 3: /* Fullscreen */ - rb->set_option(items[3].desc, &options.fullscreen, INT, fullscreen, 3, NULL ); - setvidmode(options.fullscreen); + case 3: /* Screen Size */ + rb->set_option(items[3].desc, &options.fullscreen, INT, fullscreen, + sizeof(fullscreen)/sizeof(*fullscreen), NULL ); + setvidmode(); + break; + case 4: /* Screen rotate */ + rb->set_option(items[4].desc, &options.rotate, INT, onoff, 2, NULL ); + setvidmode(); break; - case 4: /* Keys */ + case 5: /* Keys */ setupkeys(); break; #ifdef HAVE_LCD_COLOR - case 5: /* Palette */ - rb->set_option(items[5].desc, &options.pal, INT, palette, 17, NULL ); + case 6: /* Palette */ + rb->set_option(items[6].desc, &options.pal, INT, palette, 17, NULL ); set_pal(); break; #endif diff --git a/apps/plugins/rockboy/pcm.h b/apps/plugins/rockboy/pcm.h index a616ce9897..f009f5708c 100644 --- a/apps/plugins/rockboy/pcm.h +++ b/apps/plugins/rockboy/pcm.h @@ -9,7 +9,7 @@ struct pcm { int hz, len; int stereo; - byte *buf; + short *buf; int pos; }; diff --git a/apps/plugins/rockboy/rbsound.c b/apps/plugins/rockboy/rbsound.c index e671554e25..163c39aa66 100644 --- a/apps/plugins/rockboy/rbsound.c +++ b/apps/plugins/rockboy/rbsound.c @@ -5,21 +5,20 @@ struct pcm pcm IBSS_ATTR; #define N_BUFS 2 -#define BUF_SIZE 1024 - -#if CONFIG_CODEC == SWCODEC && !defined(SIMULATOR) +#define BUF_SIZE 2048 bool doneplay=1; +bool bufnum=0; -static unsigned char *buf=0; -static unsigned short *gmbuf; +static unsigned short *buf=0; static bool newly_started; void get_more(unsigned char** start, size_t* size) { - *start = (unsigned char*)(&gmbuf[pcm.len*doneplay]); + *start = (unsigned char*)(&buf[pcm.len*doneplay]); *size = BUF_SIZE*sizeof(short); + doneplay=1; } void pcm_init(void) @@ -29,19 +28,17 @@ void pcm_init(void) newly_started = true; - pcm.hz = 11025; + pcm.hz = SAMPR_44; pcm.stereo = 1; pcm.len = BUF_SIZE; if(!buf) { - buf = my_malloc(pcm.len * N_BUFS); - gmbuf = my_malloc(pcm.len * N_BUFS*sizeof (short)); + buf = my_malloc(pcm.len * N_BUFS *sizeof(short)); pcm.buf = buf; pcm.pos = 0; - memset(gmbuf, 0, pcm.len * N_BUFS *sizeof(short)); - memset(buf, 0, pcm.len * N_BUFS); + memset(buf, 0, pcm.len * N_BUFS*sizeof(short)); } rb->pcm_play_stop(); @@ -52,7 +49,7 @@ void pcm_init(void) rb->audio_set_output_source(AUDIO_SRC_PLAYBACK); #endif - rb->pcm_set_frequency(SAMPR_11); /* 44100 22050 11025 */ + rb->pcm_set_frequency(pcm.hz); /* 44100 22050 11025 */ } void pcm_close(void) @@ -65,50 +62,21 @@ void pcm_close(void) int pcm_submit(void) { - register int i; - + if (!pcm.buf) return 0; if (pcm.pos < pcm.len) return 1; - doneplay=!doneplay; - - if(doneplay) - pcm.buf = buf + pcm.len; - else - pcm.buf = buf; - - pcm.pos = 0; - - /* gotta convert the 8 bit buffer to 16 */ - for(i=0; ipcm_play_data(&get_more,NULL,0); newly_started = false; } - return 1; -} -#else -static byte buf1_unal[(BUF_SIZE / sizeof(short)) + 2]; /* 4 byte aligned */ -void pcm_init(void) -{ - pcm.hz = 11025; - pcm.stereo = 1; - pcm.buf = buf1_unal; - pcm.len = (BUF_SIZE / sizeof(short)); - pcm.pos = 0; -} + while (!doneplay) + {rb->yield();} -void pcm_close(void) -{ - memset(&pcm, 0, sizeof pcm); -} -int pcm_submit(void) -{ - pcm.pos =0; - return 0; + doneplay=0; + + pcm.pos = 0; + return 1; } -#endif diff --git a/apps/plugins/rockboy/rockboy.c b/apps/plugins/rockboy/rockboy.c index 6c99a3db18..46a0aa56c3 100644 --- a/apps/plugins/rockboy/rockboy.c +++ b/apps/plugins/rockboy/rockboy.c @@ -79,70 +79,101 @@ void setoptions (void) snprintf(optionsave, sizeof(optionsave), "%s/%s", savedir, optionname); - fd = open(optionsave, O_RDONLY); - if(fd < 0) /* no options to read, set defaults */ - { + fd = open(optionsave, O_RDONLY); + if(fd < 0) /* no options to read, set defaults */ + { + options.LEFT=BUTTON_LEFT; + options.RIGHT=BUTTON_RIGHT; + #if (CONFIG_KEYPAD == IRIVER_H100_PAD) - options.A=BUTTON_ON; - options.B=BUTTON_OFF; - options.START=BUTTON_REC; - options.SELECT=BUTTON_SELECT; - options.MENU=BUTTON_MODE; + options.UP=BUTTON_UP; + options.DOWN=BUTTON_DOWN; + + options.A=BUTTON_ON; + options.B=BUTTON_OFF; + options.START=BUTTON_REC; + options.SELECT=BUTTON_SELECT; + options.MENU=BUTTON_MODE; #elif (CONFIG_KEYPAD == IRIVER_H300_PAD) - options.A=BUTTON_REC; - options.B=BUTTON_MODE; - options.START=BUTTON_ON; - options.SELECT=BUTTON_SELECT; - options.MENU=BUTTON_OFF; + options.UP=BUTTON_UP; + options.DOWN=BUTTON_DOWN; + + options.A=BUTTON_REC; + options.B=BUTTON_MODE; + options.START=BUTTON_ON; + options.SELECT=BUTTON_SELECT; + options.MENU=BUTTON_OFF; #elif CONFIG_KEYPAD == RECORDER_PAD - options.A=BUTTON_F1; - options.B=BUTTON_F2; - options.START=BUTTON_F3; - options.SELECT=BUTTON_PLAY; - options.MENU=BUTTON_OFF; + options.UP=BUTTON_UP; + options.DOWN=BUTTON_DOWN; + + options.A=BUTTON_F1; + options.B=BUTTON_F2; + options.START=BUTTON_F3; + options.SELECT=BUTTON_PLAY; + options.MENU=BUTTON_OFF; #elif CONFIG_KEYPAD == IPOD_4G_PAD - options.A=BUTTON_NONE; - options.B=BUTTON_NONE; - options.START=BUTTON_SELECT; - options.SELECT=BUTTON_NONE; - options.MENU=(BUTTON_SELECT | BUTTON_REPEAT); + options.UP=BUTTON_MENU; + options.DOWN=BUTTON_PLAY; + + options.A=BUTTON_NONE; + options.B=BUTTON_NONE; + options.START=BUTTON_SELECT; + options.SELECT=BUTTON_NONE; + options.MENU=(BUTTON_SELECT | BUTTON_REPEAT); #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD - options.A=BUTTON_PLAY; - options.B=BUTTON_EQ; - options.START=BUTTON_MODE; - options.SELECT=(BUTTON_SELECT | BUTTON_REL); - options.MENU=(BUTTON_SELECT | BUTTON_REPEAT); + options.UP=BUTTON_UP; + options.DOWN=BUTTON_DOWN; + + options.A=BUTTON_PLAY; + options.B=BUTTON_EQ; + options.START=BUTTON_MODE; + options.SELECT=(BUTTON_SELECT | BUTTON_REL); + options.MENU=(BUTTON_SELECT | BUTTON_REPEAT); #elif CONFIG_KEYPAD == GIGABEAT_PAD - options.A=BUTTON_VOL_UP; - options.B=BUTTON_VOL_DOWN; - options.START=BUTTON_A; - options.SELECT=BUTTON_SELECT; - options.MENU=BUTTON_MENU; + options.UP=BUTTON_UP; + options.DOWN=BUTTON_DOWN; + + options.A=BUTTON_VOL_UP; + options.B=BUTTON_VOL_DOWN; + options.START=BUTTON_A; + options.SELECT=BUTTON_SELECT; + options.MENU=BUTTON_MENU; #elif CONFIG_KEYPAD == SANSA_E200_PAD - options.A=BUTTON_SELECT; - options.B=BUTTON_REC; - options.START=BUTTON_SCROLL_UP; - options.SELECT=BUTTON_SCROLL_DOWN; - options.MENU=BUTTON_POWER; + options.UP=BUTTON_UP; + options.DOWN=BUTTON_DOWN; + + options.A=BUTTON_SELECT; + options.B=BUTTON_REC; + options.START=BUTTON_SCROLL_UP; + options.SELECT=BUTTON_SCROLL_DOWN; + options.MENU=BUTTON_POWER; + #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD - options.A=BUTTON_PLAY; - options.B=BUTTON_REC; - options.START=BUTTON_SELECT; - options.SELECT=BUTTON_NONE; - options.MENU=BUTTON_POWER; + options.UP=BUTTON_UP; + options.DOWN=BUTTON_DOWN; + + options.A=BUTTON_PLAY; + options.B=BUTTON_REC; + options.START=BUTTON_SELECT; + options.SELECT=BUTTON_NONE; + options.MENU=BUTTON_POWER; #elif CONFIG_KEYPAD == IRIVER_H10_PAD - options.A=BUTTON_PLAY; - options.B=BUTTON_FF; - options.START=BUTTON_REW; - options.SELECT=BUTTON_NONE; - options.MENU=BUTTON_POWER; + options.UP=BUTTON_SCROLL_UP; + options.DOWN=BUTTON_SCROLL_DOWN; + + options.A=BUTTON_PLAY; + options.B=BUTTON_FF; + options.START=BUTTON_REW; + options.SELECT=BUTTON_NONE; + options.MENU=BUTTON_POWER; #endif options.maxskip=4; @@ -164,13 +195,17 @@ void setoptions (void) void savesettings(void) { - int fd; - char optionsave[sizeof(savedir)+sizeof(optionname)]; + int fd; + char optionsave[sizeof(savedir)+sizeof(optionname)]; - snprintf(optionsave, sizeof(optionsave), "%s/%s", savedir, optionname); - fd = open(optionsave, O_WRONLY|O_CREAT|O_TRUNC); - write(fd,&options, sizeof(options)); - close(fd); + if(options.dirty) + { + options.dirty=0; + snprintf(optionsave, sizeof(optionsave), "%s/%s", savedir, optionname); + fd = open(optionsave, O_WRONLY|O_CREAT|O_TRUNC); + write(fd,&options, sizeof(options)); + close(fd); + } } /* this is the plugin entry point */ @@ -231,12 +266,11 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) } if(!rb->audio_status()) pcm_close(); - rb->splash(HZ/2, "Shutting down"); + rb->splash(HZ/2, "Closing Rockboy"); savesettings(); cleanup(); - return PLUGIN_OK; } diff --git a/apps/plugins/rockboy/rockmacros.h b/apps/plugins/rockboy/rockmacros.h index d302fd04fe..ecf8a1ef6a 100644 --- a/apps/plugins/rockboy/rockmacros.h +++ b/apps/plugins/rockboy/rockmacros.h @@ -41,7 +41,7 @@ void ev_poll(void); int do_user_menu(void); void loadstate(int fd); void savestate(int fd); -void setvidmode(int mode); +void setvidmode(void); void set_pal(void); #if !defined(HAVE_LCD_COLOR) void vid_update(int scanline); @@ -116,9 +116,12 @@ void* memcpy(void* dst, const void* src, size_t size) ICODE_ATTR; struct options { int A, B, START, SELECT, MENU; + int UP, DOWN, LEFT, RIGHT; int frameskip, fps, maxskip; int sound, fullscreen, showstats; + int rotate; int pal; + int dirty; }; bool plugbuf; diff --git a/apps/plugins/rockboy/sound.c b/apps/plugins/rockboy/sound.c index 516b9c3f71..aba7f924b4 100644 --- a/apps/plugins/rockboy/sound.c +++ b/apps/plugins/rockboy/sound.c @@ -7,26 +7,41 @@ #include "regs.h" #include "noise.h" +static const byte dmgwave[16] = +{ + 0xac, 0xdd, 0xda, 0x48, + 0x36, 0x02, 0xcf, 0x16, + 0x2c, 0x04, 0xe5, 0x2c, + 0xac, 0xdd, 0xda, 0x48 +}; + +static const byte cgbwave[16] = +{ + 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, +}; static const byte sqwave[4][8] = - { - { 0, 0,-1, 0, 0, 0, 0, 0 }, - { 0,-1,-1, 0, 0, 0, 0, 0 }, - { 0,-1,-1,-1,-1, 0, 0, 0 }, - { -1, 0, 0,-1,-1,-1,-1,-1 } - }; +{ + { 0, 0,-1, 0, 0, 0, 0, 0 }, + { 0,-1,-1, 0, 0, 0, 0, 0 }, + { -1,-1,-1,-1, 0, 0, 0, 0 }, + { -1, 0, 0,-1,-1,-1,-1,-1 } +}; static const int freqtab[8] = - { - (1<<18)*2, - (1<<18), - (1<<18)/2, - (1<<18)/3, - (1<<18)/4, - (1<<18)/5, - (1<<18)/6, - (1<<18)/7 - }; +{ + (1<<14)*2, + (1<<14), + (1<<14)/2, + (1<<14)/3, + (1<<14)/4, + (1<<14)/5, + (1<<14)/6, + (1<<14)/7 +}; struct snd snd IBSS_ATTR; @@ -58,13 +73,14 @@ static void s2_freq(void) static void s3_freq(void) { int d = 2048 - (((R_NR34&7)<<8) + R_NR33); - if (RATE > d) S3.freq = 0; + if (RATE > (d<<3)) S3.freq = 0; else S3.freq = (RATE << 21)/d; } static void s4_freq(void) { S4.freq = (freqtab[R_NR43&7] >> (R_NR43 >> 4)) * RATE; + if (S4.freq >> 18) S4.freq = 1<<18; } void sound_dirty(void) @@ -74,13 +90,13 @@ void sound_dirty(void) S1.envol = R_NR12 >> 4; S1.endir = (R_NR12>>3) & 1; S1.endir |= S1.endir - 1; - S1.enlen = (R_NR12 & 3) << 15; + S1.enlen = (R_NR12 & 7) << 15; s1_freq(); S2.len = (64-(R_NR21&63)) << 13; S2.envol = R_NR22 >> 4; S2.endir = (R_NR22>>3) & 1; S2.endir |= S2.endir - 1; - S2.enlen = (R_NR22 & 3) << 15; + S2.enlen = (R_NR22 & 7) << 15; s2_freq(); S3.len = (256-R_NR31) << 20; s3_freq(); @@ -88,13 +104,12 @@ void sound_dirty(void) S4.envol = R_NR42 >> 4; S4.endir = (R_NR42>>3) & 1; S4.endir |= S4.endir - 1; - S4.enlen = (R_NR42 & 3) << 15; + S4.enlen = (R_NR42 & 7) << 15; s4_freq(); } -void sound_reset(void) +void sound_off(void) { - int i; memset(&snd, 0, sizeof snd); if (pcm.hz) snd.rate = (1<<21) / pcm.hz; else snd.rate = 0; @@ -115,11 +130,22 @@ void sound_reset(void) R_NR44 = 0xBF; R_NR50 = 0x77; R_NR51 = 0xF3; - R_NR52 = 0xF1; - for (i = 0; i < 16; i++) WAVE[i] = -(i&1); + R_NR52 = 0x70; +// for (i = 0; i < 16; i++) WAVE[i] = -(i&1); sound_dirty(); } +void sound_reset() +{ + memset(&snd, 0, sizeof snd); + if (pcm.hz) snd.rate = (1<<21) / pcm.hz; + else snd.rate = 0; + memcpy(WAVE, hw.cgb ? cgbwave : dmgwave, 16); + memcpy(ram.hi+0x30, WAVE, 16); + sound_off(); + R_NR52 = 0xF1; +} + void sound_mix(void) { int s, l, r, f, n; @@ -145,7 +171,8 @@ void sound_mix(void) } if (S1.swlen && (S1.swcnt += RATE) >= S1.swlen) { - f = ((R_NR14 & 7) << 8) + R_NR13; + S1.swcnt -= S1.swlen; + f = S1.swfreq; n = (R_NR10 & 7); if (R_NR10 & 8) f -= (f >> n); else f += (f >> n); @@ -153,14 +180,15 @@ void sound_mix(void) S1.on = 0; else { + S1.swfreq = f; R_NR13 = f; R_NR14 = (R_NR14 & 0xF8) | (f>>8); s1_freq_d(2048 - f); } } s <<= 2; - if (R_NR51 & 1) l += s; - if (R_NR51 & 16) r += s; + if (R_NR51 & 1) r += s; + if (R_NR51 & 16) l += s; } if (S2.on) @@ -177,8 +205,8 @@ void sound_mix(void) if (S2.envol > 15) S2.envol = 15; } s <<= 2; - if (R_NR51 & 2) l += s; - if (R_NR51 & 32) r += s; + if (R_NR51 & 2) r += s; + if (R_NR51 & 32) l += s; } if (S3.on) @@ -192,16 +220,16 @@ void sound_mix(void) S3.on = 0; if (R_NR32 & 96) s <<= (3 - ((R_NR32>>5)&3)); else s = 0; - if (R_NR51 & 4) l += s; - if (R_NR51 & 64) r += s; + if (R_NR51 & 4) r += s; + if (R_NR51 & 64) l += s; } if (S4.on) { if (R_NR43 & 8) s = 1 & (noise7[ - (S4.pos>>24)&15] >> ((S4.pos>>21)&7)); + (S4.pos>>20)&15] >> (7-((S4.pos>>17)&7))); else s = 1 & (noise15[ - (S4.pos>>24)&4095] >> ((S4.pos>>21)&7)); + (S4.pos>>20)&4095] >> (7-((S4.pos>>17)&7))); s = (-s) & S4.envol; S4.pos += S4.freq; if ((R_NR44 & 64) && ((S4.cnt += RATE) >= S4.len)) @@ -213,9 +241,9 @@ void sound_mix(void) if (S4.envol < 0) S4.envol = 0; if (S4.envol > 15) S4.envol = 15; } - s <<= 2; - if (R_NR51 & 8) l += s; - if (R_NR51 & 128) r += s; + s += s << 1; + if (R_NR51 & 8) r += s; + if (R_NR51 & 128) l += s; } l *= (R_NR50 & 0x07); @@ -234,10 +262,10 @@ void sound_mix(void) pcm_submit(); if (pcm.stereo) { - pcm.buf[pcm.pos++] = l+128; - pcm.buf[pcm.pos++] = r+128; + pcm.buf[pcm.pos++] = ((signed char)(l))<<7; + pcm.buf[pcm.pos++] = ((signed char)(r))<<7; } - else pcm.buf[pcm.pos++] = ((l+r)>>1)+128; + else pcm.buf[pcm.pos++] = ((signed char)((l+r)>>1))<<7; } } R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3); @@ -256,12 +284,13 @@ byte sound_read(byte r) void s1_init(void) { S1.swcnt = 0; + S1.swfreq = ((R_NR14&7)<<8) + R_NR13; S1.envol = R_NR12 >> 4; S1.endir = (R_NR12>>3) & 1; S1.endir |= S1.endir - 1; S1.enlen = (R_NR12 & 7) << 15; + if (!S1.on) S1.pos = 0; S1.on = 1; - S1.pos = 0; S1.cnt = 0; S1.encnt = 0; } @@ -272,17 +301,20 @@ void s2_init(void) S2.endir = (R_NR22>>3) & 1; S2.endir |= S2.endir - 1; S2.enlen = (R_NR22 & 7) << 15; + if (!S2.on) S2.pos = 0; S2.on = 1; - S2.pos = 0; S2.cnt = 0; S2.encnt = 0; } void s3_init(void) { - S3.pos = 0; + int i; + if (!S3.on) S3.pos = 0; S3.cnt = 0; S3.on = R_NR30 >> 7; + if (S3.on) for (i = 0; i < 16; i++) + ram.hi[i+0x30] = 0x13 ^ ram.hi[i+0x31]; } void s4_init(void) @@ -306,7 +338,8 @@ void sound_write(byte r, byte b) if ((r & 0xF0) == 0x30) { if (S3.on) sound_mix(); - if (!S3.on) WAVE[r - 0x30] = b; + if (!S3.on) + WAVE[r-0x30] = ram.hi[r] = b; return; } sound_mix(); @@ -314,6 +347,8 @@ void sound_write(byte r, byte b) { case RI_NR10: R_NR10 = b; + S1.swlen = ((R_NR10>>4) & 7) << 14; + S1.swfreq = ((R_NR14&7)<<8) + R_NR13; break; case RI_NR11: R_NR11 = b; @@ -361,7 +396,7 @@ void sound_write(byte r, byte b) break; case RI_NR31: R_NR31 = b; - S3.len = (256-R_NR31) << 20; + S3.len = (256-R_NR31) << 13; break; case RI_NR32: R_NR32 = b; @@ -403,13 +438,9 @@ void sound_write(byte r, byte b) case RI_NR52: R_NR52 = b; if (!(R_NR52 & 128)) - sound_reset(); + sound_off(); break; default: return; } } - - - - diff --git a/apps/plugins/rockboy/sound.h b/apps/plugins/rockboy/sound.h index fe3557cd7e..88897ef9ce 100644 --- a/apps/plugins/rockboy/sound.h +++ b/apps/plugins/rockboy/sound.h @@ -9,6 +9,7 @@ struct sndchan unsigned pos; int cnt, encnt, swcnt; int len, enlen, swlen; + int swfreq; int freq; int envol, endir; }; diff --git a/apps/plugins/rockboy/sys_rockbox.c b/apps/plugins/rockboy/sys_rockbox.c index 6cbbe523f7..60cac0a88d 100644 --- a/apps/plugins/rockboy/sys_rockbox.c +++ b/apps/plugins/rockboy/sys_rockbox.c @@ -24,36 +24,11 @@ #include "hw.h" #include "config.h" -#if (CONFIG_KEYPAD == IPOD_4G_PAD) - -#define ROCKBOY_PAD_LEFT BUTTON_LEFT -#define ROCKBOY_PAD_RIGHT BUTTON_RIGHT -#define ROCKBOY_PAD_UP BUTTON_MENU -#define ROCKBOY_PAD_DOWN BUTTON_PLAY - -#elif (CONFIG_KEYPAD == IRIVER_H10_PAD) - -#define ROCKBOY_PAD_LEFT BUTTON_LEFT -#define ROCKBOY_PAD_RIGHT BUTTON_RIGHT -#define ROCKBOY_PAD_UP BUTTON_SCROLL_UP -#define ROCKBOY_PAD_DOWN BUTTON_SCROLL_DOWN - -#elif (CONFIG_KEYPAD == SANSA_E200_PAD) +#if (CONFIG_KEYPAD == SANSA_E200_PAD) #define ROCKBOY_SCROLLWHEEL #define ROCKBOY_SCROLLWHEEL_CC BUTTON_SCROLL_UP #define ROCKBOY_SCROLLWHEEL_CW BUTTON_SCROLL_DOWN -#define ROCKBOY_PAD_LEFT BUTTON_LEFT -#define ROCKBOY_PAD_RIGHT BUTTON_RIGHT -#define ROCKBOY_PAD_UP BUTTON_UP -#define ROCKBOY_PAD_DOWN BUTTON_DOWN - -#else - -#define ROCKBOY_PAD_LEFT BUTTON_LEFT -#define ROCKBOY_PAD_RIGHT BUTTON_RIGHT -#define ROCKBOY_PAD_UP BUTTON_UP -#define ROCKBOY_PAD_DOWN BUTTON_DOWN #endif @@ -159,10 +134,10 @@ void ev_poll(void) #else if(released) { ev.type = EV_RELEASE; - if(released & ROCKBOY_PAD_LEFT) { ev.code=PAD_LEFT; ev_postevent(&ev); } - if(released & ROCKBOY_PAD_RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);} - if(released & ROCKBOY_PAD_DOWN) { ev.code=PAD_DOWN; ev_postevent(&ev); } - if(released & ROCKBOY_PAD_UP) { ev.code=PAD_UP; ev_postevent(&ev); } + if(released & options.LEFT) { ev.code=PAD_LEFT; ev_postevent(&ev); } + if(released & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);} + if(released & options.DOWN) { ev.code=PAD_DOWN; ev_postevent(&ev); } + if(released & options.UP) { ev.code=PAD_UP; ev_postevent(&ev); } if(released & options.A) { ev.code=PAD_A; ev_postevent(&ev); } if(released & options.B) { ev.code=PAD_B; ev_postevent(&ev); } if(released & options.START) { @@ -176,10 +151,10 @@ void ev_poll(void) } if(pressed) { /* button press */ ev.type = EV_PRESS; - if(pressed & ROCKBOY_PAD_LEFT) { ev.code=PAD_LEFT; ev_postevent(&ev); } - if(pressed & ROCKBOY_PAD_RIGHT) { ev.code=PAD_RIGHT; ev_postevent(&ev);} - if(pressed & ROCKBOY_PAD_DOWN) { ev.code=PAD_DOWN; ev_postevent(&ev); } - if(pressed & ROCKBOY_PAD_UP) { ev.code=PAD_UP; ev_postevent(&ev); } + if(pressed & options.LEFT) { ev.code=PAD_LEFT; ev_postevent(&ev); } + if(pressed & options.RIGHT) { ev.code=PAD_RIGHT; ev_postevent(&ev);} + if(pressed & options.DOWN) { ev.code=PAD_DOWN; ev_postevent(&ev); } + if(pressed & options.UP) { ev.code=PAD_UP; ev_postevent(&ev); } if(pressed & options.A) { ev.code=PAD_A; ev_postevent(&ev); } if(pressed & options.B) { ev.code=PAD_B; ev_postevent(&ev); } if(pressed & options.START) { -- cgit v1.2.3