psp gfx scaling/etc stuff

git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@279 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2007-10-25 19:39:40 +00:00
parent db298784dd
commit 6f748c477f
12 changed files with 497 additions and 287 deletions

View 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 make sure you enable "Accurate timing", "Emulate Z80" and use "16bit accurate
renderer". This way you will get the best compatibility this emulator can renderer". This way you will get the best compatibility this emulator can
provide. provide.
For possible Sega/Mega CD problems, see "Other important stuff" section below.
How to run Sega/Mega CD games How to run Sega/Mega CD games

View file

@ -20,7 +20,9 @@ typedef struct {
int JoyBinds[4][32]; int JoyBinds[4][32];
int PicoAutoRgnOrder; int PicoAutoRgnOrder;
int PicoCDBuffers; 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; } currentConfig_t;

View file

@ -47,6 +47,7 @@ typedef enum
MA_OPT_CPU_CLOCKS, MA_OPT_CPU_CLOCKS,
MA_OPT_SCD_OPTS, MA_OPT_SCD_OPTS,
MA_OPT_ADV_OPTS, MA_OPT_ADV_OPTS,
MA_OPT_DISP_OPTS, /* psp */
MA_OPT_SAVECFG, MA_OPT_SAVECFG,
MA_OPT_SAVECFG_GAME, MA_OPT_SAVECFG_GAME,
MA_OPT_LOADCFG, MA_OPT_LOADCFG,
@ -63,6 +64,13 @@ typedef enum
MA_OPT2_RAMTIMINGS, /* gp2x */ MA_OPT2_RAMTIMINGS, /* gp2x */
MA_OPT2_SQUIDGEHACK, /* gp2x */ MA_OPT2_SQUIDGEHACK, /* gp2x */
MA_OPT2_DONE, 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_USA,
MA_CDOPT_TESTBIOS_EUR, MA_CDOPT_TESTBIOS_EUR,
MA_CDOPT_TESTBIOS_JAP, MA_CDOPT_TESTBIOS_JAP,

View file

@ -3,8 +3,6 @@
#ifndef PORT_CONFIG_H #ifndef PORT_CONFIG_H
#define PORT_CONFIG_H #define PORT_CONFIG_H
#define CPU_CALL
// draw.c // draw.c
#define OVERRIDE_HIGHCOL 0 #define OVERRIDE_HIGHCOL 0

View file

@ -3,7 +3,6 @@
#ifndef PORT_CONFIG_H #ifndef PORT_CONFIG_H
#define PORT_CONFIG_H #define PORT_CONFIG_H
#define CPU_CALL
#define NO_SYNC #define NO_SYNC
// draw2.c // draw2.c

View file

