From: notaz Date: Thu, 25 Oct 2007 19:39:40 +0000 (+0000) Subject: psp gfx scaling/etc stuff X-Git-Tag: v1.85~639 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ab3e3c1cf696cb776b14ab511f98aa8ab22797e;p=picodrive.git psp gfx scaling/etc stuff git-svn-id: file:///home/notaz/opt/svn/PicoDrive@279 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/Pico/Memory.c b/Pico/Memory.c index 963d30b7..527b80b5 100644 --- a/Pico/Memory.c +++ b/Pico/Memory.c @@ -69,7 +69,7 @@ static __inline int PicoMemBase(u32 pc) #endif -static u32 CPU_CALL PicoCheckPc(u32 pc) +static u32 PicoCheckPc(u32 pc) { u32 ret=0; #if defined(EMU_C68K) @@ -315,7 +315,7 @@ static void OtherWrite8End(u32 a,u32 d,int realsize) // Read Rom and read Ram #ifndef _ASM_MEMORY_C -PICO_INTERNAL_ASM u32 CPU_CALL PicoRead8(u32 a) +PICO_INTERNAL_ASM u32 PicoRead8(u32 a) { u32 d=0; @@ -351,7 +351,7 @@ end: return d; } -PICO_INTERNAL_ASM u32 CPU_CALL PicoRead16(u32 a) +PICO_INTERNAL_ASM u32 PicoRead16(u32 a) { u32 d=0; @@ -387,7 +387,7 @@ end: return d; } -PICO_INTERNAL_ASM u32 CPU_CALL PicoRead32(u32 a) +PICO_INTERNAL_ASM u32 PicoRead32(u32 a) { u32 d=0; @@ -426,7 +426,7 @@ end: // Write Ram #ifndef _ASM_MEMORY_C -PICO_INTERNAL_ASM void CPU_CALL PicoWrite8(u32 a,u8 d) +PICO_INTERNAL_ASM void PicoWrite8(u32 a,u8 d) { #ifdef __debug_io dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc); @@ -446,7 +446,7 @@ PICO_INTERNAL_ASM void CPU_CALL PicoWrite8(u32 a,u8 d) } #endif -void CPU_CALL PicoWrite16(u32 a,u16 d) +void PicoWrite16(u32 a,u16 d) { #ifdef __debug_io dprintf("w16: %06x, %04x", a&0xffffff, d); @@ -462,7 +462,7 @@ void CPU_CALL PicoWrite16(u32 a,u16 d) OtherWrite16(a,d); } -static void CPU_CALL PicoWrite32(u32 a,u32 d) +static void PicoWrite32(u32 a,u32 d) { #ifdef __debug_io dprintf("w32: %06x, %08x", a&0xffffff, d); diff --git a/Pico/Pico.c b/Pico/Pico.c index ce3e3408..22bdb199 100644 --- a/Pico/Pico.c +++ b/Pico/Pico.c @@ -316,7 +316,7 @@ static int PicoFrameSimple(void) int cycles_68k_vblock,cycles_68k_block; // split to 16 run calls for active scan, for vblank split to 2 (ntsc), 3 (pal 240), 4 (pal 224) - if (Pico.m.pal && (pv->reg[1]&8)) { // 240 lines + if (Pico.m.pal && (pv->reg[1]&8)) { if(pv->reg[1]&8) { // 240 lines cycles_68k_block = 7329; // (488*240+148)/16.0, -4 cycles_68k_vblock = 11640; // (72*488-148-68)/3.0, 0 @@ -378,14 +378,6 @@ static int PicoFrameSimple(void) PicoRunZ80Simple(line, lines); } - // here we render sound if ym2612 is disabled - if (!(PicoOpt&1) && PsndOut) { - int len = sound_render(0, PsndLen); - if (PicoWriteSound) PicoWriteSound(len); - // clear sound buffer - sound_clear(); - } - // render screen if (!PicoSkipFrame) { @@ -401,6 +393,17 @@ static int PicoFrameSimple(void) for (y=0;y<224;y++) PicoLine(y); #endif else PicoFrameFull(); +#ifdef DRAW_FINISH_FUNC + DRAW_FINISH_FUNC(); +#endif + } + + // here we render sound if ym2612 is disabled + if (!(PicoOpt&1) && PsndOut) { + int len = sound_render(0, PsndLen); + if (PicoWriteSound) PicoWriteSound(len); + // clear sound buffer + sound_clear(); } // a gap between flags set and vint diff --git a/Pico/PicoFrameHints.c b/Pico/PicoFrameHints.c index c14040a6..ba76f6f8 100644 --- a/Pico/PicoFrameHints.c +++ b/Pico/PicoFrameHints.c @@ -139,6 +139,10 @@ static int PicoFrameHints(void) #endif } +#ifdef DRAW_FINISH_FUNC + DRAW_FINISH_FUNC(); +#endif + // V-int line (224 or 240) Pico.m.scanline=(short)y; diff --git a/Pico/PicoInt.h b/Pico/PicoInt.h index a9720c86..7a81ba6f 100644 --- a/Pico/PicoInt.h +++ b/Pico/PicoInt.h @@ -313,7 +313,7 @@ PICO_INTERNAL void PicoFrameFull(); // Memory.c PICO_INTERNAL int PicoInitPc(unsigned int pc); -PICO_INTERNAL_ASM unsigned int CPU_CALL PicoRead32(unsigned int a); +PICO_INTERNAL_ASM unsigned int PicoRead32(unsigned int a); PICO_INTERNAL void PicoMemSetup(void); PICO_INTERNAL_ASM void PicoMemReset(void); PICO_INTERNAL int PadRead(int i); diff --git a/cpu/Cyclone/Disa/Disa.c b/cpu/Cyclone/Disa/Disa.c index 26c99676..190e36df 100644 --- a/cpu/Cyclone/Disa/Disa.c +++ b/cpu/Cyclone/Disa/Disa.c @@ -11,7 +11,7 @@ unsigned int DisaPc=0; char *DisaText=NULL; // Text buffer to write in static char Tasm[]="bwl?"; static char Comment[64]=""; -unsigned short (CPU_CALL *DisaWord)(unsigned int a)=NULL; +unsigned short (*DisaWord)(unsigned int a)=NULL; static unsigned int DisaLong(unsigned int a) { diff --git a/cpu/Cyclone/Disa/Disa.h b/cpu/Cyclone/Disa/Disa.h index 9d45611f..1ef18fcf 100644 --- a/cpu/Cyclone/Disa/Disa.h +++ b/cpu/Cyclone/Disa/Disa.h @@ -5,16 +5,10 @@ extern "C" { #endif -#if defined(ARM) || defined(GP32) || !defined (__WINS__) -#define CPU_CALL -#else -#define CPU_CALL __fastcall -#endif - extern unsigned int DisaPc; extern char *DisaText; // Text buffer to write in -extern unsigned short (CPU_CALL *DisaWord)(unsigned int a); +extern unsigned short (*DisaWord)(unsigned int a); int DisaGetEa(char *t,int ea,int size); int DisaGet(); diff --git a/cpu/Cyclone/OpAny.cpp b/cpu/Cyclone/OpAny.cpp index 0ada13f5..6ee08ec1 100644 --- a/cpu/Cyclone/OpAny.cpp +++ b/cpu/Cyclone/OpAny.cpp @@ -5,7 +5,7 @@ int opend_op_changes_cycles, opend_check_interrupt, opend_check_trace; static unsigned char OpData[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -static unsigned short CPU_CALL OpRead16(unsigned int a) +static unsigned short OpRead16(unsigned int a) { return (unsigned short)( (OpData[a&15]<<8) | OpData[(a+1)&15] ); } diff --git a/platform/base_readme.txt b/platform/base_readme.txt index 9cedf35d..7f284bd5 100644 --- a/platform/base_readme.txt +++ b/platform/base_readme.txt @@ -38,6 +38,7 @@ If you have any problems (game does not boot, sound is glitchy, broken graphics) make sure you enable "Accurate timing", "Emulate Z80" and use "16bit accurate renderer". This way you will get the best compatibility this emulator can provide. +For possible Sega/Mega CD problems, see "Other important stuff" section below. How to run Sega/Mega CD games diff --git a/platform/common/emu.h b/platform/common/emu.h index f8261575..34c6f01b 100644 --- a/platform/common/emu.h +++ b/platform/common/emu.h @@ -20,7 +20,9 @@ typedef struct { int JoyBinds[4][32]; int PicoAutoRgnOrder; int PicoCDBuffers; - int scaling; // 0=center, 1=hscale, 2=hvscale, 3=hsoftscale + int scaling; // gp2x: 0=center, 1=hscale, 2=hvscale, 3=hsoftscale; psp: bilinear filtering + float scale; // psp: screen scale + float hscale32, hscale40; // psp: horizontal scale } currentConfig_t; diff --git a/platform/common/menu.h b/platform/common/menu.h index cbf0d856..cd7fa446 100644 --- a/platform/common/menu.h +++ b/platform/common/menu.h @@ -47,6 +47,7 @@ typedef enum MA_OPT_CPU_CLOCKS, MA_OPT_SCD_OPTS, MA_OPT_ADV_OPTS, + MA_OPT_DISP_OPTS, /* psp */ MA_OPT_SAVECFG, MA_OPT_SAVECFG_GAME, MA_OPT_LOADCFG, @@ -63,6 +64,13 @@ typedef enum MA_OPT2_RAMTIMINGS, /* gp2x */ MA_OPT2_SQUIDGEHACK, /* gp2x */ MA_OPT2_DONE, + MA_OPT3_SCALE, /* psp (all OPT3) */ + MA_OPT3_HSCALE32, + MA_OPT3_HSCALE40, + MA_OPT3_PRES_NOSCALE, + MA_OPT3_PRES_FULLSCR, + MA_OPT3_FILTERING, + MA_OPT3_DONE, MA_CDOPT_TESTBIOS_USA, MA_CDOPT_TESTBIOS_EUR, MA_CDOPT_TESTBIOS_JAP, diff --git a/platform/gizmondo/port_config.h b/platform/gizmondo/port_config.h index 3bf29f76..f07e929d 100644 --- a/platform/gizmondo/port_config.h +++ b/platform/gizmondo/port_config.h @@ -3,8 +3,6 @@ #ifndef PORT_CONFIG_H #define PORT_CONFIG_H -#define CPU_CALL - // draw.c #define OVERRIDE_HIGHCOL 1 diff --git a/platform/gp2x/port_config.h b/platform/gp2x/port_config.h index dcd50326..f097a4a9 100644 --- a/platform/gp2x/port_config.h +++ b/platform/gp2x/port_config.h @@ -3,8 +3,6 @@ #ifndef PORT_CONFIG_H #define PORT_CONFIG_H -#define CPU_CALL - // draw.c #define OVERRIDE_HIGHCOL 0 diff --git a/platform/linux/port_config.h b/platform/linux/port_config.h index 0d439c49..9af5d3d2 100644 --- a/platform/linux/port_config.h +++ b/platform/linux/port_config.h @@ -3,7 +3,6 @@ #ifndef PORT_CONFIG_H #define PORT_CONFIG_H -#define CPU_CALL #define NO_SYNC // draw2.c diff --git a/platform/psp/Makefile b/platform/psp/Makefile index 7a0cadae..db032d83 100644 --- a/platform/psp/Makefile +++ b/platform/psp/Makefile @@ -11,9 +11,9 @@ amalgamate = 0 CFLAGS += -I../.. -I. -D_UNZIP_SUPPORT -DNO_SYNC # -DBENCHMARK -CFLAGS += -Wall -Winline +CFLAGS += -Wall -Winline -G0 ifeq ($(DEBUG),) -CFLAGS += -O2 -G0 -ftracer -fstrength-reduce -ffast-math +CFLAGS += -O2 -ftracer -fstrength-reduce -ffast-math else CFLAGS += -ggdb endif @@ -52,7 +52,8 @@ OBJS += ../../Pico/sound/mix.o OBJS += ../../Pico/sound/sn76496.o ../../Pico/sound/ym2612.o # zlib (hacked) OBJS += ../../zlib/gzio.o ../../zlib/inffast.o ../../zlib/inflate.o ../../zlib/inftrees.o ../../zlib/trees.o \ - ../../zlib/deflate.o ../../zlib/crc32.o ../../zlib/adler32.o ../../zlib/zutil.o ../../zlib/compress.o + ../../zlib/deflate.o ../../zlib/crc32.o ../../zlib/adler32.o ../../zlib/zutil.o ../../zlib/compress.o \ + ../../zlib/uncompr.o # unzip OBJS += ../../unzip/unzip.o ../../unzip/unzip_stream.o # CPU cores @@ -70,6 +71,8 @@ OBJS += ../../cpu/mz80/mz80.o else $(error nothing here!) endif +# bg images +OBJS += data/bg32.o data/bg40.o LIBS += -lpng -lm -lpspgu -lpsppower -Wl,-Map=PicoDrive.map # -lpspaudio -lpsphprm @@ -109,7 +112,13 @@ readme.txt: ../../tools/textfilter ../base_readme.txt @echo ">>>" $< $(CC) $(CFLAGS) -Wno-unused -c $< -o $@ -# ? +data/bg32.o: data/bg32.bin + bin2o -i $< $@ bgdatac32 + +data/bg40.o: data/bg40.bin + bin2o -i $< $@ bgdatac40 + +# up: EBOOT.PBP @cp -v $^ /media/disk/PSP/GAME/PicoDrive/ diff --git a/platform/psp/data/bg32.bin b/platform/psp/data/bg32.bin new file mode 100644 index 00000000..e887b124 Binary files /dev/null and b/platform/psp/data/bg32.bin differ diff --git a/platform/psp/data/bg40.bin b/platform/psp/data/bg40.bin new file mode 100644 index 00000000..73fe6666 Binary files /dev/null and b/platform/psp/data/bg40.bin differ diff --git a/platform/psp/emu.c b/platform/psp/emu.c index edaf26ab..8542a8fb 100644 --- a/platform/psp/emu.c +++ b/platform/psp/emu.c @@ -15,9 +15,9 @@ #include "../../Pico/PicoInt.h" #ifdef BENCHMARK -#define OSD_FPS_X 220 +#define OSD_FPS_X 380 #else -#define OSD_FPS_X 260 +#define OSD_FPS_X 420 #endif char romFileName[PATH_MAX]; @@ -29,7 +29,7 @@ static unsigned int noticeMsgTime = 0; int reset_timing = 0; // do we need this? -static void blit(const char *fps, const char *notice); +static void blit2(const char *fps, const char *notice); static void clearArea(int full); void emu_noticeMsgUpdated(void) @@ -42,24 +42,31 @@ void emu_getMainDir(char *dst, int len) if (len > 0) *dst = 0; } -static void emu_msg_cb(const char *msg) +static void osd_text(int x, const char *text, int is_active) { - void *fb = psp_video_get_active_fb(); + unsigned short *screen = is_active ? psp_video_get_active_fb() : psp_screen; + int len = strlen(text) * 8 / 2; + int *p, h; + void *tmp; + for (h = 0; h < 8; h++) { + p = (int *) (screen+x+512*(264+h)); + p = (int *) ((int)p & ~3); // align + memset32(p, 0, len); + } + if (is_active) { tmp = psp_screen; psp_screen = screen; } // nasty pointer tricks + emu_textOut16(x, 264, text); + if (is_active) psp_screen = tmp; +} - memset32((int *)((char *)fb + 512*264*2), 0, 512*8*2/4); - emu_textOut16(4, 264, msg); +void emu_msg_cb(const char *msg) +{ + osd_text(4, msg, 1); noticeMsgTime = sceKernelGetSystemTimeLow() - 2000000; /* assumption: emu_msg_cb gets called only when something slow is about to happen */ reset_timing = 1; } -void emu_stateCb(const char *str) -{ - clearArea(0); - blit("", str); -} - static void emu_msg_tray_open(void) { strcpy(noticeMsg, "CD tray opened"); @@ -126,15 +133,15 @@ void emu_setDefaultConfig(void) currentConfig.KeyBinds[13] = 1<<5; currentConfig.KeyBinds[15] = 1<<6; currentConfig.KeyBinds[ 3] = 1<<7; - currentConfig.KeyBinds[23] = 1<<26; // switch rend currentConfig.KeyBinds[ 8] = 1<<27; // save state currentConfig.KeyBinds[ 9] = 1<<28; // load state currentConfig.PicoCDBuffers = 0; - currentConfig.scaling = 0; + currentConfig.scaling = 1; // bilinear filtering for psp + currentConfig.scale = currentConfig.hscale32 = currentConfig.hscale40 = 1.0; } -static unsigned short __attribute__((aligned(16))) localPal[0x100]; +extern void amips_clut(unsigned short *dst, unsigned char *src, unsigned short *pal, int count); struct Vertex { @@ -142,129 +149,200 @@ struct Vertex short x,y,z; }; -static void EmuScanPrepare(void) +static struct Vertex __attribute__((aligned(4))) g_vertices[2]; +static unsigned short __attribute__((aligned(16))) localPal[0x100]; +static int dynamic_palette = 0, need_pal_upload = 0, blit_16bit_mode = 0; +static int fbimg_offs = 0; + +static void set_scaling_params(void) { - HighCol = VRAM_STUFF; + int src_width, fbimg_width, fbimg_height, fbimg_xoffs, fbimg_yoffs; + g_vertices[0].x = g_vertices[0].y = + g_vertices[0].z = g_vertices[1].z = 0; + + fbimg_height = (int)(240.0 * currentConfig.scale + 0.5); + if (Pico.video.reg[12] & 1) { + fbimg_width = (int)(320.0 * currentConfig.scale * currentConfig.hscale40 + 0.5); + src_width = 320; + } else { + fbimg_width = (int)(256.0 * currentConfig.scale * currentConfig.hscale32 + 0.5); + src_width = 256; + } -#if 0 - sceGuSync(0,0); // sync with prev - sceGuStart(GU_DIRECT, guCmdList); -// sceGuDispBuffer(480, 272, psp_screen == VRAM_FB0 ? VRAMOFFS_FB1 : VRAMOFFS_FB0, 512); - sceGuDrawBuffer(GU_PSM_5650, psp_screen == VRAM_FB0 ? VRAMOFFS_FB0 : VRAMOFFS_FB1, 512); // point to back fb? - sceGuFinish(); -#endif + if (fbimg_width >= 480) { + g_vertices[0].u = (fbimg_width-480)/2; + g_vertices[1].u = src_width - (fbimg_width-480)/2; + fbimg_width = 480; + fbimg_xoffs = 0; + } else { + g_vertices[0].u = 0; + g_vertices[1].u = src_width; + fbimg_xoffs = 240 - fbimg_width/2; + } + + if (fbimg_height >= 272) { + g_vertices[0].v = (fbimg_height-272)/2; + g_vertices[1].v = 240 - (fbimg_height-272)/2; + fbimg_height = 272; + fbimg_yoffs = 0; + } else { + g_vertices[0].v = 0; + g_vertices[1].v = 240; + fbimg_yoffs = 136 - fbimg_height/2; + } + + g_vertices[1].x = fbimg_width; + g_vertices[1].y = fbimg_height; + if (fbimg_xoffs < 0) fbimg_xoffs = 0; + if (fbimg_yoffs < 0) fbimg_yoffs = 0; + fbimg_offs = (fbimg_yoffs*512 + fbimg_xoffs) * 2; // dst is always 16bit + + lprintf("set_scaling_params:\n"); + lprintf("offs: %i, %i\n", fbimg_xoffs, fbimg_yoffs); + lprintf("xy0, xy1: %i, %i; %i, %i\n", g_vertices[0].x, g_vertices[0].y, g_vertices[1].x, g_vertices[1].y); + lprintf("uv0, uv1: %i, %i; %i, %i\n", g_vertices[0].u, g_vertices[0].v, g_vertices[1].u, g_vertices[1].v); } -static int EmuScan16(unsigned int num, void *sdata) +static void do_slowmode_pal(void) { -// struct Vertex* vertices; - - if (!(Pico.video.reg[1]&8)) num += 8; - //DrawLineDest = (unsigned short *) psp_screen + 512*(num+1); - HighCol = (unsigned char *)psp_screen + num*512; + unsigned int *spal=(void *)Pico.cram; + unsigned int *dpal=(void *)localPal; + int i; -#if 0 - sceGuSync(0,0); // sync with prev - sceGuStart(GU_DIRECT, guCmdList); + for (i = 0x3f/2; i >= 0; i--) + dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4); - if (Pico.m.dirtyPal) { - int i, *dpal = (void *)localPal, *spal = (int *)Pico.cram; - Pico.m.dirtyPal = 0; + if (Pico.video.reg[0xC]&8) // shadow/hilight? + { + // shadowed pixels for (i = 0x3f/2; i >= 0; i--) - dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4); - - sceGuClutLoad((256/8), localPal); // upload 32*8 entries (256) + dpal[0x20|i] = dpal[0x60|i] = (spal[i]>>1)&0x738e738e; + // hilighted pixels + for (i = 0x3f; i >= 0; i--) { + int t=localPal[i]&0xe71c;t+=0x4208; + if (t&0x20) t|=0x1c; + if (t&0x800) t|=0x700; + if (t&0x10000) t|=0xe000; + t&=0xe71c; + localPal[0x80|i]=(unsigned short)t; + } + localPal[0xe0] = 0; } + Pico.m.dirtyPal = 0; + need_pal_upload = 1; +} - // setup CLUT texture +static void do_slowmode_lines(int line_to) +{ + int line = 0, line_len = (Pico.video.reg[12]&1) ? 320 : 256; + unsigned short *dst = (unsigned short *)VRAM_STUFF + 512*240/2; + unsigned char *src = (unsigned char *)VRAM_CACHED_STUFF + 16; + if (!(Pico.video.reg[1]&8)) { line = 8; dst += 512*8; src += 512*8; } -// sceGuClutMode(GU_PSM_5650,0,0xff,0); -// sceGuClutLoad((256/8), localPal); // upload 32*8 entries (256) -// sceGuTexMode(GU_PSM_T8,0,0,0); // 8-bit image -// sceGuTexImage(0,512,1/*512*/,512,VRAM_STUFF); -// sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGB); -// sceGuTexFilter(GU_LINEAR,GU_LINEAR); -// sceGuTexScale(1.0f,1.0f); -// sceGuTexOffset(0.0f,0.0f); -// sceGuAmbientColor(0xffffffff); + for (; line < line_to; line++, dst+=512, src+=512) + amips_clut(dst, src, localPal, line_len); +} - // render sprite +static void EmuScanPrepare(void) +{ + HighCol = (unsigned char *)VRAM_CACHED_STUFF + 8; + if (!(Pico.video.reg[1]&8)) HighCol += 8*512; -// sceGuColor(0xffffffff); - vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); - vertices[0].u = 0; vertices[0].v = 0; - vertices[0].x = 0; vertices[0].y = num; vertices[0].z = 0; - vertices[1].u = 320; vertices[1].v = 512; - vertices[1].x = 320; vertices[1].y = num+1; vertices[1].z = 0; - //sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices); + dynamic_palette = 0; + if (Pico.m.dirtyPal) + do_slowmode_pal(); +} + +static int EmuScanSlow(unsigned int num, void *sdata) +{ + if (!(Pico.video.reg[1]&8)) num += 8; + + if (Pico.m.dirtyPal) { + if (!dynamic_palette) { + do_slowmode_lines(num); + dynamic_palette = 1; + } + do_slowmode_pal(); + } + + if (dynamic_palette) { + int line_len = (Pico.video.reg[12]&1) ? 320 : 256; + void *dst = (char *)VRAM_STUFF + 512*240 + 512*2*num; + amips_clut(dst, HighCol + 8, localPal, line_len); + } else + HighCol = (unsigned char *)VRAM_CACHED_STUFF + (num+1)*512 + 8; - sceGuFinish(); -#endif return 0; } - -static void draw2_clut(void) +static void blitscreen_clut(void) { - struct Vertex* vertices; - int x; + int offs = fbimg_offs; + offs += (psp_screen == VRAM_FB0) ? VRAMOFFS_FB0 : VRAMOFFS_FB1; - sceKernelDcacheWritebackAll(); // for PicoDraw2FB + sceKernelDcacheWritebackAll(); sceGuSync(0,0); // sync with prev sceGuStart(GU_DIRECT, guCmdList); -// sceGuDispBuffer(480, 272, psp_screen == VRAM_FB0 ? VRAMOFFS_FB1 : VRAMOFFS_FB0, 512); - sceGuDrawBuffer(GU_PSM_5650, psp_screen == VRAM_FB0 ? VRAMOFFS_FB0 : VRAMOFFS_FB1, 512); // point to back fb? + sceGuDrawBuffer(GU_PSM_5650, (void *)offs, 512); // point to back buffer - if (Pico.m.dirtyPal) { - int i, *dpal = (void *)localPal, *spal = (int *)Pico.cram; - Pico.m.dirtyPal = 0; - for (i = 0x3f/2; i >= 0; i--) - dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4); + if (dynamic_palette) + { + if (!blit_16bit_mode) { + sceGuTexMode(GU_PSM_5650, 0, 0, 0); + sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 512*240); - sceGuClutLoad((256/8), localPal); // upload 32*8 entries (256) + blit_16bit_mode = 1; + } } - - #define SLICE_WIDTH 32 - - for (x = 0; x < 320; x += SLICE_WIDTH) + else { - // render sprite - vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); - vertices[0].u = vertices[0].x = x; - vertices[0].v = vertices[0].y = 0; - vertices[0].z = 0; - vertices[1].u = vertices[1].x = x + SLICE_WIDTH; - vertices[1].v = vertices[1].y = 224; - vertices[1].z = 0; - sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices); - } - - sceGuFinish(); -} - + if (blit_16bit_mode) { + sceGuClutMode(GU_PSM_5650,0,0xff,0); + sceGuTexMode(GU_PSM_T8,0,0,0); // 8-bit image + sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 16); + blit_16bit_mode = 0; + } + if ((PicoOpt&0x10) && Pico.m.dirtyPal) + { + int i, *dpal = (void *)localPal, *spal = (int *)Pico.cram; + for (i = 0x3f/2; i >= 0; i--) + dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4); + localPal[0xe0] = 0; + Pico.m.dirtyPal = 0; + need_pal_upload = 1; + } -static int EmuScan8(unsigned int num, void *sdata) -{ - // draw like the fast renderer - // TODO? - //if (!(Pico.video.reg[1]&8)) num += 8; - //HighCol = gfx_buffer + 328*(num+1); + if (need_pal_upload) { + need_pal_upload = 0; + sceGuClutLoad((256/8), localPal); // upload 32*8 entries (256) + } + } - return 0; -} +#if 1 + if (g_vertices[0].u == 0 && g_vertices[1].u == g_vertices[1].x) + { + struct Vertex* vertices; + int x; -static void osd_text(int x, const char *text) -{ - int len = strlen(text) * 8 / 2; - int *p, h; - for (h = 0; h < 8; h++) { - p = (int *) ((unsigned short *) psp_screen+x+512*(264+h)); - p = (int *) ((int)p & ~3); // align - memset32(p, 0, len); + #define SLICE_WIDTH 32 + for (x = 0; x < g_vertices[1].x; x += SLICE_WIDTH) + { + // render sprite + vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); + memcpy(vertices, g_vertices, 2 * sizeof(struct Vertex)); + vertices[0].u = vertices[0].x = x; + vertices[1].u = vertices[1].x = x + SLICE_WIDTH; + sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices); + } + // lprintf("listlen: %iB\n", sceGuCheckList()); // ~480 only } - emu_textOut16(x, 264, text); + else +#endif + sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,g_vertices); + + sceGuFinish(); } @@ -285,75 +363,56 @@ static void cd_leds(void) } -static void blit(const char *fps, const char *notice) +static void dbg_text(void) { - int emu_opt = currentConfig.EmuOpt; + int *p, h, len; + char text[128]; - if (PicoOpt&0x10) - { -#if 1 - draw2_clut(); -#else - extern void amips_clut(unsigned short *dst, unsigned char *src, unsigned short *pal, int count); - int i; // , lines_flags = 224; - unsigned short *pd = psp_screen; - unsigned char *ps = PicoDraw2FB+328*8+8; - // 8bit fast renderer - if (Pico.m.dirtyPal) { - int *dpal = (void *)localPal; - int *spal = (int *)Pico.cram; - Pico.m.dirtyPal = 0; - for (i = 0x3f/2; i >= 0; i--) - dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4); - } - // if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000; - // if (currentConfig.EmuOpt&0x4000) - // lines_flags|=0x40000; // (Pico.m.frame_count&1)?0x20000:0x40000; - //vidCpy8to16((unsigned short *)giz_screen+321*8, PicoDraw2FB+328*8, localPal, lines_flags); - for (i = 224; i > 0; i--, pd+=512, ps+=328) - amips_clut(pd, ps, localPal, 320); -#endif + sprintf(text, "sl: %i, 16b: %i", g_vertices[0].u == 0 && g_vertices[1].u == g_vertices[1].x, blit_16bit_mode); + len = strlen(text) * 8 / 2; + for (h = 0; h < 8; h++) { + p = (int *) ((unsigned short *) psp_screen+2+512*(256+h)); + p = (int *) ((int)p & ~3); // align + memset32(p, 0, len); } -#if 0 - else if (!(emu_opt&0x80)) + emu_textOut16(2, 256, text); +} + + +/* called after rendering is done, but frame emulation is not finished */ +void blit1(void) +{ + if (PicoOpt&0x10) { - int lines_flags; - // 8bit accurate renderer - if (Pico.m.dirtyPal) { - Pico.m.dirtyPal = 0; - vidConvCpyRGB565(localPal, Pico.cram, 0x40); - if (Pico.video.reg[0xC]&8) { // shadow/hilight mode - //vidConvCpyRGB32sh(localPal+0x40, Pico.cram, 0x40); - //vidConvCpyRGB32hi(localPal+0x80, Pico.cram, 0x40); // TODO? - blockcpy(localPal+0xc0, localPal+0x40, 0x40*2); - localPal[0xc0] = 0x0600; - localPal[0xd0] = 0xc000; - localPal[0xe0] = 0x0000; // reserved pixels for OSD - localPal[0xf0] = 0xffff; - } - /* no support - else if (rendstatus & 0x20) { // mid-frame palette changes - vidConvCpyRGB565(localPal+0x40, HighPal, 0x40); - vidConvCpyRGB565(localPal+0x80, HighPal+0x40, 0x40); - } */ - } - lines_flags = (Pico.video.reg[1]&8) ? 240 : 224; - if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000; - if (currentConfig.EmuOpt&0x4000) - lines_flags|=0x40000; // (Pico.m.frame_count&1)?0x20000:0x40000; - vidCpy8to16((unsigned short *)giz_screen+321*8, PicoDraw2FB+328*8, localPal, lines_flags); + int i; + unsigned char *pd; + // clear top and bottom trash + for (pd = PicoDraw2FB+8, i = 8; i > 0; i--, pd += 512) + memset32((int *)pd, 0xe0e0e0e0, 320/4); + for (pd = PicoDraw2FB+512*232+8, i = 8; i > 0; i--, pd += 512) + memset32((int *)pd, 0xe0e0e0e0, 320/4); } -#endif + + blitscreen_clut(); +} + + +static void blit2(const char *fps, const char *notice) +{ + int emu_opt = currentConfig.EmuOpt; + + sceGuSync(0,0); if (notice || (emu_opt & 2)) { - if (notice) osd_text(4, notice); - if (emu_opt & 2) osd_text(OSD_FPS_X, fps); + if (notice) osd_text(4, notice, 0); + if (emu_opt & 2) osd_text(OSD_FPS_X, fps, 0); } + dbg_text(); + if ((emu_opt & 0x400) && (PicoMCD & 1)) cd_leds(); - sceGuSync(0,0); psp_video_flip(0); } @@ -364,6 +423,8 @@ static void clearArea(int full) memset32(psp_screen, 0, 512*272*2/4); psp_video_flip(0); memset32(psp_screen, 0, 512*272*2/4); + memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*240/4); + memset32((int *)VRAM_CACHED_STUFF+512*240/4, 0, 512*240*2/4); } else { void *fb = psp_video_get_active_fb(); memset32((int *)((char *)psp_screen + 512*264*2), 0, 512*8*2/4); @@ -378,43 +439,29 @@ static void vidResetMode(void) sceGuStart(GU_DIRECT, guCmdList); sceGuClutMode(GU_PSM_5650,0,0xff,0); - //sceGuClutLoad((256/8), localPal); // upload 32*8 entries (256) sceGuTexMode(GU_PSM_T8,0,0,0); // 8-bit image sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGB); - sceGuTexFilter(GU_LINEAR,GU_LINEAR); + if (currentConfig.scaling) + sceGuTexFilter(GU_LINEAR, GU_LINEAR); + else sceGuTexFilter(GU_NEAREST, GU_NEAREST); sceGuTexScale(1.0f,1.0f); sceGuTexOffset(0.0f,0.0f); - sceGuAmbientColor(0xffffffff); - sceGuColor(0xffffffff); - - if (PicoOpt&0x10) { - sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 8*512+16); + sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 16); - } else if (currentConfig.EmuOpt&0x80) { - PicoDrawSetColorFormat(/*1*/-1); - PicoScan = EmuScan16; + // slow rend. + PicoDrawSetColorFormat(-1); + PicoScan = EmuScanSlow; - sceGuTexImage(0,512,1/*512*/,512,VRAM_STUFF); - - } else { - PicoDrawSetColorFormat(-1); - PicoScan = EmuScan8; - } - if ((PicoOpt&0x10) || !(currentConfig.EmuOpt&0x80)) { - // setup pal for 8-bit modes - localPal[0xc0] = 0x0600; - localPal[0xd0] = 0xc000; - localPal[0xe0] = 0x0000; // reserved pixels for OSD - localPal[0xf0] = 0xffff; - } + localPal[0xe0] = 0; Pico.m.dirtyPal = 1; + blit_16bit_mode = dynamic_palette = 0; sceGuFinish(); + set_scaling_params(); sceGuSync(0,0); - - clearArea(1); } + /* static void updateSound(int len) { @@ -440,11 +487,16 @@ void emu_forcedFrame(void) PicoOpt |= 0x4080; // soft_scale | acc_sprites currentConfig.EmuOpt |= 0x80; - PicoDrawSetColorFormat(1); - PicoScan = EmuScan16; + vidResetMode(); + memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*8/4); // borders + memset32((int *)VRAM_CACHED_STUFF + 512*232/4, 0xe0e0e0e0, 512*8/4); + + PicoDrawSetColorFormat(-1); + PicoScan = EmuScanSlow; EmuScanPrepare(); - Pico.m.dirtyPal = 1; PicoFrameDrawOnly(); + blit1(); + sceGuSync(0,0); PicoOpt = po_old; currentConfig.EmuOpt = eo_old; @@ -462,7 +514,7 @@ static void RunEvents(unsigned int which) (!(which & 0x1000) && (currentConfig.EmuOpt & 0x200))) ) // save { int keys; - blit("", (which & 0x1000) ? "LOAD STATE? (X=yes, O=no)" : "OVERWRITE SAVE? (X=yes, O=no)"); + blit2("", (which & 0x1000) ? "LOAD STATE? (X=yes, O=no)" : "OVERWRITE SAVE? (X=yes, O=no)"); while( !((keys = psp_pad_read(1)) & (BTN_X|BTN_CIRCLE)) ) psp_msleep(50); if (keys & BTN_CIRCLE) do_it = 0; @@ -473,8 +525,8 @@ static void RunEvents(unsigned int which) if (do_it) { - osd_text(4, (which & 0x1000) ? "LOADING GAME" : "SAVING GAME"); - PicoStateProgressCB = emu_stateCb; + osd_text(4, (which & 0x1000) ? "LOADING GAME" : "SAVING GAME", 1); + PicoStateProgressCB = emu_msg_cb; emu_SaveLoadGame((which & 0x1000) >> 12, 0); PicoStateProgressCB = NULL; psp_msleep(0); @@ -644,6 +696,7 @@ void emu_Loop(void) // make sure we are in correct mode vidResetMode(); + clearArea(1); Pico.m.dirtyPal = 1; oldmodes = ((Pico.video.reg[12]&1)<<2) ^ 0xc; find_combos(); @@ -721,6 +774,7 @@ void emu_Loop(void) if (modes != oldmodes) { oldmodes = modes; clearArea(1); + set_scaling_params(); } // second passed? @@ -798,7 +852,7 @@ void emu_Loop(void) PicoFrame(); - blit(fpsbuff, notice); + blit2(fpsbuff, notice); // check time tval = sceKernelGetSystemTimeLow(); @@ -829,7 +883,7 @@ void emu_Loop(void) */ // save SRAM if ((currentConfig.EmuOpt & 1) && SRam.changed) { - emu_stateCb("Writing SRAM/BRAM.."); + emu_msg_cb("Writing SRAM/BRAM.."); emu_SaveLoadGame(0, 1); SRam.changed = 0; } diff --git a/platform/psp/emu.h b/platform/psp/emu.h index 48ce9a3c..d122a20d 100644 --- a/platform/psp/emu.h +++ b/platform/psp/emu.h @@ -26,6 +26,6 @@ void emu_Loop(void); void emu_ResetGame(void); void emu_forcedFrame(void); -void emu_stateCb(const char *str); +void emu_msg_cb(const char *msg); diff --git a/platform/psp/menu.c b/platform/psp/menu.c index 1f3c6ea3..27cb28aa 100644 --- a/platform/psp/menu.c +++ b/platform/psp/menu.c @@ -6,7 +6,6 @@ // don't like to use loads of #ifdefs, so duplicating GP2X code // horribly instead -//#include #include #include #include @@ -16,6 +15,7 @@ #include #include #include +#include #include "psp.h" #include "emu.h" @@ -39,11 +39,11 @@ static const char * const pspKeyNames[] = { pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, pspKeyUnkn }; -static unsigned char bg_buffer[480*272*2] __attribute__((aligned(16))); // TODO: move to vram? +static unsigned short bg_buffer[480*272] __attribute__((aligned(16))); #define menu_screen psp_screen static void menu_darken_bg(void *dst, const void *src, int pixels, int darker); -static void menu_prepare_bg(int use_game_bg); +static void menu_prepare_bg(int use_game_bg, int use_back_buff); static unsigned int inp_prev = 0; @@ -495,24 +495,38 @@ static void state_check_slots(void) } } +static void *get_oldstate_for_preview(void) +{ + unsigned char *ptr = malloc(sizeof(Pico.vram) + sizeof(Pico.cram) + sizeof(Pico.vsram) + sizeof(Pico.video)); + if (ptr == NULL) return NULL; + + memcpy(ptr, Pico.vram, sizeof(Pico.vram)); + memcpy(ptr + sizeof(Pico.vram), Pico.cram, sizeof(Pico.cram)); + memcpy(ptr + sizeof(Pico.vram) + sizeof(Pico.cram), Pico.vsram, sizeof(Pico.vsram)); + memcpy(ptr + sizeof(Pico.vram) + sizeof(Pico.cram) + sizeof(Pico.vsram), &Pico.video, sizeof(Pico.video)); + return ptr; +} + +static void restore_oldstate(void *ptrx) +{ + unsigned char *ptr = ptrx; + memcpy(Pico.vram, ptr, sizeof(Pico.vram)); + memcpy(Pico.cram, ptr + sizeof(Pico.vram), sizeof(Pico.cram)); + memcpy(Pico.vsram, ptr + sizeof(Pico.vram) + sizeof(Pico.cram), sizeof(Pico.vsram)); + memcpy(&Pico.video,ptr + sizeof(Pico.vram) + sizeof(Pico.cram) + sizeof(Pico.vsram), sizeof(Pico.video)); + free(ptrx); +} + static void draw_savestate_bg(int slot) { - struct PicoVideo tmp_pv; - unsigned short tmp_cram[0x40]; - unsigned short tmp_vsram[0x40]; - void *tmp_vram, *file; + void *file, *oldstate; char *fname; fname = emu_GetSaveFName(1, 0, slot); if (!fname) return; - tmp_vram = malloc(sizeof(Pico.vram)); - if (tmp_vram == NULL) return; - - memcpy(tmp_vram, Pico.vram, sizeof(Pico.vram)); - memcpy(tmp_cram, Pico.cram, sizeof(Pico.cram)); - memcpy(tmp_vsram, Pico.vsram, sizeof(Pico.vsram)); - memcpy(&tmp_pv, &Pico.video, sizeof(Pico.video)); + oldstate = get_oldstate_for_preview(); + if (oldstate == NULL) return; if (strcmp(fname + strlen(fname) - 3, ".gz") == 0) { file = gzopen(fname, "rb"); @@ -538,13 +552,9 @@ static void draw_savestate_bg(int slot) } emu_forcedFrame(); - menu_prepare_bg(1); + menu_prepare_bg(1, 1); - memcpy(Pico.vram, tmp_vram, sizeof(Pico.vram)); - memcpy(Pico.cram, tmp_cram, sizeof(Pico.cram)); - memcpy(Pico.vsram, tmp_vsram, sizeof(Pico.vsram)); - memcpy(&Pico.video, &tmp_pv, sizeof(Pico.video)); - free(tmp_vram); + restore_oldstate(oldstate); } static void draw_savestate_menu(int menu_sel, int is_loading) @@ -595,7 +605,7 @@ static int savestate_menu_loop(int is_loading) if(inp & BTN_X) { // save/load if (menu_sel < 10) { state_slot = menu_sel; - PicoStateProgressCB = emu_stateCb; /* also suitable for menu */ + PicoStateProgressCB = emu_msg_cb; /* also suitable for menu */ if (emu_SaveLoadGame(is_loading, 0)) { strcpy(menuErrorMsg, is_loading ? "Load failed" : "Save failed"); return 1; @@ -944,6 +954,150 @@ static void cd_menu_loop_options(void) } } +// --------- display options ---------- + +menu_entry opt3_entries[] = +{ + { NULL, MB_NONE, MA_OPT3_SCALE, NULL, 0, 0, 0, 1 }, + { NULL, MB_NONE, MA_OPT3_HSCALE32, NULL, 0, 0, 0, 1 }, + { NULL, MB_NONE, MA_OPT3_HSCALE40, NULL, 0, 0, 0, 1 }, + { NULL, MB_ONOFF, MA_OPT3_FILTERING, ¤tConfig.scaling, 1, 0, 0, 1 }, + { "Set to unscaled centered", MB_NONE, MA_OPT3_PRES_NOSCALE, NULL, 0, 0, 0, 1 }, + { "Set to fullscreen", MB_NONE, MA_OPT3_PRES_FULLSCR, NULL, 0, 0, 0, 1 }, + { "done", MB_NONE, MA_OPT3_DONE, NULL, 0, 0, 0, 1 }, +}; + +#define OPT3_ENTRY_COUNT (sizeof(opt3_entries) / sizeof(opt3_entries[0])) + + +static void menu_opt3_cust_draw(const menu_entry *entry, int x, int y, void *param) +{ + switch (entry->id) + { + case MA_OPT3_SCALE: + text_out16(x, y, "Scale factor: %.2f", currentConfig.scale); + break; + case MA_OPT3_HSCALE32: + text_out16(x, y, "Hor. scale (for low res. games): %.2f", currentConfig.hscale32); + break; + case MA_OPT3_HSCALE40: + text_out16(x, y, "Hor. scale (for hi res. games): %.2f", currentConfig.hscale40); + break; + case MA_OPT3_FILTERING: + text_out16(x, y, "Bilinear filtering %s", currentConfig.scaling?"ON":"OFF"); + break; + default: break; + } +} + +static void menu_opt3_preview(int is_32col) +{ + void *oldstate = NULL; + + if (rom_data == NULL || ((Pico.video.reg[12]&1)^1) != is_32col) + { + extern char bgdatac32_start[], bgdatac40_start[]; + extern int bgdatac32_size, bgdatac40_size; + void *bgdata = is_32col ? bgdatac32_start : bgdatac40_start; + unsigned long insize = is_32col ? bgdatac32_size : bgdatac40_size, outsize = 65856; + int ret; + lprintf("%p %p %i %i (n %p)\n", bgdatac32_start, bgdatac40_start, bgdatac32_size, bgdatac40_size, &engineState); + ret = uncompress((Bytef *)bg_buffer, &outsize, bgdata, insize); + if (ret == 0) + { + if (rom_data != NULL) oldstate = get_oldstate_for_preview(); + memcpy(Pico.vram, bg_buffer, sizeof(Pico.vram)); + memcpy(Pico.cram, (char *)bg_buffer + 0x10000, 0x40*2); + memcpy(Pico.vsram, (char *)bg_buffer + 0x10080, 0x40*2); + memcpy(&Pico.video,(char *)bg_buffer + 0x10100, 0x40); + } + else + lprintf("uncompress returned %i\n", ret); + } + + memset32(psp_screen, 0, 512*272*2/4); + emu_forcedFrame(); + menu_prepare_bg(1, 1); + + if (oldstate) restore_oldstate(oldstate); +} + +static void draw_dispmenu_options(int menu_sel) +{ + int tl_x = 80+25, tl_y = 16+50; + + menu_draw_begin(); + + menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 252); + + me_draw(opt3_entries, OPT3_ENTRY_COUNT, tl_x, tl_y, menu_opt3_cust_draw, NULL); + + menu_draw_end(); +} + +static void dispmenu_loop_options(void) +{ + static int menu_sel = 0; + int menu_sel_max, is_32col = 0; + unsigned long inp = 0; + menu_id selected_id; + + menu_sel_max = me_count_enabled(opt3_entries, OPT3_ENTRY_COUNT) - 1; + + for(;;) + { + draw_dispmenu_options(menu_sel); + inp = wait_for_input(BTN_UP|BTN_DOWN|BTN_LEFT|BTN_RIGHT|BTN_X|BTN_CIRCLE); + if (inp & BTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; } + if (inp & BTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; } + selected_id = me_index2id(opt3_entries, OPT3_ENTRY_COUNT, menu_sel); + if (selected_id == MA_OPT3_HSCALE40 && is_32col) { is_32col = 0; menu_opt3_preview(is_32col); } + if (selected_id == MA_OPT3_HSCALE32 && !is_32col) { is_32col = 1; menu_opt3_preview(is_32col); } + + if (inp & (BTN_LEFT|BTN_RIGHT)) // multi choise + { + float *setting = NULL; + me_process(opt3_entries, OPT3_ENTRY_COUNT, selected_id, (inp&BTN_RIGHT) ? 1 : 0); + switch (selected_id) { + case MA_OPT3_SCALE: setting = ¤tConfig.scale; break; + case MA_OPT3_HSCALE40: setting = ¤tConfig.hscale40; is_32col = 0; break; + case MA_OPT3_HSCALE32: setting = ¤tConfig.hscale32; is_32col = 1; break; + case MA_OPT3_FILTERING:menu_opt3_preview(is_32col); break; + default: break; + } + if (setting != NULL) { + while ((inp = psp_pad_read(0)) & (BTN_LEFT|BTN_RIGHT)) { + *setting += (inp & BTN_LEFT) ? -0.01 : 0.01; + menu_opt3_preview(is_32col); + draw_dispmenu_options(menu_sel); // will wait vsync + } + } + } + if (inp & BTN_X) { // toggleable options + me_process(opt3_entries, OPT3_ENTRY_COUNT, selected_id, 1); + switch (selected_id) { + case MA_OPT3_DONE: + return; + case MA_OPT3_PRES_NOSCALE: + currentConfig.scale = currentConfig.hscale40 = currentConfig.hscale32 = 1.0; + menu_opt3_preview(is_32col); + break; + case MA_OPT3_PRES_FULLSCR: + currentConfig.scale = 1.20; + currentConfig.hscale40 = 1.25; + currentConfig.hscale32 = 1.56; + menu_opt3_preview(is_32col); + break; + case MA_OPT3_FILTERING: + menu_opt3_preview(is_32col); + break; + default: break; + } + } + if (inp & BTN_CIRCLE) return; + } +} + // --------- advanced options ---------- @@ -952,8 +1106,6 @@ menu_entry opt2_entries[] = { "Emulate Z80", MB_ONOFF, MA_OPT2_ENABLE_Z80, ¤tConfig.PicoOpt,0x0004, 0, 0, 1 }, { "Emulate YM2612 (FM)", MB_ONOFF, MA_OPT2_ENABLE_YM2612, ¤tConfig.PicoOpt,0x0001, 0, 0, 1 }, { "Emulate SN76496 (PSG)", MB_ONOFF, MA_OPT2_ENABLE_SN76496,¤tConfig.PicoOpt,0x0002, 0, 0, 1 }, -// { "Double buffering", MB_ONOFF, MA_OPT2_DBLBUFF, ¤tConfig.EmuOpt, 0x8000, 0, 0, 1 }, -// { "Wait for V-sync (slow)", MB_ONOFF, MA_OPT2_VSYNC, ¤tConfig.EmuOpt, 0x2000, 0, 0, 1 }, { "gzip savestates", MB_ONOFF, MA_OPT2_GZIP_STATES, ¤tConfig.EmuOpt, 0x0008, 0, 0, 1 }, { "Don't save last used ROM", MB_ONOFF, MA_OPT2_NO_LAST_ROM, ¤tConfig.EmuOpt, 0x0020, 0, 0, 1 }, { "done", MB_NONE, MA_OPT2_DONE, NULL, 0, 0, 0, 1 }, @@ -994,13 +1146,7 @@ static void amenu_loop_options(void) if (inp & (BTN_LEFT|BTN_RIGHT)) { // multi choise if (!me_process(opt2_entries, OPT2_ENTRY_COUNT, selected_id, (inp&BTN_RIGHT) ? 1 : 0) && selected_id == MA_OPT2_GAMMA) { - while ((inp = psp_pad_read(1)) & (BTN_LEFT|BTN_RIGHT)) { - currentConfig.gamma += (inp & BTN_LEFT) ? -1 : 1; - if (currentConfig.gamma < 1) currentConfig.gamma = 1; - if (currentConfig.gamma > 300) currentConfig.gamma = 300; - draw_amenu_options(menu_sel); - psp_msleep(18); - } + // TODO? } } if (inp & BTN_X) { // toggleable options @@ -1032,8 +1178,9 @@ menu_entry opt_entries[] = { NULL, MB_NONE, MA_OPT_CONFIRM_STATES,NULL, 0, 0, 0, 1 }, { "Save slot", MB_RANGE, MA_OPT_SAVE_SLOT, &state_slot, 0, 0, 9, 1 }, { NULL, MB_NONE, MA_OPT_CPU_CLOCKS, NULL, 0, 0, 0, 1 }, + { "[Display options]", MB_NONE, MA_OPT_DISP_OPTS, NULL, 0, 0, 0, 1 }, { "[Sega/Mega CD options]", MB_NONE, MA_OPT_SCD_OPTS, NULL, 0, 0, 0, 1 }, - { "[advanced options]", MB_NONE, MA_OPT_ADV_OPTS, NULL, 0, 0, 0, 1 }, + { "[Advanced options]", MB_NONE, MA_OPT_ADV_OPTS, NULL, 0, 0, 0, 1 }, { NULL, MB_NONE, MA_OPT_SAVECFG, NULL, 0, 0, 0, 1 }, { "Save cfg for current game only",MB_NONE,MA_OPT_SAVECFG_GAME,NULL, 0, 0, 0, 1 }, { NULL, MB_NONE, MA_OPT_LOADCFG, NULL, 0, 0, 0, 1 }, @@ -1120,7 +1267,6 @@ static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *para } - static void draw_menu_options(int menu_sel) { int tl_x = 80+25, tl_y = 16+24; @@ -1282,6 +1428,9 @@ static int menu_loop_options(void) { switch (selected_id) { + case MA_OPT_DISP_OPTS: + dispmenu_loop_options(); + break; case MA_OPT_SCD_OPTS: cd_menu_loop_options(); if (engineState == PGS_ReloadRom) @@ -1373,10 +1522,8 @@ static void draw_menu_root(int menu_sel) me_draw(main_entries, MAIN_ENTRY_COUNT, tl_x, tl_y, NULL, NULL); // error - if (menuErrorMsg[0]) { - // memset((char *)menu_screen + 321*224*2, 0, 321*16*2); - text_out16(5, 258, menuErrorMsg); - } + if (menuErrorMsg[0]) + text_out16(10, 252, menuErrorMsg); menu_draw_end(); } @@ -1525,29 +1672,30 @@ static void menu_darken_bg(void *dst, const void *src, int pixels, int darker) } } -static void menu_prepare_bg(int use_game_bg) +static void menu_prepare_bg(int use_game_bg, int use_back_buff) { - memset(bg_buffer, 0, sizeof(bg_buffer)); - if (use_game_bg) { // darken the active framebuffer - /* - memset(bg_buffer, 0, 321*8*2); - menu_darken_bg(bg_buffer + 321*8*2, (char *)giz_screen + 321*8*2, 321*224, 1); - memset(bg_buffer + 321*232*2, 0, 321*8*2); - */ + unsigned short *dst = bg_buffer; + unsigned short *src = use_back_buff ? psp_screen : psp_video_get_active_fb(); + int i; + for (i = 272; i > 0; i--, dst += 480, src += 512) + menu_darken_bg(dst, src, 480, 1); + //memset32((int *)(bg_buffer + 480*264), 0, 480*8*2/4); } else { // should really only happen once, on startup.. + memset32((int *)(void *)bg_buffer, 0, sizeof(bg_buffer)/4); readpng(bg_buffer, "skin/background.png", READPNG_BG); } + sceKernelDcacheWritebackAll(); } static void menu_gfx_prepare(void) { - menu_prepare_bg(rom_data != NULL); + menu_prepare_bg(rom_data != NULL, 0); menu_draw_begin(); menu_draw_end(); diff --git a/platform/psp/port_config.h b/platform/psp/port_config.h index 486a877c..6958c1b3 100644 --- a/platform/psp/port_config.h +++ b/platform/psp/port_config.h @@ -3,8 +3,6 @@ #ifndef PORT_CONFIG_H #define PORT_CONFIG_H -#define CPU_CALL - // draw.c #define USE_BGR555 1 #define OVERRIDE_HIGHCOL 1 @@ -15,6 +13,8 @@ #define DRAW2_OVERRIDE_LINE_WIDTH 512 // pico.c +extern void blit1(void); +#define DRAW_FINISH_FUNC blit1 #define CAN_HANDLE_240_LINES 1 // logging emu events diff --git a/platform/psp/psp.c b/platform/psp/psp.c index 8f811f63..84ab5c80 100644 --- a/platform/psp/psp.c +++ b/platform/psp/psp.c @@ -64,34 +64,24 @@ void psp_init(void) sceGuInit(); sceGuStart(GU_DIRECT, guCmdList); - sceGuDrawBuffer(GU_PSM_5650, VRAMOFFS_FB0, 512); // point to back fb? - sceGuDispBuffer(480, 272, VRAMOFFS_FB1, 512); + sceGuDrawBuffer(GU_PSM_5650, (void *)VRAMOFFS_FB0, 512); + sceGuDispBuffer(480, 272, (void *)VRAMOFFS_FB1, 512); // don't care sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT); - sceGuDepthBuffer(VRAMOFFS_DEPTH, 512); + sceGuDepthBuffer((void *)VRAMOFFS_DEPTH, 512); sceGuOffset(2048 - (480 / 2), 2048 - (272 / 2)); sceGuViewport(2048, 2048, 480, 272); sceGuDepthRange(0xc350, 0x2710); sceGuScissor(0, 0, 480, 272); sceGuEnable(GU_SCISSOR_TEST); -// sceGuAlphaFunc(GU_GREATER, 0, 0xff); -// sceGuEnable(GU_ALPHA_TEST); -// sceGuDepthFunc(GU_ALWAYS); // GU_GEQUAL); -// sceGuEnable(GU_DEPTH_TEST); sceGuDepthMask(0xffff); sceGuDisable(GU_DEPTH_TEST); sceGuFrontFace(GU_CW); -// sceGuShadeModel(GU_SMOOTH); -// sceGuEnable(GU_CULL_FACE); sceGuEnable(GU_TEXTURE_2D); -// sceGuEnable(GU_CLIP_PLANES); - sceGuTexMode(GU_PSM_5650, 0, 0, 0); sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); - sceGuTexFilter(GU_NEAREST, GU_NEAREST); -// sceGuAmbientColor(0xffffffff); -// sceGuEnable(GU_BLEND); -// sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuAmbientColor(0xffffffff); + sceGuColor(0xffffffff); sceGuFinish(); sceGuSync(0, 0); diff --git a/platform/psp/psp.h b/platform/psp/psp.h index 03f9db00..8a2828e3 100644 --- a/platform/psp/psp.h +++ b/platform/psp/psp.h @@ -9,19 +9,20 @@ void psp_msleep(int ms); // 000000-044000 fb0 // 044000-088000 fb1 // 088000-0cc000 depth (?) -// 0cc000-0??000 stuff +// 0cc000-126000 emu draw buffers: 512*240 + 512*240*2 -#define VRAMOFFS_FB0 ((void *) 0x00000000) -#define VRAMOFFS_FB1 ((void *) 0x00044000) -#define VRAMOFFS_DEPTH ((void *) 0x00088000) +#define VRAMOFFS_FB0 0x00000000 +#define VRAMOFFS_FB1 0x00044000 +#define VRAMOFFS_DEPTH 0x00088000 +#define VRAMOFFS_STUFF 0x000cc000 -#define VRAM_FB0 ((void *) 0x44000000) -#define VRAM_FB1 ((void *) 0x44044000) -#define VRAM_STUFF ((void *) 0x440cc000) +#define VRAM_FB0 ((void *) (0x44000000+VRAMOFFS_FB0)) +#define VRAM_FB1 ((void *) (0x44000000+VRAMOFFS_FB1)) +#define VRAM_STUFF ((void *) (0x44000000+VRAMOFFS_STUFF)) -#define VRAM_CACHED_STUFF ((void *) 0x040cc000) +#define VRAM_CACHED_STUFF ((void *) (0x04000000+VRAMOFFS_STUFF)) -#define GU_CMDLIST_SIZE (16*1024) // TODO: adjust +#define GU_CMDLIST_SIZE (16*1024) extern unsigned int guCmdList[GU_CMDLIST_SIZE]; @@ -48,5 +49,5 @@ int psp_set_cpu_clock(int clock); #define BTN_SQUARE PSP_CTRL_SQUARE #define BTN_SELECT PSP_CTRL_SELECT #define BTN_START PSP_CTRL_START -#define BTN_NOTE PSP_CTRL_NOTE +#define BTN_NOTE PSP_CTRL_NOTE // doesn't seem to work? diff --git a/platform/uiq2/port_config.h b/platform/uiq2/port_config.h index e5ed140c..6ed28b17 100644 --- a/platform/uiq2/port_config.h +++ b/platform/uiq2/port_config.h @@ -3,8 +3,6 @@ #ifndef PORT_CONFIG_H #define PORT_CONFIG_H -#define CPU_CALL - // draw2.c #define START_ROW 1 // which row of tiles to start rendering at? #define END_ROW 27 // ..end diff --git a/platform/uiq3/port_config.h b/platform/uiq3/port_config.h index 0478ce4b..79f5fdac 100644 --- a/platform/uiq3/port_config.h +++ b/platform/uiq3/port_config.h @@ -3,8 +3,6 @@ #ifndef PORT_CONFIG_H #define PORT_CONFIG_H -#define CPU_CALL - // draw2.c #define START_ROW 0 // which row of tiles to start rendering at? #define END_ROW 28 // ..end diff --git a/platform/win32/GenaDrive/port_config.h b/platform/win32/GenaDrive/port_config.h index 9acc7cd1..fbb21703 100644 --- a/platform/win32/GenaDrive/port_config.h +++ b/platform/win32/GenaDrive/port_config.h @@ -3,8 +3,6 @@ #ifndef PORT_CONFIG_H #define PORT_CONFIG_H -#define CPU_CALL __fastcall - // draw2.c #define START_ROW 0 // which row of tiles to start rendering at? #define END_ROW 28 // ..end diff --git a/tools/mkbgxx.c b/tools/mkbgxx.c new file mode 100644 index 00000000..02b51da5 --- /dev/null +++ b/tools/mkbgxx.c @@ -0,0 +1,43 @@ +#include +#include + +static unsigned char buff[0x10140]; +static unsigned char buff2[0x10140]; + +static void do_file(const char *ifn, const char *ofn) +{ + FILE *fi, *fo; + int ret; + unsigned long dlen = sizeof(buff2); + + fi = fopen(ifn, "rb"); + if (!fi) return; + fseek(fi, 0x10020, SEEK_SET); + fread(buff, 1, 0x10000, fi); + fseek(fi, 0x2000, SEEK_CUR); + fread(buff + 0x10000, 1, 0x80*2, fi); + fseek(fi, 0x221a0, SEEK_SET); + fread(buff + 0x10100, 1, 0x40, fi); + fclose(fi); + + ret = compress2(buff2, &dlen, buff, sizeof(buff), Z_BEST_COMPRESSION); + if (ret) { printf("compress2 failed with %i\n", ret); return; } + + fo = fopen(ofn, "wb"); + if (!fo) return; + fwrite(buff2, 1, dlen, fo); + fclose(fo); + + printf("%s: %6i -> %6li\n", ofn, sizeof(buff), dlen); +} + +int main(int argc, char *argv[]) +{ + if (argc != 3) return 1; + + do_file(argv[1], "bg40.bin"); + do_file(argv[2], "bg32.bin"); + + return 0; +} +