From: notaz Date: Wed, 15 Sep 2010 13:48:55 +0000 (+0000) Subject: supporting caanoo, line doublers, refactoring X-Git-Tag: v1.85~164 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4750ee051b509a17bb940d6372a0c12faae18cd;p=picodrive.git supporting caanoo, line doublers, refactoring git-svn-id: file:///home/notaz/opt/svn/PicoDrive@893 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/pico/draw.c b/pico/draw.c index 3442d8f7..0dd682c4 100644 --- a/pico/draw.c +++ b/pico/draw.c @@ -1590,3 +1590,19 @@ void PicoDrawSetInternalBuf(void *dest, int increment) } } +void PicoDrawSetCallbacks(int (*begin)(unsigned int num), int (*end)(unsigned int num)) +{ + PicoScanBegin = NULL; + PicoScanEnd = NULL; + PicoScan32xBegin = NULL; + PicoScan32xEnd = NULL; + + if ((PicoAHW & PAHW_32X) && FinalizeLine != FinalizeLine32xRGB555) { + PicoScan32xBegin = begin; + PicoScan32xEnd = end; + } + else { + PicoScanBegin = begin; + PicoScanEnd = end; + } +} diff --git a/pico/draw_arm.s b/pico/draw_arm.s index 82bb603d..ae6de760 100644 --- a/pico/draw_arm.s +++ b/pico/draw_arm.s @@ -1638,7 +1638,7 @@ vidConvCpyRGB565: @ void *to, void *from, int pixels stmfd sp!, {r4-r9,lr} mov r8, #0x0061 orr r8, r8, #0x0800 - orr r8, r8, lsl #16 + orr r8, r8, r8, lsl #16 vidConvCpyRGB565_local ldmfd sp!, {r4-r9,lr} bx lr @@ -1663,7 +1663,7 @@ PicoDoHighPal555_nopush: mov r2, #0x40 mov r8, #0x0061 orr r8, r8, #0x0800 - orr r8, r8, lsl #16 + orr r8, r8, r8, lsl #16 vidConvCpyRGB565_local diff --git a/pico/pico.h b/pico/pico.h index b8f1c3f8..e0acda10 100644 --- a/pico/pico.h +++ b/pico/pico.h @@ -170,10 +170,9 @@ typedef enum } pdso_t; void PicoDrawSetOutFormat(pdso_t which, int allow_32x); void PicoDrawSetOutBuf(void *dest, int increment); +void PicoDrawSetCallbacks(int (*begin)(unsigned int num), int (*end)(unsigned int num)); extern void *DrawLineDest; extern unsigned char *HighCol; -extern int (*PicoScanBegin)(unsigned int num); -extern int (*PicoScanEnd)(unsigned int num); // utility #ifdef _ASM_DRAW_C void vidConvCpyRGB565(void *to, void *from, int pixels); @@ -219,8 +218,6 @@ extern int p32x_ssh2_multiplier; // 32x/draw.c void PicoDraw32xSetFrameMode(int is_on, int only_32x); -extern int (*PicoScan32xBegin)(unsigned int num); -extern int (*PicoScan32xEnd)(unsigned int num); // sound.c extern int PsndRate,PsndLen; diff --git a/pico/pico_int.h b/pico/pico_int.h index dcd321ac..aaf2f502 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -540,6 +540,8 @@ PICO_INTERNAL void PicoFrameStart(void); void PicoDrawSync(int to, int blank_last_line); void BackFill(int reg7, int sh); void FinalizeLine555(int sh, int line); +extern int (*PicoScanBegin)(unsigned int num); +extern int (*PicoScanEnd)(unsigned int num); extern int DrawScanline; #define MAX_LINE_SPRITES 29 extern unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES]; @@ -727,6 +729,8 @@ void p32x_poll_event(int cpu_mask, int is_vdp); void FinalizeLine32xRGB555(int sh, int line); void PicoDraw32xLayer(int offs, int lines, int mdbg); void PicoDraw32xLayerMdOnly(int offs, int lines); +extern int (*PicoScan32xBegin)(unsigned int num); +extern int (*PicoScan32xEnd)(unsigned int num); enum { PDM32X_OFF, PDM32X_32X_ONLY, diff --git a/platform/common/emu.h b/platform/common/emu.h index 90803a64..27864bec 100644 --- a/platform/common/emu.h +++ b/platform/common/emu.h @@ -43,9 +43,8 @@ extern int g_screen_height; enum { EOPT_SCALE_NONE = 0, - EOPT_SCALE_SW_H, - EOPT_SCALE_HW_H, - EOPT_SCALE_HW_HV, + EOPT_SCALE_SW, + EOPT_SCALE_HW, }; enum { @@ -67,7 +66,8 @@ typedef struct _currentConfig_t { int CPUclock; int volume; int gamma; - int scaling; // gp2x: 0=center, 1=hscale, 2=hvscale, 3=hsoftscale; psp: bilinear filtering + int scaling; // gp2x: EOPT_SCALE_*; psp: bilinear filtering + int vscaling; int rotation; // for UIQ float scale; // psp: screen scale float hscale32, hscale40; // psp: horizontal scale diff --git a/platform/common/menu.c b/platform/common/menu.c index 35ab449c..4ee5c197 100644 --- a/platform/common/menu.c +++ b/platform/common/menu.c @@ -1606,7 +1606,7 @@ static int menu_loop_32x_options(menu_id id, int keys) { static int sel = 0; - me_enable(e_menu_32x_options, MA_32XOPT_RENDERER, renderer_names32x != NULL); + me_enable(e_menu_32x_options, MA_32XOPT_RENDERER, renderer_names32x[0] != NULL); me_loop(e_menu_32x_options, &sel, NULL); return 0; @@ -1834,7 +1834,7 @@ static menu_entry e_menu_options[] = mee_onoff ("Enable sound", MA_OPT_ENABLE_SOUND, currentConfig.EmuOpt, EOPT_EN_SOUND), mee_cust ("Sound Quality", MA_OPT_SOUND_QUALITY, mh_opt_misc, mgn_opt_sound), mee_enum_h ("Confirm savestate", MA_OPT_CONFIRM_STATES,currentConfig.confirm_save, men_confirm_save, h_confirm_save), - mee_range (cpu_clk_name, MA_OPT_CPU_CLOCKS, currentConfig.CPUclock, 20, 900), + mee_range ("", MA_OPT_CPU_CLOCKS, currentConfig.CPUclock, 20, 900), mee_handler ("[Display options]", menu_loop_gfx_options), mee_handler ("[Sega/Mega CD options]", menu_loop_cd_options), #ifndef NO_32X @@ -1851,7 +1851,10 @@ static menu_entry e_menu_options[] = static int menu_loop_options(menu_id id, int keys) { static int sel = 0; + int i; + i = me_id2offset(e_menu_options, MA_OPT_CPU_CLOCKS); + e_menu_options[i].enabled = e_menu_options[i].name ? 1 : 0; me_enable(e_menu_options, MA_OPT_SAVECFG_GAME, rom_loaded); me_enable(e_menu_options, MA_OPT_LOADCFG, config_slot != config_slot_current); @@ -2191,28 +2194,6 @@ void me_update_msg(const char *msg) // ------------ util ------------ -/* GP2X/wiz for now, probably extend later */ -void menu_plat_setup(int is_wiz) -{ - int i; - - if (!is_wiz) { - me_enable(e_menu_gfx_options, MA_OPT_TEARING_FIX, 0); - i = me_id2offset(e_menu_gfx_options, MA_OPT_TEARING_FIX); - e_menu_gfx_options[i].need_to_save = 0; - return; - } - - me_enable(e_menu_adv_options, MA_OPT_ARM940_SOUND, 0); - me_enable(e_menu_gfx_options, MA_OPT2_GAMMA, 0); - me_enable(e_menu_gfx_options, MA_OPT2_A_SN_GAMMA, 0); - - i = me_id2offset(e_menu_gfx_options, MA_OPT_SCALING); - e_menu_gfx_options[i].max = 1; /* only off and sw */ - i = me_id2offset(e_menu_gfx_options, MA_OPT_ARM940_SOUND); - e_menu_gfx_options[i].need_to_save = 0; -} - /* hidden options for config engine only */ static menu_entry e_menu_hidden[] = { diff --git a/platform/common/menu.h b/platform/common/menu.h index 64a70a74..fd807533 100644 --- a/platform/common/menu.h +++ b/platform/common/menu.h @@ -27,6 +27,7 @@ typedef enum MA_MAIN_EXIT, MA_OPT_RENDERER, MA_OPT_SCALING, + MA_OPT_VSCALING, MA_OPT_ACC_SPRITES, MA_OPT_SHOW_FPS, MA_OPT_FRAMESKIP, @@ -195,7 +196,6 @@ extern int g_menuscreen_h; #endif void menu_init(void); -void menu_plat_setup(int is_wiz); void text_out16(int x, int y, const char *texto, ...); void me_update_msg(const char *msg); diff --git a/platform/common/plat.h b/platform/common/plat.h index bc48e83a..eadc2a89 100644 --- a/platform/common/plat.h +++ b/platform/common/plat.h @@ -3,7 +3,6 @@ extern "C" { #endif /* stuff to be implemented by platform code */ -extern char cpu_clk_name[]; extern const char *renderer_names[]; extern const char *renderer_names32x[]; diff --git a/platform/gizmondo/emu.c b/platform/gizmondo/emu.c index 86a5d8c6..c0211e6e 100644 --- a/platform/gizmondo/emu.c +++ b/platform/gizmondo/emu.c @@ -231,10 +231,10 @@ static void vidResetMode(void) if (PicoOpt&0x10) { } else if (currentConfig.EmuOpt&0x80) { PicoDrawSetOutFormat(PDF_RGB555, 0); - PicoScanBegin = EmuScanBegin16; + PicoDrawSetCallbacks(EmuScanBegin16, NULL); } else { PicoDrawSetOutFormat(PDF_NONE, 0); - PicoScanBegin = EmuScanBegin8; + PicoDrawSetCallbacks(EmuScanBegin8, NULL); } if ((PicoOpt&0x10) || !(currentConfig.EmuOpt&0x80)) { // setup pal for 8-bit modes @@ -307,7 +307,7 @@ void pemu_forced_frame(int opts, int no_scale) giz_screen = fb_lock(1); PicoDrawSetOutFormat(PDF_RGB555, 0); - PicoScanBegin = EmuScanBegin16; + PicoDrawSetCallbacks(EmuScanBegin16, NULL); Pico.m.dirtyPal = 1; PicoFrameDrawOnly(); diff --git a/platform/gp2x/PicoDrive.gpe b/platform/gp2x/PicoDrive.gpe index e5c4914f..1c065185 100644 --- a/platform/gp2x/PicoDrive.gpe +++ b/platform/gp2x/PicoDrive.gpe @@ -2,9 +2,12 @@ export LD_PRELOAD= -export POLLUX_RAM_TIMINGS='ram_timings=2,9,4,1,1,1,1' -export POLLUX_LCD_TIMINGS_NTSC='lcd_timings=397,1,37,277,341,0,17,337;clkdiv0=9' -export POLLUX_LCD_TIMINGS_PAL='lcd_timings=428,1,37,277,341,0,17,337;clkdiv0=10' +if ! [ -e /dev/accel ]; then + # Wiz + export POLLUX_RAM_TIMINGS='ram_timings=2,9,4,1,1,1,1' + export POLLUX_LCD_TIMINGS_NTSC='lcd_timings=397,1,37,277,341,0,17,337;clkdiv0=9' + export POLLUX_LCD_TIMINGS_PAL='lcd_timings=428,1,37,277,341,0,17,337;clkdiv0=10' +fi ./PicoDrive "$@" diff --git a/platform/gp2x/emu.c b/platform/gp2x/emu.c index b019c3b0..75200763 100644 --- a/platform/gp2x/emu.c +++ b/platform/gp2x/emu.c @@ -43,28 +43,15 @@ 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, osd_y; +static int osd_fps_x, osd_y, doing_bg_frame; const char *renderer_names[] = { "16bit accurate", " 8bit accurate", " 8bit fast", NULL }; const char *renderer_names32x[] = { "accurate", "faster", "fastest", NULL }; enum renderer_types { RT_16BIT, RT_8BIT_ACC, RT_8BIT_FAST, RT_COUNT }; -extern void *gp2x_screens[4]; - +static int (*emu_scan_begin)(unsigned int num) = NULL; +static int (*emu_scan_end)(unsigned int num) = NULL; -static void scaling_update(void) -{ - PicoOpt &= ~(POPT_DIS_32C_BORDER|POPT_EN_SOFTSCALE); - switch (currentConfig.scaling) { - default:break; - case EOPT_SCALE_HW_H: - case EOPT_SCALE_HW_HV: - PicoOpt |= POPT_DIS_32C_BORDER; - break; - case EOPT_SCALE_SW_H: - PicoOpt |= POPT_EN_SOFTSCALE; - break; - } -} +extern void *gp2x_screens[4]; void pemu_prep_defconfig(void) @@ -83,12 +70,9 @@ void pemu_prep_defconfig(void) void pemu_validate_config(void) { - gp2x_soc_t soc; - - soc = soc_detect(); - if (soc != SOCID_MMSP2) + if (gp2x_dev_id != GP2X_DEV_GP2X) PicoOpt &= ~POPT_EXT_FM; - if (soc != SOCID_POLLUX) + if (gp2x_dev_id != GP2X_DEV_WIZ) currentConfig.EmuOpt &= ~EOPT_WIZ_TEAR_FIX; if (currentConfig.gamma < 10 || currentConfig.gamma > 300) @@ -114,6 +98,11 @@ static void change_renderer(int diff) else r = ¤tConfig.renderer; *r += diff; + + // 8bpp fast is not there (yet?) + if ((PicoAHW & PAHW_SMS) && *r == RT_8BIT_FAST) + (*r)++; + if (*r >= RT_COUNT) *r = 0; else if (*r < 0) @@ -277,6 +266,46 @@ static int EmuScanEnd8_rot(unsigned int num) return 0; } +/* line doublers */ +static unsigned int ld_counter; +static int ld_left, ld_lines; + +static int EmuScanBegin16_ld(unsigned int num) +{ + if ((signed int)(ld_counter - num) > 100) + ld_counter = 0; + + if (emu_scan_begin) + return emu_scan_begin(ld_counter); + else + DrawLineDest = (char *)g_screen_ptr + 320 * ld_counter * gp2x_current_bpp / 8; + + return 0; +} + +static int EmuScanEnd16_ld(unsigned int num) +{ + void *oldline = DrawLineDest; + + if (emu_scan_end) + emu_scan_end(ld_counter); + + ld_counter++; + ld_left--; + if (ld_left <= 0) { + ld_left = ld_lines; + + EmuScanBegin16_ld(num); + memcpy32(DrawLineDest, oldline, 320 * gp2x_current_bpp / 8 / 4); + if (emu_scan_end) + emu_scan_end(ld_counter); + + ld_counter++; + } + + return 0; +} + 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); @@ -358,12 +387,10 @@ void pemu_finalize_frame(const char *fps, const char *notice) } } - if (notice || (emu_opt & EOPT_SHOW_FPS)) { - if (notice) - osd_text(4, osd_y, notice); - if (emu_opt & 2) - osd_text(osd_fps_x, osd_y, fps); - } + if (notice) + osd_text(4, osd_y, notice); + if (emu_opt & EOPT_SHOW_FPS) + osd_text(osd_fps_x, osd_y, fps); if ((PicoAHW & PAHW_MCD) && (emu_opt & EOPT_EN_CD_LEDS)) draw_cd_leds(); if (PicoAHW & PAHW_PICO) @@ -458,77 +485,73 @@ void plat_status_msg_busy_first(const char *msg) plat_status_msg_busy_next(msg); } -static void vidResetMode(void) +static void vid_reset_mode(void) { int gp2x_mode = 16; int renderer = get_renderer(); - PicoScanBegin = NULL; - PicoScanEnd = NULL; + PicoOpt &= ~POPT_ALT_RENDERER; + emu_scan_begin = NULL; + emu_scan_end = NULL; switch (renderer) { case RT_16BIT: - PicoOpt &= ~POPT_ALT_RENDERER; PicoDrawSetOutFormat(PDF_RGB555, 0); PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2); - if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) { - PicoScanBegin = EmuScanBegin16_rot; - PicoScanEnd = EmuScanEnd16_rot; - } break; case RT_8BIT_ACC: - PicoOpt &= ~POPT_ALT_RENDERER; PicoDrawSetOutFormat(PDF_8BIT, 0); PicoDrawSetOutBuf(g_screen_ptr, g_screen_width); - if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) { - PicoScanBegin = EmuScanBegin8_rot; - PicoScanEnd = EmuScanEnd8_rot; - } gp2x_mode = 8; break; case RT_8BIT_FAST: - PicoOpt |= POPT_ALT_RENDERER; + PicoOpt |= POPT_ALT_RENDERER; PicoDrawSetOutFormat(PDF_NONE, 0); - if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) - vidcpyM2 = vidcpy_m2_rot; - else - vidcpyM2 = vidcpy_m2; + vidcpyM2 = vidcpy_m2; gp2x_mode = 8; break; + default: + printf("bad renderer\n"); + break; } - if (is_16bit_mode()) - osd_text = (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) ? osd_text16_rot : osd_text16; - else - osd_text = (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) ? osd_text8_rot : osd_text8; - if (PicoAHW & PAHW_32X) { - // rules change in 32X world - if (renderer != RT_16BIT) { - PicoDrawSetOutFormat(PDF_NONE, 0); - PicoScanBegin = NULL; - PicoScanEnd = NULL; - } - PicoScan32xBegin = NULL; - PicoScan32xEnd = NULL; - if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) { - PicoScan32xBegin = EmuScanBegin16_rot; - PicoScan32xEnd = EmuScanEnd16_rot; - } // Wiz 16bit is an exception, uses line rendering due to rotation mess if (renderer == RT_16BIT && (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)) { PicoDrawSetOutFormat(PDF_RGB555, 1); PicoDraw32xSetFrameMode(0, 0); } else { + PicoDrawSetOutFormat(PDF_NONE, 0); PicoDraw32xSetFrameMode(1, (renderer == RT_16BIT) ? 1 : 0); } PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2); - gp2x_mode = 16; } + if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) { + if ((PicoAHW & PAHW_32X) || renderer == RT_16BIT) { + emu_scan_begin = EmuScanBegin16_rot; + emu_scan_end = EmuScanEnd16_rot; + } + else if (renderer == RT_8BIT_ACC) { + emu_scan_begin = EmuScanBegin8_rot; + emu_scan_end = EmuScanEnd8_rot; + } + else if (renderer == RT_8BIT_FAST) + vidcpyM2 = vidcpy_m2_rot; + } + + PicoDrawSetCallbacks(emu_scan_begin, emu_scan_end); + + if (is_16bit_mode()) + osd_text = (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) ? osd_text16_rot : osd_text16; + else + osd_text = (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) ? osd_text8_rot : osd_text8; + if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) gp2x_mode = -gp2x_mode; + + gp2x_video_wait_vsync(); gp2x_video_changemode(gp2x_mode); if (!is_16bit_mode()) { @@ -539,19 +562,60 @@ static void vidResetMode(void) localPal[0xf0] = 0x00ffffff; gp2x_video_setpalette(localPal, 0x100); gp2x_memset_all_buffers(0, 0xe0, 320*240); - gp2x_video_flip(); } + else + gp2x_memset_all_buffers(0, 0, 320*240*2); + Pico.m.dirtyPal = 1; - // reset scaling - 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); + PicoOpt &= ~POPT_EN_SOFTSCALE; + if (currentConfig.scaling == EOPT_SCALE_SW) + PicoOpt |= POPT_EN_SOFTSCALE; // palette converters for 8bit modes make_local_pal = (PicoAHW & PAHW_SMS) ? make_local_pal_sms : make_local_pal_md; } +void emu_video_mode_change(int start_line, int line_count, int is_32cols) +{ + int scalex = 320, scaley = 240; + int ln_offs = 0; + + if (doing_bg_frame) + return; + + osd_fps_x = OSD_FPS_X; + osd_y = 232; + + /* set up hwscaling here */ + PicoOpt &= ~POPT_DIS_32C_BORDER; + if (is_32cols && currentConfig.scaling == EOPT_SCALE_HW) { + scalex = 256; + PicoOpt |= POPT_DIS_32C_BORDER; + osd_fps_x = OSD_FPS_X - 64; + } + + if (currentConfig.vscaling == EOPT_SCALE_HW) { + ln_offs = start_line; + scaley = line_count; + osd_y = start_line + line_count - 8; + } + + gp2x_video_RGB_setscaling(ln_offs, scalex, scaley); + + /* line doubling */ + if (currentConfig.vscaling == EOPT_SCALE_SW && line_count < 240) { + ld_lines = ld_left = line_count / (240 - line_count); + PicoDrawSetCallbacks(EmuScanBegin16_ld, EmuScanEnd16_ld); + } + + // clear whole screen in all buffers + if (!is_16bit_mode()) + gp2x_memset_all_buffers(0, 0xe0, 320*240); + else + gp2x_memset_all_buffers(0, 0, 320*240*2); +} + void plat_video_toggle_renderer(int change, int is_menu_call) { change_renderer(change); @@ -559,7 +623,7 @@ void plat_video_toggle_renderer(int change, int is_menu_call) if (is_menu_call) return; - vidResetMode(); + vid_reset_mode(); rendstatus_old = -1; if (PicoAHW & PAHW_32X) @@ -730,22 +794,29 @@ void pemu_sound_wait(void) // don't need to do anything, writes will block by themselves } - void pemu_forced_frame(int opts, int no_scale) { int po_old = PicoOpt; + doing_bg_frame = 1; PicoOpt &= ~POPT_ALT_RENDERER; PicoOpt |= opts|POPT_ACC_SPRITES; + memset32(g_screen_ptr, 0, g_screen_width * g_screen_height * 2 / 4); + PicoDrawSetOutFormat(PDF_RGB555, 1); PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2); PicoDraw32xSetFrameMode(0, 0); - PicoScanBegin = NULL; - PicoScanEnd = NULL; + PicoDrawSetCallbacks(NULL, NULL); Pico.m.dirtyPal = 1; - PicoFrameDrawOnly(); + if (no_scale == -9) + // yes I'm lazy, see pemu_forced_frame call below + PicoFrame(); + else + PicoFrameDrawOnly(); + + doing_bg_frame = 0; PicoOpt = po_old; } @@ -753,30 +824,6 @@ void plat_debug_cat(char *str) { } -void emu_video_mode_change(int start_line, int line_count, int is_32cols) -{ - int scalex = 320; - osd_fps_x = OSD_FPS_X; - 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) { - 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 - if (!is_16bit_mode()) - gp2x_memset_all_buffers(0, 0xe0, 320*240); - else - gp2x_memset_all_buffers(0, 0, 320*240*2); -} - #if 0 static void tga_dump(void) { @@ -842,7 +889,7 @@ void pemu_loop_prep(void) if (gp2x_old_clock < 0) gp2x_old_clock = default_cpu_clock; - if (gp2x_old_clock != currentConfig.CPUclock) { + if (gp2x_old_clock != currentConfig.CPUclock && gp2x_set_cpuclk != NULL) { printf("changing clock to %i...", currentConfig.CPUclock); fflush(stdout); gp2x_set_cpuclk(currentConfig.CPUclock); gp2x_old_clock = currentConfig.CPUclock; @@ -869,8 +916,8 @@ void pemu_loop_prep(void) pal_old = Pico.m.pal; // make sure we are in correct mode - vidResetMode(); - scaling_update(); + change_renderer(0); + vid_reset_mode(); // dirty buffers better go now than during gameplay sync(); @@ -881,26 +928,11 @@ void pemu_loop_prep(void) void pemu_loop_end(void) { - int po_old = PicoOpt; - 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; - PicoOpt |= POPT_EN_SOFTSCALE|POPT_ACC_SPRITES; - - PicoDrawSetOutFormat(PDF_RGB555, 1); - PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2); - PicoDraw32xSetFrameMode(0, 0); - PicoScanBegin = NULL; - PicoScanEnd = NULL; - Pico.m.dirtyPal = 1; - PicoFrame(); - - PicoOpt = po_old; - currentConfig.EmuOpt = eo_old; + pemu_forced_frame(POPT_EN_SOFTSCALE, -9); + g_menubg_src_ptr = g_screen_ptr; } const char *plat_get_credits(void) diff --git a/platform/gp2x/in_gp2x.c b/platform/gp2x/in_gp2x.c index eb97a7e9..9894669c 100644 --- a/platform/gp2x/in_gp2x.c +++ b/platform/gp2x/in_gp2x.c @@ -8,7 +8,7 @@ #include "../common/input.h" #include "in_gp2x.h" -#include "soc.h" +#include "plat_gp2x.h" #define IN_PREFIX "gp2x:" #define IN_GP2X_NBUTTONS 32 @@ -92,15 +92,12 @@ static int in_gp2x_get_fake_bits(void) static void in_gp2x_probe(void) { - gp2x_soc_t soc; - - soc = soc_detect(); - switch (soc) + switch (gp2x_dev_id) { - case SOCID_MMSP2: + case GP2X_DEV_GP2X: in_gp2x_get_bits = in_gp2x_get_mmsp2_bits; break; - case SOCID_POLLUX: + case GP2X_DEV_WIZ: gpiodev = open("/dev/GPIO", O_RDONLY); if (gpiodev < 0) { perror("in_gp2x: couldn't open /dev/GPIO"); @@ -320,10 +317,8 @@ static int in_gp2x_clean_binds(void *drv_data, int *binds, int *def_binds) void in_gp2x_init(void *vdrv) { in_drv_t *drv = vdrv; - gp2x_soc_t soc; - soc = soc_detect(); - if (soc == SOCID_POLLUX) + if (gp2x_dev_id == GP2X_DEV_WIZ) in_gp2x_keys[BTN_START] = "MENU"; in_gp2x_combo_keys = in_gp2x_combo_acts = 0; diff --git a/platform/gp2x/menu.c b/platform/gp2x/menu.c index 9dbabe46..9e53b253 100644 --- a/platform/gp2x/menu.c +++ b/platform/gp2x/menu.c @@ -1,5 +1,6 @@ #include #include "soc.h" +#include "plat_gp2x.h" static void menu_main_plat_draw(void) { @@ -60,10 +61,11 @@ static const char *mgn_aopt_gamma(menu_id id, int *offs) } -const char *men_scaling_opts[] = { "OFF", "sw horizontal", "hw horizontal", "hw horiz. + vert", NULL }; +const char *men_scaling_opts[] = { "OFF", "software", "hardware", NULL }; #define MENU_OPTIONS_GFX \ - mee_enum ("Scaling", MA_OPT_SCALING, currentConfig.scaling, men_scaling_opts), \ + mee_enum ("Horizontal scaling", MA_OPT_SCALING, currentConfig.scaling, men_scaling_opts), \ + mee_enum ("Vertical scaling", MA_OPT_VSCALING, currentConfig.vscaling, men_scaling_opts), \ mee_onoff ("Tearing Fix", MA_OPT_TEARING_FIX, currentConfig.EmuOpt, EOPT_WIZ_TEAR_FIX), \ mee_range_cust("Gamma correction", MA_OPT2_GAMMA, currentConfig.gamma, 1, 300, mgn_aopt_gamma), \ mee_onoff ("A_SN's gamma curve", MA_OPT2_A_SN_GAMMA, currentConfig.EmuOpt, EOPT_A_SN_GAMMA), \ @@ -76,3 +78,47 @@ const char *men_scaling_opts[] = { "OFF", "sw horizontal", "hw horizontal", "hw mee_onoff ("SVP dynarec", MA_OPT2_SVP_DYNAREC, PicoOpt, POPT_EN_SVP_DRC), \ mee_onoff ("Status line in main menu", MA_OPT2_STATUS_LINE, currentConfig.EmuOpt, EOPT_SHOW_RTC), + +static menu_entry e_menu_adv_options[]; +static menu_entry e_menu_gfx_options[]; +static menu_entry e_menu_options[]; + +void gp2x_menu_init(void) +{ + static menu_entry *cpu_clk_ent; + int i; + + i = me_id2offset(e_menu_options, MA_OPT_CPU_CLOCKS); + cpu_clk_ent = &e_menu_options[i]; + + /* disable by default.. */ + me_enable(e_menu_adv_options, MA_OPT_ARM940_SOUND, 0); + me_enable(e_menu_gfx_options, MA_OPT_TEARING_FIX, 0); + me_enable(e_menu_gfx_options, MA_OPT2_GAMMA, 0); + me_enable(e_menu_gfx_options, MA_OPT2_A_SN_GAMMA, 0); + + switch (gp2x_dev_id) { + case GP2X_DEV_GP2X: + me_enable(e_menu_adv_options, MA_OPT_ARM940_SOUND, 1); + me_enable(e_menu_gfx_options, MA_OPT2_GAMMA, 1); + me_enable(e_menu_gfx_options, MA_OPT2_A_SN_GAMMA, 1); + cpu_clk_ent->name = "GP2X CPU clocks"; + break; + case GP2X_DEV_WIZ: + me_enable(e_menu_gfx_options, MA_OPT_TEARING_FIX, 1); + cpu_clk_ent->name = "Wiz/Caanoo CPU clock"; + break; + case GP2X_DEV_CAANOO: + cpu_clk_ent->name = "Wiz/Caanoo CPU clock"; + break; + default: + break; + } + + if (gp2x_set_cpuclk == NULL) + cpu_clk_ent->name = ""; + + if (gp2x_dev_id != GP2X_DEV_GP2X) + men_scaling_opts[2] = NULL; /* leave only off and sw */ +} + diff --git a/platform/gp2x/plat.c b/platform/gp2x/plat.c index f0be14e7..6fce7bc2 100644 --- a/platform/gp2x/plat.c +++ b/platform/gp2x/plat.c @@ -16,14 +16,15 @@ /* GP2X local */ int default_cpu_clock; +int gp2x_dev_id; +int gp2x_current_bpp; void *gp2x_screens[4]; void gp2x_video_changemode(int bpp) { gp2x_video_changemode_ll(bpp); - gp2x_memset_all_buffers(0, 0, 320*240*2); - gp2x_video_flip(); + gp2x_current_bpp = bpp < 0 ? -bpp : bpp; } static void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len) @@ -65,17 +66,17 @@ void gp2x_make_fb_bufferable(int yes) } /* common */ -char cpu_clk_name[16] = "GP2X CPU clocks"; - void plat_video_menu_enter(int is_rom_loaded) { - /* try to switch nicely avoiding tearing on Wiz */ - gp2x_video_wait_vsync(); - memset(gp2x_screens[0], 0, 320*240*2); - memset(gp2x_screens[1], 0, 320*240*2); - gp2x_video_flip2(); - gp2x_video_wait_vsync(); - gp2x_video_wait_vsync(); + if (gp2x_current_bpp != 16 || gp2x_dev_id == GP2X_DEV_WIZ) { + /* try to switch nicely avoiding glitches */ + gp2x_video_wait_vsync(); + memset(gp2x_screens[0], 0, 320*240*2); + memset(gp2x_screens[1], 0, 320*240*2); + gp2x_video_flip2(); // might flip to fb2/3 + gp2x_video_flip2(); // ..so we do it again + // gp2x_video_wait_vsync(); + } // switch to 16bpp gp2x_video_changemode_ll(16); @@ -98,21 +99,34 @@ void plat_video_menu_end(void) void plat_early_init(void) { gp2x_soc_t soc; + FILE *f; soc = soc_detect(); switch (soc) { case SOCID_MMSP2: default_cpu_clock = 200; + gp2x_dev_id = GP2X_DEV_GP2X; break; case SOCID_POLLUX: - strcpy(cpu_clk_name, "Wiz CPU clock"); default_cpu_clock = 533; + f = fopen("/dev/accel", "rb"); + if (f) { + printf("detected Caanoo\n"); + gp2x_dev_id = GP2X_DEV_CAANOO; + fclose(f); + } + else { + printf("detected Wiz\n"); + gp2x_dev_id = GP2X_DEV_WIZ; + } break; default: printf("could not recognize SoC, running in dummy mode.\n"); break; } + + gp2x_menu_init(); } void plat_init(void) @@ -124,11 +138,9 @@ void plat_init(void) { case SOCID_MMSP2: mmsp2_init(); - menu_plat_setup(0); break; case SOCID_POLLUX: pollux_init(); - menu_plat_setup(1); break; default: dummy_init(); diff --git a/platform/gp2x/plat_gp2x.h b/platform/gp2x/plat_gp2x.h index 5a59452d..c77e061f 100644 --- a/platform/gp2x/plat_gp2x.h +++ b/platform/gp2x/plat_gp2x.h @@ -12,4 +12,18 @@ void gp2x_make_fb_bufferable(int yes); /* input */ int gp2x_touchpad_read(int *x, int *y); +/* misc */ +enum { + GP2X_DEV_GP2X = 1, + GP2X_DEV_WIZ, + GP2X_DEV_CAANOO, +}; +extern int gp2x_dev_id; +extern int gp2x_current_bpp; + +unsigned int plat_get_ticks_ms_good(void); +unsigned int plat_get_ticks_us_good(void); + +void gp2x_menu_init(void); + #endif diff --git a/platform/gp2x/soc.c b/platform/gp2x/soc.c index 5de0d237..43ebd85c 100644 --- a/platform/gp2x/soc.c +++ b/platform/gp2x/soc.c @@ -39,7 +39,7 @@ gp2x_soc_t soc_detect(void) int memdev; int i; - if (ret != -2) + if ((int)ret != -2) /* already detected */ return ret; diff --git a/platform/gp2x/soc_dummy.c b/platform/gp2x/soc_dummy.c index ad01ab76..99910825 100644 --- a/platform/gp2x/soc_dummy.c +++ b/platform/gp2x/soc_dummy.c @@ -35,11 +35,6 @@ static void gp2x_video_wait_vsync_(void) { } -/* CPU clock */ -static void gp2x_set_cpuclk_(unsigned int mhz) -{ -} - /* RAM timings */ static void set_ram_timings_(void) { @@ -81,8 +76,6 @@ void dummy_init(void) gp2x_video_RGB_setscaling = gp2x_video_RGB_setscaling_; gp2x_video_wait_vsync = gp2x_video_wait_vsync_; - gp2x_set_cpuclk = gp2x_set_cpuclk_; - set_lcd_custom_rate = set_lcd_custom_rate_; unset_lcd_custom_rate = unset_lcd_custom_rate_; set_lcd_gamma = set_lcd_gamma_; diff --git a/platform/gp2x/soc_mmsp2.c b/platform/gp2x/soc_mmsp2.c index 155cdf94..35748d84 100644 --- a/platform/gp2x/soc_mmsp2.c +++ b/platform/gp2x/soc_mmsp2.c @@ -41,9 +41,6 @@ static unsigned short gp2x_screenaddr_old[4]; static unsigned short memtimex_old[2]; static unsigned short reg0910; -extern unsigned int plat_get_ticks_ms_good(void); -extern unsigned int plat_get_ticks_us_good(void); - /* video stuff */ static void gp2x_video_flip_(void) { diff --git a/platform/gp2x/soc_pollux.c b/platform/gp2x/soc_pollux.c index 3b2ca2df..b343e149 100644 --- a/platform/gp2x/soc_pollux.c +++ b/platform/gp2x/soc_pollux.c @@ -21,11 +21,12 @@ #include "soc.h" #include "plat_gp2x.h" #include "../common/emu.h" +#include "../common/plat.h" #include "../common/arm_utils.h" #include "pollux_set.h" static volatile unsigned short *memregs; -static volatile unsigned long *memregl; +static volatile unsigned int *memregl; static int memdev = -1; static int battdev = -1; @@ -241,10 +242,29 @@ static void timer_cleanup(void) TIMER_REG(0x44) = 0; /* dividers back to default */ } +/* note: both PLLs are programmed the same way, + * the databook incorrectly states that PLL1 differs */ +static int decode_pll(unsigned int reg) +{ + long long v; + int p, m, s; + + p = (reg >> 18) & 0x3f; + m = (reg >> 8) & 0x3ff; + s = reg & 0xff; + + if (p == 0) + p = 1; + + v = 27000000; // master clock + v = v * m / (p << s); + return v; +} + void pollux_init(void) { struct fb_fix_screeninfo fbfix; - int i, ret; + int i, ret, rate; memdev = open("/dev/mem", O_RDWR); if (memdev == -1) { @@ -297,13 +317,32 @@ void pollux_init(void) if (battdev < 0) perror("Warning: could't open pollux_batt"); + /* find what PLL1 runs at, for the timer */ + rate = decode_pll(memregl[0xf008>>2]); + printf("PLL1 @ %dHz\n", rate); + rate /= 1000000; + /* setup timer */ - if (TIMER_REG(0x08) & 8) - timer_cleanup(); + if (1 <= rate && rate <= 256) { + if (TIMER_REG(0x08) & 8) { + fprintf(stderr, "warning: timer in use, overriding!\n"); + timer_cleanup(); + } + + TIMER_REG(0x44) = ((rate - 1) << 4) | 2; /* using PLL1, divide by it's rate */ + TIMER_REG(0x40) = 0x0c; /* clocks on */ + TIMER_REG(0x08) = 0x6b; /* run timer, clear irq, latch value */ + + gp2x_get_ticks_ms = gp2x_get_ticks_ms_; + gp2x_get_ticks_us = gp2x_get_ticks_us_; + } + else { + fprintf(stderr, "warning: could not make use of timer\n"); - TIMER_REG(0x44) = 0x922; /* using PLL1, divider value 147 */ - TIMER_REG(0x40) = 0x0c; /* clocks on */ - TIMER_REG(0x08) = 0x6b; /* run timer, clear irq, latch value */ + // those functions are actually not good at all on Wiz kernel + gp2x_get_ticks_ms = plat_get_ticks_ms_good; + gp2x_get_ticks_us = plat_get_ticks_us_good; + } pllsetreg0 = memregl[0xf004>>2]; memtimex_old[0] = memregs[0x14802>>1]; @@ -316,7 +355,15 @@ void pollux_init(void) gp2x_video_RGB_setscaling = gp2x_video_RGB_setscaling_; gp2x_video_wait_vsync = gp2x_video_wait_vsync_; - gp2x_set_cpuclk = gp2x_set_cpuclk_; + /* some firmwares have sys clk on PLL0, we can't adjust CPU clock + * by reprogramming the PLL0 then, as it overclocks system bus */ + if ((memregl[0xf000>>2] & 0x03000030) == 0x01000000) + gp2x_set_cpuclk = gp2x_set_cpuclk_; + else { + fprintf(stderr, "unexpected PLL config (%08x), overclocking disabled\n", + memregl[0xf000>>2]); + gp2x_set_cpuclk = NULL; + } set_lcd_custom_rate = set_lcd_custom_rate_; unset_lcd_custom_rate = unset_lcd_custom_rate_; @@ -325,9 +372,6 @@ void pollux_init(void) set_ram_timings = set_ram_timings_; unset_ram_timings = unset_ram_timings_; gp2x_read_battery = gp2x_read_battery_; - - gp2x_get_ticks_ms = gp2x_get_ticks_ms_; - gp2x_get_ticks_us = gp2x_get_ticks_us_; } void pollux_finish(void) diff --git a/platform/linux/emu.c b/platform/linux/emu.c index db5d6be8..65d868b5 100644 --- a/platform/linux/emu.c +++ b/platform/linux/emu.c @@ -17,7 +17,6 @@ static short __attribute__((aligned(4))) sndBuffer[2*44100/50]; -char cpu_clk_name[] = "unused"; const char *renderer_names[] = { "16bit accurate", " 8bit accurate", " 8bit fast", NULL }; const char *renderer_names32x[] = { "accurate", "faster", "fastest", NULL }; enum renderer_types { RT_16BIT, RT_8BIT_ACC, RT_8BIT_FAST, RT_COUNT }; @@ -125,9 +124,6 @@ void pemu_finalize_frame(const char *fps, const char *notice) static void apply_renderer(void) { - PicoScanBegin = NULL; - PicoScanEnd = NULL; - switch (currentConfig.renderer) { case RT_16BIT: PicoOpt &= ~POPT_ALT_RENDERER; diff --git a/platform/pandora/menu.c b/platform/pandora/menu.c index ae2a0790..bcbbc1ca 100644 --- a/platform/pandora/menu.c +++ b/platform/pandora/menu.c @@ -81,6 +81,7 @@ static int menu_loop_cscaler(menu_id id, int keys) #include static menu_entry e_menu_gfx_options[]; +static menu_entry e_menu_options[]; void pnd_menu_init(void) { @@ -139,5 +140,8 @@ void pnd_menu_init(void) i = me_id2offset(e_menu_gfx_options, MA_OPT3_FILTERING); e_menu_gfx_options[i].data = (void *)mfilters; pnd_filter_list = mfilters; + + i = me_id2offset(e_menu_options, MA_OPT_SCALING); + e_menu_options[i]->name = "Max CPU clock"; } diff --git a/platform/pandora/plat.c b/platform/pandora/plat.c index e259f857..99519732 100644 --- a/platform/pandora/plat.c +++ b/platform/pandora/plat.c @@ -39,7 +39,6 @@ static unsigned char __attribute__((aligned(4))) fb_copy[g_screen_width * g_scre unsigned char *PicoDraw2FB = temp_frame; const char *renderer_names[] = { NULL }; const char *renderer_names32x[] = { NULL }; -char cpu_clk_name[] = "Max CPU clock"; static int get_cpu_clock(void) { @@ -371,9 +370,8 @@ void emu_video_mode_change(int start_line, int line_count, int is_32cols) { int fb_w = 320, fb_h = 240, fb_left = 0, fb_right = 0, fb_top = 0, fb_bottom = 0; - PicoScanBegin = emuscan; - PicoScanEnd = NULL; PicoDrawSetOutFormat(PDF_RGB555, 1); + PicoDrawSetCallbacks(emuscan, NULL); if (is_32cols) { fb_w = 256; diff --git a/platform/psp/emu.c b/platform/psp/emu.c index 77b20d19..8ee4a96d 100644 --- a/platform/psp/emu.c +++ b/platform/psp/emu.c @@ -466,8 +466,7 @@ static void vidResetMode(void) // slow rend. PicoDrawSetOutFormat(PDF_NONE, 0); - PicoScanBegin = EmuScanSlowBegin; - PicoScanEnd = EmuScanSlowEnd; + PicoDrawSetCallbacks(EmuScanSlowBegin, EmuScanSlowEnd); localPal[0xe0] = 0; localPal[0xf0] = 0x001f; @@ -683,8 +682,7 @@ void pemu_forced_frame(int opts, int no_scale) memset32_uncached((int *)psp_screen + 512*264*2/4, 0, 512*8*2/4); PicoDrawSetOutFormat(PDF_NONE, 0); - PicoScanBegin = EmuScanSlowBegin; - PicoScanEnd = EmuScanSlowEnd; + PicoDrawSetCallbacks(EmuScanSlowBegin, EmuScanSlowEnd); EmuScanPrepare(); PicoFrameDrawOnly(); blit1(); diff --git a/platform/win32/plat.c b/platform/win32/plat.c index 15aff220..f83a9011 100644 --- a/platform/win32/plat.c +++ b/platform/win32/plat.c @@ -16,8 +16,6 @@ unsigned char *PicoDraw2FB = PicoDraw2FB_; const char *renderer_names[] = { NULL }; const char *renderer_names32x[] = { NULL }; -char cpu_clk_name[] = "unused"; - void plat_init(void) { g_screen_ptr = (void *)screen_buff;