@ -11,9 +11,9 @@ amalgamate = 0
CFLAGS += -I../.. -I. -D_UNZIP_SUPPORT -DNO_SYNC # -DBENCHMARK CFLAGS += -I../.. -I. -D_UNZIP_SUPPORT -DNO_SYNC # -DBENCHMARK
CFLAGS += -Wall -Winline CFLAGS += -Wall -Winline -G0
ifeq ($(DEBUG),) ifeq ($(DEBUG),)
CFLAGS += -O2 -G0 -ftracer -fstrength-reduce -ffast-math CFLAGS += -O2 -ftracer -fstrength-reduce -ffast-math
else else
CFLAGS += -ggdb CFLAGS += -ggdb
endif endif
@ -52,7 +52,8 @@ OBJS += ../../Pico/sound/mix.o
OBJS += ../../Pico/sound/sn76496.o ../../Pico/sound/ym2612.o OBJS += ../../Pico/sound/sn76496.o ../../Pico/sound/ym2612.o
# zlib (hacked) # zlib (hacked)
OBJS += ../../zlib/gzio.o ../../zlib/inffast.o ../../zlib/inflate.o ../../zlib/inftrees.o ../../zlib/trees.o \ 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 # unzip
OBJS += ../../unzip/unzip.o ../../unzip/unzip_stream.o OBJS += ../../unzip/unzip.o ../../unzip/unzip_stream.o
# CPU cores # CPU cores
@ -70,6 +71,8 @@ OBJS += ../../cpu/mz80/mz80.o
else else
$(error nothing here!) $(error nothing here!)
endif endif
# bg images
OBJS += data/bg32.o data/bg40.o
LIBS += -lpng -lm -lpspgu -lpsppower -Wl,-Map=PicoDrive.map # -lpspaudio -lpsphprm LIBS += -lpng -lm -lpspgu -lpsppower -Wl,-Map=PicoDrive.map # -lpspaudio -lpsphprm
@ -109,7 +112,13 @@ readme.txt: ../../tools/textfilter ../base_readme.txt
@echo ">>>" $< @echo ">>>" $<
$(CC) $(CFLAGS) -Wno-unused -c $< -o $@ $(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 up: EBOOT.PBP
@cp -v $^ /media/disk/PSP/GAME/PicoDrive/ @cp -v $^ /media/disk/PSP/GAME/PicoDrive/

450
psp/emu.c
View file

@ -15,9 +15,9 @@
#include "../../Pico/PicoInt.h" #include "../../Pico/PicoInt.h"
#ifdef BENCHMARK #ifdef BENCHMARK
#define OSD_FPS_X 220 #define OSD_FPS_X 380
#else #else
#define OSD_FPS_X 260 #define OSD_FPS_X 420
#endif #endif
char romFileName[PATH_MAX]; char romFileName[PATH_MAX];
@ -29,7 +29,7 @@ static unsigned int noticeMsgTime = 0;
int reset_timing = 0; // do we need this? 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); static void clearArea(int full);
void emu_noticeMsgUpdated(void) void emu_noticeMsgUpdated(void)
@ -42,24 +42,31 @@ void emu_getMainDir(char *dst, int len)
if (len > 0) *dst = 0; 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); void emu_msg_cb(const char *msg)
emu_textOut16(4, 264, msg); {
osd_text(4, msg, 1);
noticeMsgTime = sceKernelGetSystemTimeLow() - 2000000; noticeMsgTime = sceKernelGetSystemTimeLow() - 2000000;
/* assumption: emu_msg_cb gets called only when something slow is about to happen */ /* assumption: emu_msg_cb gets called only when something slow is about to happen */
reset_timing = 1; reset_timing = 1;
} }
void emu_stateCb(const char *str)
{
clearArea(0);
blit("", str);
}
static void emu_msg_tray_open(void) static void emu_msg_tray_open(void)
{ {
strcpy(noticeMsg, "CD tray opened"); strcpy(noticeMsg, "CD tray opened");
@ -126,15 +133,15 @@ void emu_setDefaultConfig(void)
currentConfig.KeyBinds[13] = 1<<5; currentConfig.KeyBinds[13] = 1<<5;
currentConfig.KeyBinds[15] = 1<<6; currentConfig.KeyBinds[15] = 1<<6;
currentConfig.KeyBinds[ 3] = 1<<7; currentConfig.KeyBinds[ 3] = 1<<7;
currentConfig.KeyBinds[23] = 1<<26; // switch rend
currentConfig.KeyBinds[ 8] = 1<<27; // save state currentConfig.KeyBinds[ 8] = 1<<27; // save state
currentConfig.KeyBinds[ 9] = 1<<28; // load state currentConfig.KeyBinds[ 9] = 1<<28; // load state
currentConfig.PicoCDBuffers = 0; 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 struct Vertex
{ {
@ -142,132 +149,203 @@ struct Vertex
short x,y,z; 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];
HighCol = VRAM_STUFF; static int dynamic_palette = 0, need_pal_upload = 0, blit_16bit_mode = 0;
static int fbimg_offs = 0;
#if 0 static void set_scaling_params(void)
sceGuSync(0,0); // sync with prev {
sceGuStart(GU_DIRECT, guCmdList); int src_width, fbimg_width, fbimg_height, fbimg_xoffs, fbimg_yoffs;
// sceGuDispBuffer(480, 272, psp_screen == VRAM_FB0 ? VRAMOFFS_FB1 : VRAMOFFS_FB0, 512); g_vertices[0].x = g_vertices[0].y =
sceGuDrawBuffer(GU_PSM_5650, psp_screen == VRAM_FB0 ? VRAMOFFS_FB0 : VRAMOFFS_FB1, 512); // point to back fb? g_vertices[0].z = g_vertices[1].z = 0;
sceGuFinish();
#endif 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;
} }
static int EmuScan16(unsigned int num, void *sdata) 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 void do_slowmode_pal(void)
{ {
// struct Vertex* vertices; unsigned int *spal=(void *)Pico.cram;
unsigned int *dpal=(void *)localPal;
int i;
if (!(Pico.video.reg[1]&8)) num += 8;
//DrawLineDest = (unsigned short *) psp_screen + 512*(num+1);
HighCol = (unsigned char *)psp_screen + num*512;
#if 0
sceGuSync(0,0); // sync with prev
sceGuStart(GU_DIRECT, guCmdList);
if (Pico.m.dirtyPal) {
int i, *dpal = (void *)localPal, *spal = (int *)Pico.cram;
Pico.m.dirtyPal = 0;
for (i = 0x3f/2; i >= 0; i--) for (i = 0x3f/2; i >= 0; i--)
dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4); dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4);
sceGuClutLoad((256/8), localPal); // upload 32*8 entries (256) if (Pico.video.reg[0xC]&8) // shadow/hilight?
{
// shadowed pixels
for (i = 0x3f/2; i >= 0; i--)
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); for (; line < line_to; line++, dst+=512, src+=512)
// sceGuClutLoad((256/8), localPal); // upload 32*8 entries (256) amips_clut(dst, src, localPal, line_len);
// 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);
// render sprite static void EmuScanPrepare(void)
{
HighCol = (unsigned char *)VRAM_CACHED_STUFF + 8;
if (!(Pico.video.reg[1]&8)) HighCol += 8*512;
// sceGuColor(0xffffffff); dynamic_palette = 0;
vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); if (Pico.m.dirtyPal)
vertices[0].u = 0; vertices[0].v = 0; do_slowmode_pal();
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; static int EmuScanSlow(unsigned int num, void *sdata)
//sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices); {
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; return 0;
} }
static void blitscreen_clut(void)
{
int offs = fbimg_offs;
offs += (psp_screen == VRAM_FB0) ? VRAMOFFS_FB0 : VRAMOFFS_FB1;
static void draw2_clut(void) sceKernelDcacheWritebackAll();
sceGuSync(0,0); // sync with prev
sceGuStart(GU_DIRECT, guCmdList);
sceGuDrawBuffer(GU_PSM_5650, (void *)offs, 512); // point to back buffer
if (dynamic_palette)
{
if (!blit_16bit_mode) {
sceGuTexMode(GU_PSM_5650, 0, 0, 0);
sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 512*240);
blit_16bit_mode = 1;
}
}
else
{
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;
}
if (need_pal_upload) {
need_pal_upload = 0;
sceGuClutLoad((256/8), localPal); // upload 32*8 entries (256)
}
}
#if 1
if (g_vertices[0].u == 0 && g_vertices[1].u == g_vertices[1].x)
{ {
struct Vertex* vertices; struct Vertex* vertices;
int x; int x;
sceKernelDcacheWritebackAll(); // for PicoDraw2FB
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?
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);
sceGuClutLoad((256/8), localPal); // upload 32*8 entries (256)
}
#define SLICE_WIDTH 32 #define SLICE_WIDTH 32
for (x = 0; x < g_vertices[1].x; x += SLICE_WIDTH)
for (x = 0; x < 320; x += SLICE_WIDTH)
{ {
// render sprite // render sprite
vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex));
memcpy(vertices, g_vertices, 2 * sizeof(struct Vertex));
vertices[0].u = vertices[0].x = x; 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].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); sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices);
} }
// lprintf("listlen: %iB\n", sceGuCheckList()); // ~480 only
}
else
#endif
sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,g_vertices);
sceGuFinish(); sceGuFinish();
} }
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);
return 0;
}
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);
}
emu_textOut16(x, 264, text);
}
static void cd_leds(void) static void cd_leds(void)
{ {
static int old_reg = 0; static int old_reg = 0;
@ -285,75 +363,56 @@ static void cd_leds(void)
} }
static void blit(const char *fps, const char *notice) static void dbg_text(void)
{
int *p, h, len;
char text[128];
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);
}
emu_textOut16(2, 256, text);
}
/* called after rendering is done, but frame emulation is not finished */
void blit1(void)
{
if (PicoOpt&0x10)
{
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);
}
blitscreen_clut();
}
static void blit2(const char *fps, const char *notice)
{ {
int emu_opt = currentConfig.EmuOpt; int emu_opt = currentConfig.EmuOpt;
if (PicoOpt&0x10) sceGuSync(0,0);
{
#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
}
#if 0
else if (!(emu_opt&0x80))
{
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);
}
#endif
if (notice || (emu_opt & 2)) { if (notice || (emu_opt & 2)) {
if (notice) osd_text(4, notice); if (notice) osd_text(4, notice, 0);
if (emu_opt & 2) osd_text(OSD_FPS_X, fps); if (emu_opt & 2) osd_text(OSD_FPS_X, fps, 0);
} }
dbg_text();
if ((emu_opt & 0x400) && (PicoMCD & 1)) if ((emu_opt & 0x400) && (PicoMCD & 1))
cd_leds(); cd_leds();
sceGuSync(0,0);
psp_video_flip(0); psp_video_flip(0);
} }
@ -364,6 +423,8 @@ static void clearArea(int full)
memset32(psp_screen, 0, 512*272*2/4); memset32(psp_screen, 0, 512*272*2/4);
psp_video_flip(0); psp_video_flip(0);
memset32(psp_screen, 0, 512*272*2/4); 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 { } else {
void *fb = psp_video_get_active_fb(); void *fb = psp_video_get_active_fb();
memset32((int *)((char *)psp_screen + 512*264*2), 0, 512*8*2/4); 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); sceGuStart(GU_DIRECT, guCmdList);
sceGuClutMode(GU_PSM_5650,0,0xff,0); 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 sceGuTexMode(GU_PSM_T8,0,0,0); // 8-bit image
sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGB); sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGB);
if (currentConfig.scaling)
sceGuTexFilter(GU_LINEAR, GU_LINEAR); sceGuTexFilter(GU_LINEAR, GU_LINEAR);
else sceGuTexFilter(GU_NEAREST, GU_NEAREST);
sceGuTexScale(1.0f,1.0f); sceGuTexScale(1.0f,1.0f);
sceGuTexOffset(0.0f,0.0f); sceGuTexOffset(0.0f,0.0f);
sceGuAmbientColor(0xffffffff);
sceGuColor(0xffffffff);
sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 16);
if (PicoOpt&0x10) { // slow rend.
sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 8*512+16);
} else if (currentConfig.EmuOpt&0x80) {
PicoDrawSetColorFormat(/*1*/-1);
PicoScan = EmuScan16;
sceGuTexImage(0,512,1/*512*/,512,VRAM_STUFF);
} else {
PicoDrawSetColorFormat(-1); PicoDrawSetColorFormat(-1);
PicoScan = EmuScan8; PicoScan = EmuScanSlow;
}
if ((PicoOpt&0x10) || !(currentConfig.EmuOpt&0x80)) { localPal[0xe0] = 0;
// setup pal for 8-bit modes
localPal[0xc0] = 0x0600;
localPal[0xd0] = 0xc000;
localPal[0xe0] = 0x0000; // reserved pixels for OSD
localPal[0xf0] = 0xffff;
}
Pico.m.dirtyPal = 1; Pico.m.dirtyPal = 1;
blit_16bit_mode = dynamic_palette = 0;
sceGuFinish(); sceGuFinish();
set_scaling_params();
sceGuSync(0,0); sceGuSync(0,0);
clearArea(1);
} }
/* /*
static void updateSound(int len) static void updateSound(int len)
{ {
@ -440,11 +487,16 @@ void emu_forcedFrame(void)
PicoOpt |= 0x4080; // soft_scale | acc_sprites PicoOpt |= 0x4080; // soft_scale | acc_sprites
currentConfig.EmuOpt |= 0x80; currentConfig.EmuOpt |= 0x80;
PicoDrawSetColorFormat(1); vidResetMode();
PicoScan = EmuScan16; 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(); EmuScanPrepare();
Pico.m.dirtyPal = 1;
PicoFrameDrawOnly(); PicoFrameDrawOnly();
blit1();
sceGuSync(0,0);
PicoOpt = po_old; PicoOpt = po_old;
currentConfig.EmuOpt = eo_old; currentConfig.EmuOpt = eo_old;
@ -462,7 +514,7 @@ static void RunEvents(unsigned int which)
(!(which & 0x1000) && (currentConfig.EmuOpt & 0x200))) ) // save (!(which & 0x1000) && (currentConfig.EmuOpt & 0x200))) ) // save
{ {
int keys; 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)) ) while( !((keys = psp_pad_read(1)) & (BTN_X|BTN_CIRCLE)) )
psp_msleep(50); psp_msleep(50);
if (keys & BTN_CIRCLE) do_it = 0; if (keys & BTN_CIRCLE) do_it = 0;
@ -473,8 +525,8 @@ static void RunEvents(unsigned int which)
if (do_it) if (do_it)
{ {
osd_text(4, (which & 0x1000) ? "LOADING GAME" : "SAVING GAME"); osd_text(4, (which & 0x1000) ? "LOADING GAME" : "SAVING GAME", 1);
PicoStateProgressCB = emu_stateCb; PicoStateProgressCB = emu_msg_cb;
emu_SaveLoadGame((which & 0x1000) >> 12, 0); emu_SaveLoadGame((which & 0x1000) >> 12, 0);
PicoStateProgressCB = NULL; PicoStateProgressCB = NULL;
psp_msleep(0); psp_msleep(0);
@ -644,6 +696,7 @@ void emu_Loop(void)
// make sure we are in correct mode // make sure we are in correct mode
vidResetMode(); vidResetMode();
clearArea(1);
Pico.m.dirtyPal = 1; Pico.m.dirtyPal = 1;
oldmodes = ((Pico.video.reg[12]&1)<<2) ^ 0xc; oldmodes = ((Pico.video.reg[12]&1)<<2) ^ 0xc;
find_combos(); find_combos();
@ -721,6 +774,7 @@ void emu_Loop(void)
if (modes != oldmodes) { if (modes != oldmodes) {
oldmodes = modes; oldmodes = modes;
clearArea(1); clearArea(1);
set_scaling_params();
} }
// second passed? // second passed?
@ -798,7 +852,7 @@ void emu_Loop(void)
PicoFrame(); PicoFrame();
blit(fpsbuff, notice); blit2(fpsbuff, notice);
// check time // check time
tval = sceKernelGetSystemTimeLow(); tval = sceKernelGetSystemTimeLow();
@ -829,7 +883,7 @@ void emu_Loop(void)
*/ */
// save SRAM // save SRAM
if ((currentConfig.EmuOpt & 1) && SRam.changed) { if ((currentConfig.EmuOpt & 1) && SRam.changed) {
emu_stateCb("Writing SRAM/BRAM.."); emu_msg_cb("Writing SRAM/BRAM..");
emu_SaveLoadGame(0, 1); emu_SaveLoadGame(0, 1);
SRam.changed = 0; SRam.changed = 0;
} }

