psp gfx scaling/etc stuff
authornotaz <notasas@gmail.com>
Thu, 25 Oct 2007 19:39:40 +0000 (19:39 +0000)
committernotaz <notasas@gmail.com>
Thu, 25 Oct 2007 19:39:40 +0000 (19:39 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@279 be3aeb3a-fb24-0410-a615-afba39da0efa

26 files changed:
Pico/Memory.c
Pico/Pico.c
Pico/PicoFrameHints.c
Pico/PicoInt.h
cpu/Cyclone/Disa/Disa.c
cpu/Cyclone/Disa/Disa.h
cpu/Cyclone/OpAny.cpp
platform/base_readme.txt
platform/common/emu.h
platform/common/menu.h
platform/gizmondo/port_config.h
platform/gp2x/port_config.h
platform/linux/port_config.h
platform/psp/Makefile
platform/psp/data/bg32.bin [new file with mode: 0644]
platform/psp/data/bg40.bin [new file with mode: 0644]
platform/psp/emu.c
platform/psp/emu.h
platform/psp/menu.c
platform/psp/port_config.h
platform/psp/psp.c
platform/psp/psp.h
platform/uiq2/port_config.h
platform/uiq3/port_config.h
platform/win32/GenaDrive/port_config.h
tools/mkbgxx.c [new file with mode: 0644]

index 963d30b..527b80b 100644 (file)
@@ -69,7 +69,7 @@ static __inline int PicoMemBase(u32 pc)
 #endif\r
 \r
 \r
-static u32 CPU_CALL PicoCheckPc(u32 pc)\r
+static u32 PicoCheckPc(u32 pc)\r
 {\r
   u32 ret=0;\r
 #if defined(EMU_C68K)\r
@@ -315,7 +315,7 @@ static void OtherWrite8End(u32 a,u32 d,int realsize)
 //                     Read Rom and read Ram\r
 \r
 #ifndef _ASM_MEMORY_C\r
-PICO_INTERNAL_ASM u32 CPU_CALL PicoRead8(u32 a)\r
+PICO_INTERNAL_ASM u32 PicoRead8(u32 a)\r
 {\r
   u32 d=0;\r
 \r
@@ -351,7 +351,7 @@ end:
   return d;\r
 }\r
 \r
-PICO_INTERNAL_ASM u32 CPU_CALL PicoRead16(u32 a)\r
+PICO_INTERNAL_ASM u32 PicoRead16(u32 a)\r
 {\r
   u32 d=0;\r
 \r
@@ -387,7 +387,7 @@ end:
   return d;\r
 }\r
 \r
-PICO_INTERNAL_ASM u32 CPU_CALL PicoRead32(u32 a)\r
+PICO_INTERNAL_ASM u32 PicoRead32(u32 a)\r
 {\r
   u32 d=0;\r
 \r
@@ -426,7 +426,7 @@ end:
 //                            Write Ram\r
 \r
 #ifndef _ASM_MEMORY_C\r
-PICO_INTERNAL_ASM void CPU_CALL PicoWrite8(u32 a,u8 d)\r
+PICO_INTERNAL_ASM void PicoWrite8(u32 a,u8 d)\r
 {\r
 #ifdef __debug_io\r
   dprintf("w8 : %06x,   %02x @%06x", a&0xffffff, d, SekPc);\r
@@ -446,7 +446,7 @@ PICO_INTERNAL_ASM void CPU_CALL PicoWrite8(u32 a,u8 d)
 }\r
 #endif\r
 \r
-void CPU_CALL PicoWrite16(u32 a,u16 d)\r
+void PicoWrite16(u32 a,u16 d)\r
 {\r
 #ifdef __debug_io\r
   dprintf("w16: %06x, %04x", a&0xffffff, d);\r
@@ -462,7 +462,7 @@ void CPU_CALL PicoWrite16(u32 a,u16 d)
   OtherWrite16(a,d);\r
 }\r
 \r
-static void CPU_CALL PicoWrite32(u32 a,u32 d)\r
+static void PicoWrite32(u32 a,u32 d)\r
 {\r
 #ifdef __debug_io\r
   dprintf("w32: %06x, %08x", a&0xffffff, d);\r
index ce3e340..22bdb19 100644 (file)
@@ -316,7 +316,7 @@ static int PicoFrameSimple(void)
   int cycles_68k_vblock,cycles_68k_block;\r
 \r
   // split to 16 run calls for active scan, for vblank split to 2 (ntsc), 3 (pal 240), 4 (pal 224)\r
-  if (Pico.m.pal && (pv->reg[1]&8)) { // 240 lines\r
+  if (Pico.m.pal && (pv->reg[1]&8)) {\r
     if(pv->reg[1]&8) { // 240 lines\r
       cycles_68k_block  = 7329;  // (488*240+148)/16.0, -4\r
       cycles_68k_vblock = 11640; // (72*488-148-68)/3.0, 0\r
@@ -378,14 +378,6 @@ static int PicoFrameSimple(void)
     PicoRunZ80Simple(line, lines);\r
   }\r
 \r
-  // here we render sound if ym2612 is disabled\r
-  if (!(PicoOpt&1) && PsndOut) {\r
-    int len = sound_render(0, PsndLen);\r
-    if (PicoWriteSound) PicoWriteSound(len);\r
-    // clear sound buffer\r
-    sound_clear();\r
-  }\r
-\r
   // render screen\r
   if (!PicoSkipFrame)\r
   {\r
@@ -401,6 +393,17 @@ static int PicoFrameSimple(void)
       for (y=0;y<224;y++) PicoLine(y);\r
 #endif\r
     else PicoFrameFull();\r
+#ifdef DRAW_FINISH_FUNC\r
+    DRAW_FINISH_FUNC();\r
+#endif\r
+  }\r
+\r
+  // here we render sound if ym2612 is disabled\r
+  if (!(PicoOpt&1) && PsndOut) {\r
+    int len = sound_render(0, PsndLen);\r
+    if (PicoWriteSound) PicoWriteSound(len);\r
+    // clear sound buffer\r
+    sound_clear();\r
   }\r
 \r
   // a gap between flags set and vint\r
index c14040a..ba76f6f 100644 (file)
@@ -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;
 
index a9720c8..7a81ba6 100644 (file)
@@ -313,7 +313,7 @@ PICO_INTERNAL void PicoFrameFull();
 \r
 // Memory.c\r
 PICO_INTERNAL int PicoInitPc(unsigned int pc);\r
-PICO_INTERNAL_ASM unsigned int CPU_CALL PicoRead32(unsigned int a);\r
+PICO_INTERNAL_ASM unsigned int PicoRead32(unsigned int a);\r
 PICO_INTERNAL void PicoMemSetup(void);\r
 PICO_INTERNAL_ASM void PicoMemReset(void);\r
 PICO_INTERNAL int PadRead(int i);\r
index 26c9967..190e36d 100644 (file)
@@ -11,7 +11,7 @@ unsigned int DisaPc=0;
 char *DisaText=NULL; // Text buffer to write in\r
 static char Tasm[]="bwl?";\r
 static char Comment[64]="";\r
-unsigned short (CPU_CALL *DisaWord)(unsigned int a)=NULL;\r
+unsigned short (*DisaWord)(unsigned int a)=NULL;\r
 \r
 static unsigned int DisaLong(unsigned int a)\r
 {\r
index 9d45611..1ef18fc 100644 (file)
@@ -5,16 +5,10 @@
 extern "C" {\r
 #endif\r
 \r
-#if defined(ARM) || defined(GP32) || !defined (__WINS__)\r
-#define CPU_CALL\r
-#else\r
-#define CPU_CALL __fastcall\r
-#endif\r
-\r
 extern unsigned int DisaPc;\r
 extern char *DisaText; // Text buffer to write in\r
 \r
-extern unsigned short (CPU_CALL *DisaWord)(unsigned int a);\r
+extern unsigned short (*DisaWord)(unsigned int a);\r
 int DisaGetEa(char *t,int ea,int size);\r
 \r
 int DisaGet();\r
index 0ada13f..6ee08ec 100644 (file)
@@ -5,7 +5,7 @@ int opend_op_changes_cycles, opend_check_interrupt, opend_check_trace;
 \r
 static unsigned char OpData[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\r
 \r
-static unsigned short CPU_CALL OpRead16(unsigned int a)\r
+static unsigned short OpRead16(unsigned int a)\r
 {\r
   return (unsigned short)( (OpData[a&15]<<8) | OpData[(a+1)&15] );\r
 }\r
index 9cedf35..7f284bd 100644 (file)
@@ -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\r
 renderer". This way you will get the best compatibility this emulator can\r
 provide.\r
+For possible Sega/Mega CD problems, see "Other important stuff" section below.\r
 \r
 \r
 How to run Sega/Mega CD games\r
index f826157..34c6f01 100644 (file)
@@ -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;
 
 
index cbf0d85..cd7fa44 100644 (file)
@@ -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,
index 3bf29f7..f07e929 100644 (file)
@@ -3,8 +3,6 @@
 #ifndef PORT_CONFIG_H\r
 #define PORT_CONFIG_H\r
 \r
-#define CPU_CALL\r
-\r
 // draw.c\r
 #define OVERRIDE_HIGHCOL 1\r
 \r
index dcd5032..f097a4a 100644 (file)
@@ -3,8 +3,6 @@
 #ifndef PORT_CONFIG_H\r
 #define PORT_CONFIG_H\r
 \r
-#define CPU_CALL\r
-\r
 // draw.c\r
 #define OVERRIDE_HIGHCOL 0\r
 \r
index 0d439c4..9af5d3d 100644 (file)
@@ -3,7 +3,6 @@
 #ifndef PORT_CONFIG_H
 #define PORT_CONFIG_H
 
-#define CPU_CALL
 #define NO_SYNC
 
 // draw2.c
index 7a0cada..db032d8 100644 (file)
@@ -11,9 +11,9 @@ amalgamate = 0
 \r
 \r
 CFLAGS += -I../.. -I. -D_UNZIP_SUPPORT -DNO_SYNC # -DBENCHMARK\r
-CFLAGS += -Wall -Winline\r
+CFLAGS += -Wall -Winline -G0\r
 ifeq ($(DEBUG),)\r
-CFLAGS += -O2 -G0 -ftracer -fstrength-reduce -ffast-math\r
+CFLAGS += -O2 -ftracer -fstrength-reduce -ffast-math\r
 else\r
 CFLAGS += -ggdb\r
 endif\r
@@ -52,7 +52,8 @@ OBJS += ../../Pico/sound/mix.o
 OBJS += ../../Pico/sound/sn76496.o ../../Pico/sound/ym2612.o\r
 # zlib (hacked)\r
 OBJS += ../../zlib/gzio.o ../../zlib/inffast.o ../../zlib/inflate.o ../../zlib/inftrees.o ../../zlib/trees.o \\r
-       ../../zlib/deflate.o ../../zlib/crc32.o ../../zlib/adler32.o ../../zlib/zutil.o ../../zlib/compress.o\r
+       ../../zlib/deflate.o ../../zlib/crc32.o ../../zlib/adler32.o ../../zlib/zutil.o ../../zlib/compress.o \\r
+       ../../zlib/uncompr.o\r
 # unzip\r
 OBJS += ../../unzip/unzip.o ../../unzip/unzip_stream.o\r
 # CPU cores\r
@@ -70,6 +71,8 @@ OBJS += ../../cpu/mz80/mz80.o
 else\r
 $(error nothing here!)\r
 endif\r
+# bg images\r
+OBJS += data/bg32.o data/bg40.o\r
 \r
 \r
 LIBS += -lpng -lm -lpspgu -lpsppower -Wl,-Map=PicoDrive.map # -lpspaudio -lpsphprm\r
@@ -109,7 +112,13 @@ readme.txt: ../../tools/textfilter ../base_readme.txt
        @echo ">>>" $<\r
        $(CC) $(CFLAGS) -Wno-unused -c $< -o $@\r
 \r
-# ?\r
+data/bg32.o: data/bg32.bin\r
+       bin2o -i $< $@ bgdatac32\r
+\r
+data/bg40.o: data/bg40.bin\r
+       bin2o -i $< $@ bgdatac40\r
+\r
+#\r
 up: EBOOT.PBP\r
        @cp -v $^ /media/disk/PSP/GAME/PicoDrive/\r
 \r
diff --git a/platform/psp/data/bg32.bin b/platform/psp/data/bg32.bin
new file mode 100644 (file)
index 0000000..e887b12
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 (file)
index 0000000..73fe666
Binary files /dev/null and b/platform/psp/data/bg40.bin differ
index edaf26a..8542a8f 100644 (file)
@@ -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;
        }
index 48ce9a3..d122a20 100644 (file)
@@ -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);
 
 
index 1f3c6ea..27cb28a 100644 (file)
@@ -6,7 +6,6 @@
 // don't like to use loads of #ifdefs, so duplicating GP2X code
 // horribly instead
 
-//#include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <wchar.h>
@@ -16,6 +15,7 @@
 #include <pspdisplay.h>
 #include <pspgu.h>
 #include <pspiofilemgr.h>
+#include <psputils.h>
 
 #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,     &currentConfig.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 = &currentConfig.scale; break;
+                               case MA_OPT3_HSCALE40: setting = &currentConfig.hscale40; is_32col = 0; break;
+                               case MA_OPT3_HSCALE32: setting = &currentConfig.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,    &currentConfig.PicoOpt,0x0004, 0, 0, 1 },
        { "Emulate YM2612 (FM)",       MB_ONOFF, MA_OPT2_ENABLE_YM2612, &currentConfig.PicoOpt,0x0001, 0, 0, 1 },
        { "Emulate SN76496 (PSG)",     MB_ONOFF, MA_OPT2_ENABLE_SN76496,&currentConfig.PicoOpt,0x0002, 0, 0, 1 },
-//     { "Double buffering",          MB_ONOFF, MA_OPT2_DBLBUFF,       &currentConfig.EmuOpt, 0x8000, 0, 0, 1 },
-//     { "Wait for V-sync (slow)",    MB_ONOFF, MA_OPT2_VSYNC,         &currentConfig.EmuOpt, 0x2000, 0, 0, 1 },
        { "gzip savestates",           MB_ONOFF, MA_OPT2_GZIP_STATES,   &currentConfig.EmuOpt, 0x0008, 0, 0, 1 },
        { "Don't save last used ROM",  MB_ONOFF, MA_OPT2_NO_LAST_ROM,   &currentConfig.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();
index 486a877..6958c1b 100644 (file)
@@ -3,8 +3,6 @@
 #ifndef PORT_CONFIG_H\r
 #define PORT_CONFIG_H\r
 \r
-#define CPU_CALL\r
-\r
 // draw.c\r
 #define USE_BGR555 1\r
 #define OVERRIDE_HIGHCOL 1\r
@@ -15,6 +13,8 @@
 #define DRAW2_OVERRIDE_LINE_WIDTH 512\r
 \r
 // pico.c\r
+extern void blit1(void);\r
+#define DRAW_FINISH_FUNC blit1\r
 #define CAN_HANDLE_240_LINES   1\r
 \r
 // logging emu events\r
index 8f811f6..84ab5c8 100644 (file)
@@ -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);
 
index 03f9db0..8a2828e 100644 (file)
@@ -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?
 
index e5ed140..6ed28b1 100644 (file)
@@ -3,8 +3,6 @@
 #ifndef PORT_CONFIG_H\r
 #define PORT_CONFIG_H\r
 \r
-#define CPU_CALL\r
-\r
 // draw2.c\r
 #define START_ROW  1 // which row of tiles to start rendering at?\r
 #define END_ROW   27 // ..end\r
index 0478ce4..79f5fda 100644 (file)
@@ -3,8 +3,6 @@
 #ifndef PORT_CONFIG_H\r
 #define PORT_CONFIG_H\r
 \r
-#define CPU_CALL\r
-\r
 // draw2.c\r
 #define START_ROW  0 // which row of tiles to start rendering at?\r
 #define END_ROW   28 // ..end\r
index 9acc7cd..fbb2170 100644 (file)
@@ -3,8 +3,6 @@
 #ifndef PORT_CONFIG_H\r
 #define PORT_CONFIG_H\r
 \r
-#define CPU_CALL __fastcall\r
-\r
 // draw2.c\r
 #define START_ROW  0 // which row of tiles to start rendering at?\r
 #define END_ROW   28 // ..end\r
diff --git a/tools/mkbgxx.c b/tools/mkbgxx.c
new file mode 100644 (file)
index 0000000..02b51da
--- /dev/null
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <zlib.h>
+
+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;
+}
+