psp gfx scaling/etc stuff

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@279 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2007-10-25 19:39:40 +00:00
parent 3aa1e148a2
commit 8ab3e3c1cf
26 changed files with 567 additions and 321 deletions

View file

@ -69,7 +69,7 @@ static __inline int PicoMemBase(u32 pc)
#endif
static u32 CPU_CALL PicoCheckPc(u32 pc)
static u32 PicoCheckPc(u32 pc)
{
u32 ret=0;
#if defined(EMU_C68K)
@ -315,7 +315,7 @@ static void OtherWrite8End(u32 a,u32 d,int realsize)
// Read Rom and read Ram
#ifndef _ASM_MEMORY_C
PICO_INTERNAL_ASM u32 CPU_CALL PicoRead8(u32 a)
PICO_INTERNAL_ASM u32 PicoRead8(u32 a)
{
u32 d=0;
@ -351,7 +351,7 @@ end:
return d;
}
PICO_INTERNAL_ASM u32 CPU_CALL PicoRead16(u32 a)
PICO_INTERNAL_ASM u32 PicoRead16(u32 a)
{
u32 d=0;
@ -387,7 +387,7 @@ end:
return d;
}
PICO_INTERNAL_ASM u32 CPU_CALL PicoRead32(u32 a)
PICO_INTERNAL_ASM u32 PicoRead32(u32 a)
{
u32 d=0;
@ -426,7 +426,7 @@ end:
// Write Ram
#ifndef _ASM_MEMORY_C
PICO_INTERNAL_ASM void CPU_CALL PicoWrite8(u32 a,u8 d)
PICO_INTERNAL_ASM void PicoWrite8(u32 a,u8 d)
{
#ifdef __debug_io
dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);
@ -446,7 +446,7 @@ PICO_INTERNAL_ASM void CPU_CALL PicoWrite8(u32 a,u8 d)
}
#endif
void CPU_CALL PicoWrite16(u32 a,u16 d)
void PicoWrite16(u32 a,u16 d)
{
#ifdef __debug_io
dprintf("w16: %06x, %04x", a&0xffffff, d);
@ -462,7 +462,7 @@ void CPU_CALL PicoWrite16(u32 a,u16 d)
OtherWrite16(a,d);
}
static void CPU_CALL PicoWrite32(u32 a,u32 d)
static void PicoWrite32(u32 a,u32 d)
{
#ifdef __debug_io
dprintf("w32: %06x, %08x", a&0xffffff, d);

View file

@ -316,7 +316,7 @@ static int PicoFrameSimple(void)
int cycles_68k_vblock,cycles_68k_block;
// split to 16 run calls for active scan, for vblank split to 2 (ntsc), 3 (pal 240), 4 (pal 224)
if (Pico.m.pal && (pv->reg[1]&8)) { // 240 lines
if (Pico.m.pal && (pv->reg[1]&8)) {
if(pv->reg[1]&8) { // 240 lines
cycles_68k_block = 7329; // (488*240+148)/16.0, -4
cycles_68k_vblock = 11640; // (72*488-148-68)/3.0, 0
@ -378,14 +378,6 @@ static int PicoFrameSimple(void)
PicoRunZ80Simple(line, lines);
}
// here we render sound if ym2612 is disabled
if (!(PicoOpt&1) && PsndOut) {
int len = sound_render(0, PsndLen);
if (PicoWriteSound) PicoWriteSound(len);
// clear sound buffer
sound_clear();
}
// render screen
if (!PicoSkipFrame)
{
@ -401,6 +393,17 @@ static int PicoFrameSimple(void)
for (y=0;y<224;y++) PicoLine(y);
#endif
else PicoFrameFull();
#ifdef DRAW_FINISH_FUNC
DRAW_FINISH_FUNC();
#endif
}
// here we render sound if ym2612 is disabled
if (!(PicoOpt&1) && PsndOut) {
int len = sound_render(0, PsndLen);
if (PicoWriteSound) PicoWriteSound(len);
// clear sound buffer
sound_clear();
}
// a gap between flags set and vint

View 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;

View file

@ -313,7 +313,7 @@ PICO_INTERNAL void PicoFrameFull();
// Memory.c
PICO_INTERNAL int PicoInitPc(unsigned int pc);
PICO_INTERNAL_ASM unsigned int CPU_CALL PicoRead32(unsigned int a);
PICO_INTERNAL_ASM unsigned int PicoRead32(unsigned int a);
PICO_INTERNAL void PicoMemSetup(void);
PICO_INTERNAL_ASM void PicoMemReset(void);
PICO_INTERNAL int PadRead(int i);

View file

@ -11,7 +11,7 @@ unsigned int DisaPc=0;
char *DisaText=NULL; // Text buffer to write in
static char Tasm[]="bwl?";
static char Comment[64]="";
unsigned short (CPU_CALL *DisaWord)(unsigned int a)=NULL;
unsigned short (*DisaWord)(unsigned int a)=NULL;
static unsigned int DisaLong(unsigned int a)
{

View file

@ -5,16 +5,10 @@
extern "C" {
#endif
#if defined(ARM) || defined(GP32) || !defined (__WINS__)
#define CPU_CALL
#else
#define CPU_CALL __fastcall
#endif
extern unsigned int DisaPc;
extern char *DisaText; // Text buffer to write in
extern unsigned short (CPU_CALL *DisaWord)(unsigned int a);
extern unsigned short (*DisaWord)(unsigned int a);
int DisaGetEa(char *t,int ea,int size);
int DisaGet();

View file

@ -5,7 +5,7 @@ int opend_op_changes_cycles, opend_check_interrupt, opend_check_trace;
static unsigned char OpData[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static unsigned short CPU_CALL OpRead16(unsigned int a)
static unsigned short OpRead16(unsigned int a)
{
return (unsigned short)( (OpData[a&15]<<8) | OpData[(a+1)&15] );
}

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
renderer". This way you will get the best compatibility this emulator can
provide.
For possible Sega/Mega CD problems, see "Other important stuff" section below.
How to run Sega/Mega CD games

View 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;

View 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,

View file

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

View file

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

View file

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

View file

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

BIN
platform/psp/data/bg32.bin Normal file

Binary file not shown.

BIN
platform/psp/data/bg40.bin Normal file

Binary file not shown.

View 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,132 +149,203 @@ struct Vertex
short x,y,z;
};
static void EmuScanPrepare(void)
{
HighCol = VRAM_STUFF;
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;
#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
static void set_scaling_params(void)
{
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;
}
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--)
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);
// 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 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;
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
for (x = 0; x < 320; x += SLICE_WIDTH)
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[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);
}
// 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();
}
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 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;
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
}
#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
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);
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);
sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 16);
if (PicoOpt&0x10) {
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 {
// slow rend.
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;
}
PicoScan = EmuScanSlow;
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;
}

View 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);

View 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();

View file

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

View 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);

View 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?

View file

@ -3,8 +3,6 @@
#ifndef PORT_CONFIG_H
#define PORT_CONFIG_H
#define CPU_CALL
// draw2.c
#define START_ROW 1 // which row of tiles to start rendering at?
#define END_ROW 27 // ..end

View file

@ -3,8 +3,6 @@
#ifndef PORT_CONFIG_H
#define PORT_CONFIG_H
#define CPU_CALL
// draw2.c
#define START_ROW 0 // which row of tiles to start rendering at?
#define END_ROW 28 // ..end

View file

@ -3,8 +3,6 @@
#ifndef PORT_CONFIG_H
#define PORT_CONFIG_H
#define CPU_CALL __fastcall
// draw2.c
#define START_ROW 0 // which row of tiles to start rendering at?
#define END_ROW 28 // ..end

43
tools/mkbgxx.c Normal file
View file

@ -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;
}