View file

@ -26,6 +26,6 @@ void emu_Loop(void);
void emu_ResetGame(void); void emu_ResetGame(void);
void emu_forcedFrame(void); void emu_forcedFrame(void);
void emu_stateCb(const char *str); void emu_msg_cb(const char *msg);

View file

@ -6,7 +6,6 @@
// don't like to use loads of #ifdefs, so duplicating GP2X code // don't like to use loads of #ifdefs, so duplicating GP2X code
// horribly instead // horribly instead
//#include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <wchar.h> #include <wchar.h>
@ -16,6 +15,7 @@
#include <pspdisplay.h> #include <pspdisplay.h>
#include <pspgu.h> #include <pspgu.h>
#include <pspiofilemgr.h> #include <pspiofilemgr.h>
#include <psputils.h>
#include "psp.h" #include "psp.h"
#include "emu.h" #include "emu.h"
@ -39,11 +39,11 @@ static const char * const pspKeyNames[] = {
pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, pspKeyUnkn 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 #define menu_screen psp_screen
static void menu_darken_bg(void *dst, const void *src, int pixels, int darker); 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; 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) static void draw_savestate_bg(int slot)
{ {
struct PicoVideo tmp_pv; void *file, *oldstate;
unsigned short tmp_cram[0x40];
unsigned short tmp_vsram[0x40];
void *tmp_vram, *file;
char *fname; char *fname;
fname = emu_GetSaveFName(1, 0, slot); fname = emu_GetSaveFName(1, 0, slot);
if (!fname) return; if (!fname) return;
tmp_vram = malloc(sizeof(Pico.vram)); oldstate = get_oldstate_for_preview();
if (tmp_vram == NULL) return; if (oldstate == 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));
if (strcmp(fname + strlen(fname) - 3, ".gz") == 0) { if (strcmp(fname + strlen(fname) - 3, ".gz") == 0) {
file = gzopen(fname, "rb"); file = gzopen(fname, "rb");
@ -538,13 +552,9 @@ static void draw_savestate_bg(int slot)
} }
emu_forcedFrame(); emu_forcedFrame();
menu_prepare_bg(1); menu_prepare_bg(1, 1);
memcpy(Pico.vram, tmp_vram, sizeof(Pico.vram)); restore_oldstate(oldstate);
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);
} }
static void draw_savestate_menu(int menu_sel, int is_loading) 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(inp & BTN_X) { // save/load
if (menu_sel < 10) { if (menu_sel < 10) {
state_slot = menu_sel; 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)) { if (emu_SaveLoadGame(is_loading, 0)) {
strcpy(menuErrorMsg, is_loading ? "Load failed" : "Save failed"); strcpy(menuErrorMsg, is_loading ? "Load failed" : "Save failed");
return 1; 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 ---------- // --------- 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 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 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 }, { "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 }, { "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 }, { "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 }, { "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 (inp & (BTN_LEFT|BTN_RIGHT)) { // multi choise
if (!me_process(opt2_entries, OPT2_ENTRY_COUNT, selected_id, (inp&BTN_RIGHT) ? 1 : 0) && if (!me_process(opt2_entries, OPT2_ENTRY_COUNT, selected_id, (inp&BTN_RIGHT) ? 1 : 0) &&
selected_id == MA_OPT2_GAMMA) { selected_id == MA_OPT2_GAMMA) {
while ((inp = psp_pad_read(1)) & (BTN_LEFT|BTN_RIGHT)) { // TODO?
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);
}
} }
} }
if (inp & BTN_X) { // toggleable options 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 }, { 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 }, { "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 }, { 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 }, { "[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 }, { 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 }, { "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 }, { 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) static void draw_menu_options(int menu_sel)
{ {
int tl_x = 80+25, tl_y = 16+24; int tl_x = 80+25, tl_y = 16+24;
@ -1282,6 +1428,9 @@ static int menu_loop_options(void)
{ {
switch (selected_id) switch (selected_id)
{ {
case MA_OPT_DISP_OPTS:
dispmenu_loop_options();
break;
case MA_OPT_SCD_OPTS: case MA_OPT_SCD_OPTS:
cd_menu_loop_options(); cd_menu_loop_options();
if (engineState == PGS_ReloadRom) 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); me_draw(main_entries, MAIN_ENTRY_COUNT, tl_x, tl_y, NULL, NULL);
// error // error
if (menuErrorMsg[0]) { if (menuErrorMsg[0])
// memset((char *)menu_screen + 321*224*2, 0, 321*16*2); text_out16(10, 252, menuErrorMsg);
text_out16(5, 258, menuErrorMsg);
}
menu_draw_end(); 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) if (use_game_bg)
{ {
// darken the active framebuffer // darken the active framebuffer
/* unsigned short *dst = bg_buffer;
memset(bg_buffer, 0, 321*8*2); unsigned short *src = use_back_buff ? psp_screen : psp_video_get_active_fb();
menu_darken_bg(bg_buffer + 321*8*2, (char *)giz_screen + 321*8*2, 321*224, 1); int i;
memset(bg_buffer + 321*232*2, 0, 321*8*2); 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 else
{ {
// should really only happen once, on startup.. // 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); readpng(bg_buffer, "skin/background.png", READPNG_BG);
} }
sceKernelDcacheWritebackAll();
} }
static void menu_gfx_prepare(void) static void menu_gfx_prepare(void)
{ {
menu_prepare_bg(rom_data != NULL); menu_prepare_bg(rom_data != NULL, 0);
menu_draw_begin(); menu_draw_begin();
menu_draw_end(); menu_draw_end();

View file

@ -3,8 +3,6 @@
#ifndef PORT_CONFIG_H #ifndef PORT_CONFIG_H
#define PORT_CONFIG_H #define PORT_CONFIG_H
#define CPU_CALL
// draw.c // draw.c
#define USE_BGR555 1 #define USE_BGR555 1
#define OVERRIDE_HIGHCOL 1 #define OVERRIDE_HIGHCOL 1
@ -15,6 +13,8 @@
#define DRAW2_OVERRIDE_LINE_WIDTH 512 #define DRAW2_OVERRIDE_LINE_WIDTH 512
// pico.c // pico.c
extern void blit1(void);
#define DRAW_FINISH_FUNC blit1
#define CAN_HANDLE_240_LINES 1 #define CAN_HANDLE_240_LINES 1
// logging emu events // logging emu events

View file

@ -64,34 +64,24 @@ void psp_init(void)
sceGuInit(); sceGuInit();
sceGuStart(GU_DIRECT, guCmdList); sceGuStart(GU_DIRECT, guCmdList);
sceGuDrawBuffer(GU_PSM_5650, VRAMOFFS_FB0, 512); // point to back fb? sceGuDrawBuffer(GU_PSM_5650, (void *)VRAMOFFS_FB0, 512);
sceGuDispBuffer(480, 272, VRAMOFFS_FB1, 512); sceGuDispBuffer(480, 272, (void *)VRAMOFFS_FB1, 512); // don't care
sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT); 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)); sceGuOffset(2048 - (480 / 2), 2048 - (272 / 2));
sceGuViewport(2048, 2048, 480, 272); sceGuViewport(2048, 2048, 480, 272);
sceGuDepthRange(0xc350, 0x2710); sceGuDepthRange(0xc350, 0x2710);
sceGuScissor(0, 0, 480, 272); sceGuScissor(0, 0, 480, 272);
sceGuEnable(GU_SCISSOR_TEST); sceGuEnable(GU_SCISSOR_TEST);
// sceGuAlphaFunc(GU_GREATER, 0, 0xff);
// sceGuEnable(GU_ALPHA_TEST);
// sceGuDepthFunc(GU_ALWAYS); // GU_GEQUAL);
// sceGuEnable(GU_DEPTH_TEST);
sceGuDepthMask(0xffff); sceGuDepthMask(0xffff);
sceGuDisable(GU_DEPTH_TEST); sceGuDisable(GU_DEPTH_TEST);
sceGuFrontFace(GU_CW); sceGuFrontFace(GU_CW);
// sceGuShadeModel(GU_SMOOTH);
// sceGuEnable(GU_CULL_FACE);
sceGuEnable(GU_TEXTURE_2D); sceGuEnable(GU_TEXTURE_2D);
// sceGuEnable(GU_CLIP_PLANES);
sceGuTexMode(GU_PSM_5650, 0, 0, 0);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
sceGuTexFilter(GU_NEAREST, GU_NEAREST); sceGuAmbientColor(0xffffffff);
// sceGuAmbientColor(0xffffffff); sceGuColor(0xffffffff);
// sceGuEnable(GU_BLEND);
// sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
sceGuFinish(); sceGuFinish();
sceGuSync(0, 0); sceGuSync(0, 0);

View file

@ -9,19 +9,20 @@ void psp_msleep(int ms);
// 000000-044000 fb0 // 000000-044000 fb0
// 044000-088000 fb1 // 044000-088000 fb1
// 088000-0cc000 depth (?) // 088000-0cc000 depth (?)
// 0cc000-0??000 stuff // 0cc000-126000 emu draw buffers: 512*240 + 512*240*2
#define VRAMOFFS_FB0 ((void *) 0x00000000) #define VRAMOFFS_FB0 0x00000000
#define VRAMOFFS_FB1 ((void *) 0x00044000) #define VRAMOFFS_FB1 0x00044000
#define VRAMOFFS_DEPTH ((void *) 0x00088000) #define VRAMOFFS_DEPTH 0x00088000
#define VRAMOFFS_STUFF 0x000cc000
#define VRAM_FB0 ((void *) 0x44000000) #define VRAM_FB0 ((void *) (0x44000000+VRAMOFFS_FB0))
#define VRAM_FB1 ((void *) 0x44044000) #define VRAM_FB1 ((void *) (0x44000000+VRAMOFFS_FB1))
#define VRAM_STUFF ((void *) 0x440cc000) #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]; 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_SQUARE PSP_CTRL_SQUARE
#define BTN_SELECT PSP_CTRL_SELECT #define BTN_SELECT PSP_CTRL_SELECT
#define BTN_START PSP_CTRL_START #define BTN_START PSP_CTRL_START
#define BTN_NOTE PSP_CTRL_NOTE #define BTN_NOTE PSP_CTRL_NOTE // doesn't seem to work?