}\r
}\r
\r
+void PicoDrawSetCallbacks(int (*begin)(unsigned int num), int (*end)(unsigned int num))\r
+{\r
+ PicoScanBegin = NULL;\r
+ PicoScanEnd = NULL;\r
+ PicoScan32xBegin = NULL;\r
+ PicoScan32xEnd = NULL;\r
+\r
+ if ((PicoAHW & PAHW_32X) && FinalizeLine != FinalizeLine32xRGB555) {\r
+ PicoScan32xBegin = begin;\r
+ PicoScan32xEnd = end;\r
+ }\r
+ else {\r
+ PicoScanBegin = begin;\r
+ PicoScanEnd = end;\r
+ }\r
+}\r
stmfd sp!, {r4-r9,lr}\r
mov r8, #0x0061\r
orr r8, r8, #0x0800\r
- orr r8, r8, lsl #16\r
+ orr r8, r8, r8, lsl #16\r
vidConvCpyRGB565_local\r
ldmfd sp!, {r4-r9,lr}\r
bx lr\r
mov r2, #0x40\r
mov r8, #0x0061\r
orr r8, r8, #0x0800\r
- orr r8, r8, lsl #16\r
+ orr r8, r8, r8, lsl #16\r
\r
vidConvCpyRGB565_local\r
\r
} pdso_t;\r
void PicoDrawSetOutFormat(pdso_t which, int allow_32x);\r
void PicoDrawSetOutBuf(void *dest, int increment);\r
+void PicoDrawSetCallbacks(int (*begin)(unsigned int num), int (*end)(unsigned int num));\r
extern void *DrawLineDest;\r
extern unsigned char *HighCol;\r
-extern int (*PicoScanBegin)(unsigned int num);\r
-extern int (*PicoScanEnd)(unsigned int num);\r
// utility\r
#ifdef _ASM_DRAW_C\r
void vidConvCpyRGB565(void *to, void *from, int pixels);\r
\r
// 32x/draw.c\r
void PicoDraw32xSetFrameMode(int is_on, int only_32x);\r
-extern int (*PicoScan32xBegin)(unsigned int num);\r
-extern int (*PicoScan32xEnd)(unsigned int num);\r
\r
// sound.c\r
extern int PsndRate,PsndLen;\r
void PicoDrawSync(int to, int blank_last_line);\r
void BackFill(int reg7, int sh);\r
void FinalizeLine555(int sh, int line);\r
+extern int (*PicoScanBegin)(unsigned int num);\r
+extern int (*PicoScanEnd)(unsigned int num);\r
extern int DrawScanline;\r
#define MAX_LINE_SPRITES 29\r
extern unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES];\r
void FinalizeLine32xRGB555(int sh, int line);\r
void PicoDraw32xLayer(int offs, int lines, int mdbg);\r
void PicoDraw32xLayerMdOnly(int offs, int lines);\r
+extern int (*PicoScan32xBegin)(unsigned int num);\r
+extern int (*PicoScan32xEnd)(unsigned int num);\r
enum {\r
PDM32X_OFF,\r
PDM32X_32X_ONLY,\r
enum {
EOPT_SCALE_NONE = 0,
- EOPT_SCALE_SW_H,
- EOPT_SCALE_HW_H,
- EOPT_SCALE_HW_HV,
+ EOPT_SCALE_SW,
+ EOPT_SCALE_HW,
};
enum {
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
{\r
static int sel = 0;\r
\r
- me_enable(e_menu_32x_options, MA_32XOPT_RENDERER, renderer_names32x != NULL);\r
+ me_enable(e_menu_32x_options, MA_32XOPT_RENDERER, renderer_names32x[0] != NULL);\r
me_loop(e_menu_32x_options, &sel, NULL);\r
\r
return 0;\r
mee_onoff ("Enable sound", MA_OPT_ENABLE_SOUND, currentConfig.EmuOpt, EOPT_EN_SOUND),\r
mee_cust ("Sound Quality", MA_OPT_SOUND_QUALITY, mh_opt_misc, mgn_opt_sound),\r
mee_enum_h ("Confirm savestate", MA_OPT_CONFIRM_STATES,currentConfig.confirm_save, men_confirm_save, h_confirm_save),\r
- mee_range (cpu_clk_name, MA_OPT_CPU_CLOCKS, currentConfig.CPUclock, 20, 900),\r
+ mee_range ("", MA_OPT_CPU_CLOCKS, currentConfig.CPUclock, 20, 900),\r
mee_handler ("[Display options]", menu_loop_gfx_options),\r
mee_handler ("[Sega/Mega CD options]", menu_loop_cd_options),\r
#ifndef NO_32X\r
static int menu_loop_options(menu_id id, int keys)\r
{\r
static int sel = 0;\r
+ int i;\r
\r
+ i = me_id2offset(e_menu_options, MA_OPT_CPU_CLOCKS);\r
+ e_menu_options[i].enabled = e_menu_options[i].name ? 1 : 0;\r
me_enable(e_menu_options, MA_OPT_SAVECFG_GAME, rom_loaded);\r
me_enable(e_menu_options, MA_OPT_LOADCFG, config_slot != config_slot_current);\r
\r
\r
// ------------ util ------------\r
\r
-/* GP2X/wiz for now, probably extend later */\r
-void menu_plat_setup(int is_wiz)\r
-{\r
- int i;\r
-\r
- if (!is_wiz) {\r
- me_enable(e_menu_gfx_options, MA_OPT_TEARING_FIX, 0);\r
- i = me_id2offset(e_menu_gfx_options, MA_OPT_TEARING_FIX);\r
- e_menu_gfx_options[i].need_to_save = 0;\r
- return;\r
- }\r
-\r
- me_enable(e_menu_adv_options, MA_OPT_ARM940_SOUND, 0);\r
- me_enable(e_menu_gfx_options, MA_OPT2_GAMMA, 0);\r
- me_enable(e_menu_gfx_options, MA_OPT2_A_SN_GAMMA, 0);\r
-\r
- i = me_id2offset(e_menu_gfx_options, MA_OPT_SCALING);\r
- e_menu_gfx_options[i].max = 1; /* only off and sw */\r
- i = me_id2offset(e_menu_gfx_options, MA_OPT_ARM940_SOUND);\r
- e_menu_gfx_options[i].need_to_save = 0;\r
-}\r
-\r
/* hidden options for config engine only */\r
static menu_entry e_menu_hidden[] =\r
{\r
MA_MAIN_EXIT,
MA_OPT_RENDERER,
MA_OPT_SCALING,
+ MA_OPT_VSCALING,
MA_OPT_ACC_SPRITES,
MA_OPT_SHOW_FPS,
MA_OPT_FRAMESKIP,
#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);
#endif
/* stuff to be implemented by platform code */
-extern char cpu_clk_name[];
extern const char *renderer_names[];
extern const char *renderer_names32x[];
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
giz_screen = fb_lock(1);
PicoDrawSetOutFormat(PDF_RGB555, 0);
- PicoScanBegin = EmuScanBegin16;
+ PicoDrawSetCallbacks(EmuScanBegin16, NULL);
Pico.m.dirtyPal = 1;
PicoFrameDrawOnly();
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 "$@"
static short __attribute__((aligned(4))) sndBuffer[2*(44100+100)/50];\r
static unsigned char PicoDraw2FB_[(8+320) * (8+240+8)];\r
unsigned char *PicoDraw2FB = PicoDraw2FB_;\r
-static int osd_fps_x, osd_y;\r
+static int osd_fps_x, osd_y, doing_bg_frame;\r
const char *renderer_names[] = { "16bit accurate", " 8bit accurate", " 8bit fast", NULL };\r
const char *renderer_names32x[] = { "accurate", "faster", "fastest", NULL };\r
enum renderer_types { RT_16BIT, RT_8BIT_ACC, RT_8BIT_FAST, RT_COUNT };\r
\r
-extern void *gp2x_screens[4];\r
-\r
+static int (*emu_scan_begin)(unsigned int num) = NULL;\r
+static int (*emu_scan_end)(unsigned int num) = NULL;\r
\r
-static void scaling_update(void)\r
-{\r
- PicoOpt &= ~(POPT_DIS_32C_BORDER|POPT_EN_SOFTSCALE);\r
- switch (currentConfig.scaling) {\r
- default:break;\r
- case EOPT_SCALE_HW_H:\r
- case EOPT_SCALE_HW_HV:\r
- PicoOpt |= POPT_DIS_32C_BORDER;\r
- break;\r
- case EOPT_SCALE_SW_H:\r
- PicoOpt |= POPT_EN_SOFTSCALE;\r
- break;\r
- }\r
-}\r
+extern void *gp2x_screens[4];\r
\r
\r
void pemu_prep_defconfig(void)\r
\r
void pemu_validate_config(void)\r
{\r
- gp2x_soc_t soc;\r
-\r
- soc = soc_detect();\r
- if (soc != SOCID_MMSP2)\r
+ if (gp2x_dev_id != GP2X_DEV_GP2X)\r
PicoOpt &= ~POPT_EXT_FM;\r
- if (soc != SOCID_POLLUX)\r
+ if (gp2x_dev_id != GP2X_DEV_WIZ)\r
currentConfig.EmuOpt &= ~EOPT_WIZ_TEAR_FIX;\r
\r
if (currentConfig.gamma < 10 || currentConfig.gamma > 300)\r
else\r
r = ¤tConfig.renderer;\r
*r += diff;\r
+\r
+ // 8bpp fast is not there (yet?)\r
+ if ((PicoAHW & PAHW_SMS) && *r == RT_8BIT_FAST)\r
+ (*r)++;\r
+\r
if (*r >= RT_COUNT)\r
*r = 0;\r
else if (*r < 0)\r
return 0;\r
}\r
\r
+/* line doublers */\r
+static unsigned int ld_counter;\r
+static int ld_left, ld_lines;\r
+\r
+static int EmuScanBegin16_ld(unsigned int num)\r
+{\r
+ if ((signed int)(ld_counter - num) > 100)\r
+ ld_counter = 0;\r
+\r
+ if (emu_scan_begin)\r
+ return emu_scan_begin(ld_counter);\r
+ else\r
+ DrawLineDest = (char *)g_screen_ptr + 320 * ld_counter * gp2x_current_bpp / 8;\r
+\r
+ return 0;\r
+}\r
+\r
+static int EmuScanEnd16_ld(unsigned int num)\r
+{\r
+ void *oldline = DrawLineDest;\r
+\r
+ if (emu_scan_end)\r
+ emu_scan_end(ld_counter);\r
+\r
+ ld_counter++;\r
+ ld_left--;\r
+ if (ld_left <= 0) {\r
+ ld_left = ld_lines;\r
+\r
+ EmuScanBegin16_ld(num);\r
+ memcpy32(DrawLineDest, oldline, 320 * gp2x_current_bpp / 8 / 4);\r
+ if (emu_scan_end)\r
+ emu_scan_end(ld_counter);\r
+\r
+ ld_counter++;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
static int localPal[0x100];\r
static void (*vidcpyM2)(void *dest, void *src, int m32col, int with_32c_border);\r
static int (*make_local_pal)(int fast_mode);\r
}\r
}\r
\r
- if (notice || (emu_opt & EOPT_SHOW_FPS)) {\r
- if (notice)\r
- osd_text(4, osd_y, notice);\r
- if (emu_opt & 2)\r
- osd_text(osd_fps_x, osd_y, fps);\r
- }\r
+ if (notice)\r
+ osd_text(4, osd_y, notice);\r
+ if (emu_opt & EOPT_SHOW_FPS)\r
+ osd_text(osd_fps_x, osd_y, fps);\r
if ((PicoAHW & PAHW_MCD) && (emu_opt & EOPT_EN_CD_LEDS))\r
draw_cd_leds();\r
if (PicoAHW & PAHW_PICO)\r
plat_status_msg_busy_next(msg);\r
}\r
\r
-static void vidResetMode(void)\r
+static void vid_reset_mode(void)\r
{\r
int gp2x_mode = 16;\r
int renderer = get_renderer();\r
\r
- PicoScanBegin = NULL;\r
- PicoScanEnd = NULL;\r
+ PicoOpt &= ~POPT_ALT_RENDERER;\r
+ emu_scan_begin = NULL;\r
+ emu_scan_end = NULL;\r
\r
switch (renderer) {\r
case RT_16BIT:\r
- PicoOpt &= ~POPT_ALT_RENDERER;\r
PicoDrawSetOutFormat(PDF_RGB555, 0);\r
PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
- if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
- PicoScanBegin = EmuScanBegin16_rot;\r
- PicoScanEnd = EmuScanEnd16_rot;\r
- }\r
break;\r
case RT_8BIT_ACC:\r
- PicoOpt &= ~POPT_ALT_RENDERER;\r
PicoDrawSetOutFormat(PDF_8BIT, 0);\r
PicoDrawSetOutBuf(g_screen_ptr, g_screen_width);\r
- if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
- PicoScanBegin = EmuScanBegin8_rot;\r
- PicoScanEnd = EmuScanEnd8_rot;\r
- }\r
gp2x_mode = 8;\r
break;\r
case RT_8BIT_FAST:\r
- PicoOpt |= POPT_ALT_RENDERER;\r
+ PicoOpt |= POPT_ALT_RENDERER;\r
PicoDrawSetOutFormat(PDF_NONE, 0);\r
- if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)\r
- vidcpyM2 = vidcpy_m2_rot;\r
- else\r
- vidcpyM2 = vidcpy_m2;\r
+ vidcpyM2 = vidcpy_m2;\r
gp2x_mode = 8;\r
break;\r
+ default:\r
+ printf("bad renderer\n");\r
+ break;\r
}\r
\r
- if (is_16bit_mode())\r
- osd_text = (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) ? osd_text16_rot : osd_text16;\r
- else\r
- osd_text = (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) ? osd_text8_rot : osd_text8;\r
-\r
if (PicoAHW & PAHW_32X) {\r
- // rules change in 32X world\r
- if (renderer != RT_16BIT) {\r
- PicoDrawSetOutFormat(PDF_NONE, 0);\r
- PicoScanBegin = NULL;\r
- PicoScanEnd = NULL;\r
- }\r
- PicoScan32xBegin = NULL;\r
- PicoScan32xEnd = NULL;\r
- if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
- PicoScan32xBegin = EmuScanBegin16_rot;\r
- PicoScan32xEnd = EmuScanEnd16_rot;\r
- }\r
// Wiz 16bit is an exception, uses line rendering due to rotation mess\r
if (renderer == RT_16BIT && (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)) {\r
PicoDrawSetOutFormat(PDF_RGB555, 1);\r
PicoDraw32xSetFrameMode(0, 0);\r
}\r
else {\r
+ PicoDrawSetOutFormat(PDF_NONE, 0);\r
PicoDraw32xSetFrameMode(1, (renderer == RT_16BIT) ? 1 : 0);\r
}\r
PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
- gp2x_mode = 16;\r
}\r
\r
+ if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
+ if ((PicoAHW & PAHW_32X) || renderer == RT_16BIT) {\r
+ emu_scan_begin = EmuScanBegin16_rot;\r
+ emu_scan_end = EmuScanEnd16_rot;\r
+ }\r
+ else if (renderer == RT_8BIT_ACC) {\r
+ emu_scan_begin = EmuScanBegin8_rot;\r
+ emu_scan_end = EmuScanEnd8_rot;\r
+ }\r
+ else if (renderer == RT_8BIT_FAST)\r
+ vidcpyM2 = vidcpy_m2_rot;\r
+ }\r
+\r
+ PicoDrawSetCallbacks(emu_scan_begin, emu_scan_end);\r
+\r
+ if (is_16bit_mode())\r
+ osd_text = (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) ? osd_text16_rot : osd_text16;\r
+ else\r
+ osd_text = (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) ? osd_text8_rot : osd_text8;\r
+\r
if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)\r
gp2x_mode = -gp2x_mode;\r
+\r
+ gp2x_video_wait_vsync();\r
gp2x_video_changemode(gp2x_mode);\r
\r
if (!is_16bit_mode()) {\r
localPal[0xf0] = 0x00ffffff;\r
gp2x_video_setpalette(localPal, 0x100);\r
gp2x_memset_all_buffers(0, 0xe0, 320*240);\r
- gp2x_video_flip();\r
}\r
+ else\r
+ gp2x_memset_all_buffers(0, 0, 320*240*2);\r
+\r
Pico.m.dirtyPal = 1;\r
\r
- // reset scaling\r
- if (currentConfig.scaling == EOPT_SCALE_HW_HV && !(Pico.video.reg[1]&8))\r
- gp2x_video_RGB_setscaling(8, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 224);\r
- else gp2x_video_RGB_setscaling(0, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 240);\r
+ PicoOpt &= ~POPT_EN_SOFTSCALE;\r
+ if (currentConfig.scaling == EOPT_SCALE_SW)\r
+ PicoOpt |= POPT_EN_SOFTSCALE;\r
\r
// palette converters for 8bit modes\r
make_local_pal = (PicoAHW & PAHW_SMS) ? make_local_pal_sms : make_local_pal_md;\r
}\r
\r
+void emu_video_mode_change(int start_line, int line_count, int is_32cols)\r
+{\r
+ int scalex = 320, scaley = 240;\r
+ int ln_offs = 0;\r
+\r
+ if (doing_bg_frame)\r
+ return;\r
+\r
+ osd_fps_x = OSD_FPS_X;\r
+ osd_y = 232;\r
+\r
+ /* set up hwscaling here */\r
+ PicoOpt &= ~POPT_DIS_32C_BORDER;\r
+ if (is_32cols && currentConfig.scaling == EOPT_SCALE_HW) {\r
+ scalex = 256;\r
+ PicoOpt |= POPT_DIS_32C_BORDER;\r
+ osd_fps_x = OSD_FPS_X - 64;\r
+ }\r
+\r
+ if (currentConfig.vscaling == EOPT_SCALE_HW) {\r
+ ln_offs = start_line;\r
+ scaley = line_count;\r
+ osd_y = start_line + line_count - 8;\r
+ }\r
+\r
+ gp2x_video_RGB_setscaling(ln_offs, scalex, scaley);\r
+\r
+ /* line doubling */\r
+ if (currentConfig.vscaling == EOPT_SCALE_SW && line_count < 240) {\r
+ ld_lines = ld_left = line_count / (240 - line_count);\r
+ PicoDrawSetCallbacks(EmuScanBegin16_ld, EmuScanEnd16_ld);\r
+ }\r
+\r
+ // clear whole screen in all buffers\r
+ if (!is_16bit_mode())\r
+ gp2x_memset_all_buffers(0, 0xe0, 320*240);\r
+ else\r
+ gp2x_memset_all_buffers(0, 0, 320*240*2);\r
+}\r
+\r
void plat_video_toggle_renderer(int change, int is_menu_call)\r
{\r
change_renderer(change);\r
if (is_menu_call)\r
return;\r
\r
- vidResetMode();\r
+ vid_reset_mode();\r
rendstatus_old = -1;\r
\r
if (PicoAHW & PAHW_32X)\r
// don't need to do anything, writes will block by themselves\r
}\r
\r
-\r
void pemu_forced_frame(int opts, int no_scale)\r
{\r
int po_old = PicoOpt;\r
\r
+ doing_bg_frame = 1;\r
PicoOpt &= ~POPT_ALT_RENDERER;\r
PicoOpt |= opts|POPT_ACC_SPRITES;\r
\r
+ memset32(g_screen_ptr, 0, g_screen_width * g_screen_height * 2 / 4);\r
+\r
PicoDrawSetOutFormat(PDF_RGB555, 1);\r
PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
PicoDraw32xSetFrameMode(0, 0);\r
- PicoScanBegin = NULL;\r
- PicoScanEnd = NULL;\r
+ PicoDrawSetCallbacks(NULL, NULL);\r
Pico.m.dirtyPal = 1;\r
- PicoFrameDrawOnly();\r
\r
+ if (no_scale == -9)\r
+ // yes I'm lazy, see pemu_forced_frame call below\r
+ PicoFrame();\r
+ else\r
+ PicoFrameDrawOnly();\r
+\r
+ doing_bg_frame = 0;\r
PicoOpt = po_old;\r
}\r
\r
{\r
}\r
\r
-void emu_video_mode_change(int start_line, int line_count, int is_32cols)\r
-{\r
- int scalex = 320;\r
- osd_fps_x = OSD_FPS_X;\r
- osd_y = 232;\r
- if (is_32cols && (PicoOpt & POPT_DIS_32C_BORDER)) {\r
- scalex = 256;\r
- osd_fps_x = OSD_FPS_X - 64;\r
- }\r
-\r
- /* want vertical scaling and game is not in 240 line mode */\r
- if (currentConfig.scaling == EOPT_SCALE_HW_HV) {\r
- gp2x_video_RGB_setscaling(start_line, scalex, line_count);\r
- osd_y = start_line + line_count - 8;\r
- } else\r
- gp2x_video_RGB_setscaling(0, scalex, 240);\r
-\r
- // clear whole screen in all buffers\r
- if (!is_16bit_mode())\r
- gp2x_memset_all_buffers(0, 0xe0, 320*240);\r
- else\r
- gp2x_memset_all_buffers(0, 0, 320*240*2);\r
-}\r
-\r
#if 0\r
static void tga_dump(void)\r
{\r
\r
if (gp2x_old_clock < 0)\r
gp2x_old_clock = default_cpu_clock;\r
- if (gp2x_old_clock != currentConfig.CPUclock) {\r
+ if (gp2x_old_clock != currentConfig.CPUclock && gp2x_set_cpuclk != NULL) {\r
printf("changing clock to %i...", currentConfig.CPUclock); fflush(stdout);\r
gp2x_set_cpuclk(currentConfig.CPUclock);\r
gp2x_old_clock = currentConfig.CPUclock;\r
pal_old = Pico.m.pal;\r
\r
// make sure we are in correct mode\r
- vidResetMode();\r
- scaling_update();\r
+ change_renderer(0);\r
+ vid_reset_mode();\r
\r
// dirty buffers better go now than during gameplay\r
sync();\r
\r
void pemu_loop_end(void)\r
{\r
- int po_old = PicoOpt;\r
- int eo_old = currentConfig.EmuOpt;\r
-\r
pemu_sound_stop();\r
- memset32(g_screen_ptr, 0, 320*240*2/4);\r
\r
/* do one more frame for menu bg */\r
- PicoOpt &= ~POPT_ALT_RENDERER;\r
- PicoOpt |= POPT_EN_SOFTSCALE|POPT_ACC_SPRITES;\r
-\r
- PicoDrawSetOutFormat(PDF_RGB555, 1);\r
- PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
- PicoDraw32xSetFrameMode(0, 0);\r
- PicoScanBegin = NULL;\r
- PicoScanEnd = NULL;\r
- Pico.m.dirtyPal = 1;\r
- PicoFrame();\r
-\r
- PicoOpt = po_old;\r
- currentConfig.EmuOpt = eo_old;\r
+ pemu_forced_frame(POPT_EN_SOFTSCALE, -9);\r
+ g_menubg_src_ptr = g_screen_ptr;\r
}\r
\r
const char *plat_get_credits(void)\r
#include "../common/input.h"
#include "in_gp2x.h"
-#include "soc.h"
+#include "plat_gp2x.h"
#define IN_PREFIX "gp2x:"
#define IN_GP2X_NBUTTONS 32
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");
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;
#include <time.h>
#include "soc.h"
+#include "plat_gp2x.h"
static void menu_main_plat_draw(void)
{
}
-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), \
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 */
+}
+
/* 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)
}
/* 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);
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)
{
case SOCID_MMSP2:
mmsp2_init();
- menu_plat_setup(0);
break;
case SOCID_POLLUX:
pollux_init();
- menu_plat_setup(1);
break;
default:
dummy_init();
/* 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
int memdev;
int i;
- if (ret != -2)
+ if ((int)ret != -2)
/* already detected */
return ret;
{
}
-/* CPU clock */
-static void gp2x_set_cpuclk_(unsigned int mhz)
-{
-}
-
/* RAM timings */
static void set_ram_timings_(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_;
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)
{
#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;
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) {
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];
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_;
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)
\r
\r
static short __attribute__((aligned(4))) sndBuffer[2*44100/50];\r
-char cpu_clk_name[] = "unused";\r
const char *renderer_names[] = { "16bit accurate", " 8bit accurate", " 8bit fast", NULL };\r
const char *renderer_names32x[] = { "accurate", "faster", "fastest", NULL };\r
enum renderer_types { RT_16BIT, RT_8BIT_ACC, RT_8BIT_FAST, RT_COUNT };\r
\r
static void apply_renderer(void)\r
{\r
- PicoScanBegin = NULL;\r
- PicoScanEnd = NULL;\r
-\r
switch (currentConfig.renderer) {\r
case RT_16BIT:\r
PicoOpt &= ~POPT_ALT_RENDERER;\r
#include <errno.h>
static menu_entry e_menu_gfx_options[];
+static menu_entry e_menu_options[];
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";
}
unsigned char *PicoDraw2FB = temp_frame;\r
const char *renderer_names[] = { NULL };\r
const char *renderer_names32x[] = { NULL };\r
-char cpu_clk_name[] = "Max CPU clock";\r
\r
static int get_cpu_clock(void)\r
{\r
{\r
int fb_w = 320, fb_h = 240, fb_left = 0, fb_right = 0, fb_top = 0, fb_bottom = 0;\r
\r
- PicoScanBegin = emuscan;\r
- PicoScanEnd = NULL;\r
PicoDrawSetOutFormat(PDF_RGB555, 1);\r
+ PicoDrawSetCallbacks(emuscan, NULL);\r
\r
if (is_32cols) {\r
fb_w = 256;\r
// slow rend.
PicoDrawSetOutFormat(PDF_NONE, 0);
- PicoScanBegin = EmuScanSlowBegin;
- PicoScanEnd = EmuScanSlowEnd;
+ PicoDrawSetCallbacks(EmuScanSlowBegin, EmuScanSlowEnd);
localPal[0xe0] = 0;
localPal[0xf0] = 0x001f;
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();
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;