From: notaz Date: Fri, 28 Aug 2009 20:16:33 +0000 (+0000) Subject: sms wip: random tweaks, refactoring (palette, sound stuff, etc) X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ab8a8d36598061ddae8741c6585fbaa3e257c037;p=libpicofe.git sms wip: random tweaks, refactoring (palette, sound stuff, etc) git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@764 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/common/arm_utils.h b/common/arm_utils.h index ae5ae24..8cf34ce 100644 --- a/common/arm_utils.h +++ b/common/arm_utils.h @@ -3,9 +3,9 @@ // For commercial use, separate licencing terms must be obtained. -void vidConvCpyRGB32 (void *to, void *from, int pixels); -void vidConvCpyRGB32sh(void *to, void *from, int pixels); -void vidConvCpyRGB32hi(void *to, void *from, int pixels); +void bgr444_to_rgb32(void *to, void *from); +void bgr444_to_rgb32_sh(void *to, void *from); + void vidcpy_m2(void *dest, void *src, int m32col, int with_32c_border); void vidcpy_m2_rot(void *dest, void *src, int m32col, int with_32c_border); void spend_cycles(int c); // utility diff --git a/common/arm_utils.s b/common/arm_utils.s index b93b99f..fd13cac 100644 --- a/common/arm_utils.s +++ b/common/arm_utils.s @@ -13,7 +13,6 @@ @ to 00000000 rrr00000 ggg00000 bbb00000 ... @ lr = 0x00e000e0, out: r3=lower_pix, r2=higher_pix; trashes rin -@ if sh==2, r8=0x00404040 (sh!=0 destroys flags!) .macro convRGB32_2 rin sh=0 and r2, lr, \rin, lsr #4 @ blue and r3, \rin, lr @@ -59,16 +58,19 @@ .endif orr r2, r2, r2, lsr #3 +.if \sh == 1 + str r2, [r0, #0x40*2*4] +.endif str r2, [r0], #4 .endm -.global vidConvCpyRGB32 @ void *to, void *from, int pixels +.global bgr444_to_rgb32 @ void *to, void *from -vidConvCpyRGB32: +bgr444_to_rgb32: stmfd sp!, {r4-r7,lr} - mov r12, r2, lsr #3 @ repeats + mov r12, #0x40>>3 @ repeats mov lr, #0x00e00000 orr lr, lr, #0x00e0 @@ -80,19 +82,18 @@ vidConvCpyRGB32: convRGB32_2 r5 convRGB32_2 r6 convRGB32_2 r7 - bgt .loopRGB32 - ldmfd sp!, {r4-r7,lr} - bx lr + ldmfd sp!, {r4-r7,pc} -.global vidConvCpyRGB32sh @ void *to, void *from, int pixels +.global bgr444_to_rgb32_sh @ void *to, void *from -vidConvCpyRGB32sh: +bgr444_to_rgb32_sh: stmfd sp!, {r4-r7,lr} - mov r12, r2, lsr #3 @ repeats + mov r12, #0x40>>3 @ repeats + add r0, r0, #0x40*4 mov lr, #0x00e00000 orr lr, lr, #0x00e0 @@ -104,21 +105,10 @@ vidConvCpyRGB32sh: convRGB32_2 r5, 1 convRGB32_2 r6, 1 convRGB32_2 r7, 1 - bgt .loopRGB32sh - ldmfd sp!, {r4-r7,lr} - bx lr - - -.global vidConvCpyRGB32hi @ void *to, void *from, int pixels - -vidConvCpyRGB32hi: - stmfd sp!, {r4-r7,lr} - - mov r12, r2, lsr #3 @ repeats - mov lr, #0x00e00000 - orr lr, lr, #0x00e0 + mov r12, #0x40>>3 @ repeats + sub r1, r1, #0x40*2 .loopRGB32hi: ldmia r1!, {r4-r7} diff --git a/common/emu.c b/common/emu.c index aca54be..4a95a3f 100644 --- a/common/emu.c +++ b/common/emu.c @@ -1332,7 +1332,7 @@ void emu_loop(void) { int pframes_done; /* "period" frames, used for sync */ int frames_done, frames_shown; /* actual frames for fps counter */ - int oldmodes, target_fps, target_frametime; + int target_fps, target_frametime; unsigned int timestamp_base = 0, timestamp_fps; char *notice_msg = NULL; char fpsbuff[24]; @@ -1341,8 +1341,8 @@ void emu_loop(void) fpsbuff[0] = 0; /* make sure we are in correct mode */ - oldmodes = ((Pico.video.reg[12]&1)<<2) ^ 0xc; Pico.m.dirtyPal = 1; + rendstatus_old = -1; /* number of ticks per frame */ if (Pico.m.pal) { @@ -1371,7 +1371,6 @@ void emu_loop(void) { unsigned int timestamp; int diff, diff_lim; - int modes; timestamp = get_ticks(); if (reset_timing) { @@ -1398,13 +1397,6 @@ void emu_loop(void) } } - // check for mode changes - modes = ((Pico.video.reg[12]&1)<<2) | (Pico.video.reg[1]&8); - if (modes != oldmodes) { - oldmodes = modes; - pemu_video_mode_change(!(modes & 4), (modes & 8)); - } - // second changed? if (timestamp - timestamp_fps >= ms_to_ticks(1000)) { diff --git a/common/plat.h b/common/plat.h index a453431..ca847c6 100644 --- a/common/plat.h +++ b/common/plat.h @@ -9,7 +9,6 @@ void pemu_prep_defconfig(void); void pemu_loop_prep(void); void pemu_loop_end(void); void pemu_forced_frame(int opts); -void pemu_video_mode_change(int is_32col, int is_240_lines); void pemu_update_display(const char *fps, const char *notice_msg); void pemu_sound_start(void); diff --git a/gp2x/emu.c b/gp2x/emu.c index dd4b686..77e33f2 100644 --- a/gp2x/emu.c +++ b/gp2x/emu.c @@ -36,7 +36,7 @@ extern int crashed_940; static short __attribute__((aligned(4))) sndBuffer[2*(44100+100)/50]; static unsigned char PicoDraw2FB_[(8+320) * (8+240+8)]; unsigned char *PicoDraw2FB = PicoDraw2FB_; -static int osd_fps_x; +static int osd_fps_x, osd_y; extern void *gp2x_screens[4]; @@ -265,21 +265,66 @@ static int EmuScanEnd8_rot(unsigned int num) return 0; } -int localPal[0x100]; -static void (*vidcpyM2)(void *dest, void *src, int m32col, int with_32c_border) = NULL; +static int localPal[0x100]; +static void (*vidcpyM2)(void *dest, void *src, int m32col, int with_32c_border); +static int (*make_local_pal)(int fast_mode); + +static int make_local_pal_md(int fast_mode) +{ + int pallen = 0xc0; + + bgr444_to_rgb32(localPal, Pico.cram); + if (fast_mode) + return 0x40; + + if (Pico.video.reg[0xC] & 8) { // shadow/hilight mode + bgr444_to_rgb32_sh(localPal, Pico.cram); + localPal[0xc0] = 0x0000c000; + localPal[0xd0] = 0x00c00000; + localPal[0xe0] = 0x00000000; // reserved pixels for OSD + localPal[0xf0] = 0x00ffffff; + pallen = 0x100; + } + else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes + bgr444_to_rgb32(localPal+0x40, HighPal); + bgr444_to_rgb32(localPal+0x80, HighPal+0x40); + } + else + memcpy32(localPal+0x80, localPal, 0x40); // for spr prio mess + + return pallen; +} + +static int make_local_pal_sms(int fast_mode) +{ + unsigned short *spal = Pico.cram; + unsigned int *dpal = (void *)localPal; + unsigned int i, t; + + for (i = 0x40; i > 0; i--) { + t = *spal++; + t = ((t & 0x0003) << 22) | ((t & 0x000c) << 12) | ((t & 0x0030) << 2); + t |= t >> 2; + t |= t >> 4; + *dpal++ = t; + } + + return 0x40; +} void pemu_update_display(const char *fps, const char *notice) { int emu_opt = currentConfig.EmuOpt; + int ret; if (PicoOpt & POPT_ALT_RENDERER) { // 8bit fast renderer if (Pico.m.dirtyPal) { Pico.m.dirtyPal = 0; - vidConvCpyRGB32(localPal, Pico.cram, 0x40); + ret = make_local_pal(1); // feed new palette to our device - gp2x_video_setpalette(localPal, 0x40); + gp2x_video_setpalette(localPal, ret); } // a hack for VR if (PicoRead16Hook == PicoSVPRead16) @@ -293,43 +338,17 @@ void pemu_update_display(const char *fps, const char *notice) // 8bit accurate renderer if (Pico.m.dirtyPal) { - int pallen = 0xc0; Pico.m.dirtyPal = 0; - if (Pico.video.reg[0xC]&8) // shadow/hilight mode - { - vidConvCpyRGB32(localPal, Pico.cram, 0x40); - vidConvCpyRGB32sh(localPal+0x40, Pico.cram, 0x40); - vidConvCpyRGB32hi(localPal+0x80, Pico.cram, 0x40); - memcpy32(localPal+0xc0, localPal+0x40, 0x40); - pallen = 0x100; - } - else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes - vidConvCpyRGB32(localPal, Pico.cram, 0x40); - vidConvCpyRGB32(localPal+0x40, HighPal, 0x40); - vidConvCpyRGB32(localPal+0x80, HighPal+0x40, 0x40); - } - else { - vidConvCpyRGB32(localPal, Pico.cram, 0x40); - memcpy32(localPal+0x80, localPal, 0x40); // for spr prio mess - } - if (pallen > 0xc0) { - localPal[0xc0] = 0x0000c000; - localPal[0xd0] = 0x00c00000; - localPal[0xe0] = 0x00000000; // reserved pixels for OSD - localPal[0xf0] = 0x00ffffff; - } - gp2x_video_setpalette(localPal, pallen); + ret = make_local_pal(0); + gp2x_video_setpalette(localPal, ret); } } if (notice || (emu_opt & 2)) { - int h = 232; - if (currentConfig.scaling == EOPT_SCALE_HW_HV && !(Pico.video.reg[1]&8)) - h -= 8; if (notice) - osd_text(4, h, notice); + osd_text(4, osd_y, notice); if (emu_opt & 2) - osd_text(osd_fps_x, h, fps); + osd_text(osd_fps_x, osd_y, fps); } if ((emu_opt & 0x400) && (PicoAHW & PAHW_MCD)) draw_cd_leds(); @@ -474,6 +493,9 @@ static void vidResetMode(void) if (currentConfig.scaling == EOPT_SCALE_HW_HV && !(Pico.video.reg[1]&8)) gp2x_video_RGB_setscaling(8, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 224); else gp2x_video_RGB_setscaling(0, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 240); + + // palette converters for 8bit modes + make_local_pal = (PicoAHW & PAHW_SMS) ? make_local_pal_sms : make_local_pal_md; } void plat_video_toggle_renderer(int is_next, int is_menu) @@ -498,6 +520,7 @@ void plat_video_toggle_renderer(int is_next, int is_menu) return; vidResetMode(); + rendstatus_old = -1; if (PicoOpt & POPT_ALT_RENDERER) { emu_status_msg(" 8bit fast renderer"); @@ -694,18 +717,21 @@ void plat_debug_cat(char *str) { } -void pemu_video_mode_change(int is_32col, int is_240_lines) +void emu_video_mode_change(int start_line, int line_count, int is_32cols) { int scalex = 320; osd_fps_x = OSD_FPS_X; - if (is_32col && (PicoOpt & POPT_DIS_32C_BORDER)) { + osd_y = 232; + if (is_32cols && (PicoOpt & POPT_DIS_32C_BORDER)) { scalex = 256; osd_fps_x = OSD_FPS_X - 64; } + /* want vertical scaling and game is not in 240 line mode */ - if (currentConfig.scaling == EOPT_SCALE_HW_HV && !is_240_lines) - gp2x_video_RGB_setscaling(8, scalex, 224); - else + if (currentConfig.scaling == EOPT_SCALE_HW_HV) { + gp2x_video_RGB_setscaling(start_line, scalex, line_count); + osd_y = start_line + line_count - 8; + } else gp2x_video_RGB_setscaling(0, scalex, 240); // clear whole screen in all buffers @@ -819,6 +845,7 @@ void pemu_loop_end(void) int eo_old = currentConfig.EmuOpt; pemu_sound_stop(); + memset32(g_screen_ptr, 0, 320*240*2/4); /* do one more frame for menu bg */ PicoOpt &= ~POPT_ALT_RENDERER; diff --git a/linux/blit.c b/linux/blit.c index 7f46623..fbaac03 100644 --- a/linux/blit.c +++ b/linux/blit.c @@ -3,37 +3,36 @@ // to 00000000 rrr00000 ggg00000 bbb00000 ... // TODO: rm when gp2x/emu.c is no longer used -void vidConvCpyRGB32 (void *to, void *from, int pixels) +void bgr444_to_rgb32(void *to, void *from) { unsigned short *ps = from; unsigned int *pd = to; + int pixels; - for (; pixels; pixels--, ps++, pd++) + for (pixels = 0x40; pixels; pixels--, ps++, pd++) { *pd = ((*ps<<20)&0xe00000) | ((*ps<<8)&0xe000) | ((*ps>>4)&0xe0); *pd |= *pd >> 3; } } -void vidConvCpyRGB32sh(void *to, void *from, int pixels) +void bgr444_to_rgb32_sh(void *to, void *from) { unsigned short *ps = from; unsigned int *pd = to; + int pixels; - for (; pixels; pixels--, ps++, pd++) + pd += 0x40; + for (pixels = 0x40; pixels; pixels--, ps++, pd++) { *pd = ((*ps<<20)&0xe00000) | ((*ps<<8)&0xe000) | ((*ps>>4)&0xe0); *pd >>= 1; *pd |= *pd >> 3; + pd[0x40*2] = *pd; } -} - -void vidConvCpyRGB32hi(void *to, void *from, int pixels) -{ - unsigned short *ps = from; - unsigned int *pd = to; - for (; pixels; pixels--, ps++, pd++) + ps -= 0x40; + for (pixels = 0x40; pixels; pixels--, ps++, pd++) { *pd = ((*ps<<20)&0xe00000) | ((*ps<<8)&0xe000) | ((*ps>>4)&0xe0); continue;