partially revived platform support for PSP (unfinished)

just to have a platform with an unusal screen resolution
- suspend/resume handling probably non-working
- no scaling settings
- no image generation
currently no intentions to finish this.
This commit is contained in:
kub 2021-01-10 12:09:18 +01:00
parent f821bb7011
commit cdc6aac4c0
17 changed files with 961 additions and 2468 deletions

View file

@ -34,10 +34,12 @@ gperf ?= 0
ifneq ("$(PLATFORM)", "libretro") ifneq ("$(PLATFORM)", "libretro")
CFLAGS += -Wall -g CFLAGS += -Wall -g
ifneq ("$(PLATFORM)", "psp")
ifneq ($(findstring gcc,$(shell $(CC) -v 2>&1)),) ifneq ($(findstring gcc,$(shell $(CC) -v 2>&1)),)
CFLAGS += -ffunction-sections -fdata-sections CFLAGS += -ffunction-sections -fdata-sections
LDFLAGS += -Wl,--gc-sections LDFLAGS += -Wl,--gc-sections
endif endif
endif
ifeq "$(DEBUG)" "0" ifeq "$(DEBUG)" "0"
CFLAGS += -O3 -DNDEBUG CFLAGS += -O3 -DNDEBUG
@ -162,6 +164,20 @@ USE_FRONTEND = 1
PLATFORM_MP3 = 1 PLATFORM_MP3 = 1
PLATFORM_ZLIB = 1 PLATFORM_ZLIB = 1
endif endif
ifeq "$(PLATFORM)" "psp"
CFLAGS += -DUSE_BGR565 -DDRAW2_OVERRIDE_LINE_WIDTH=512 -G8 # -DLPRINTF_STDIO -DFW15
platform/common/main.o: CFLAGS += -Dmain=pico_main
OBJS += platform/psp/plat.o
OBJS += platform/psp/emu.o
OBJS += platform/psp/in_psp.o
OBJS += platform/psp/psp.o
#OBJS += platform/psp/menu.o
OBJS += platform/psp/asm_utils.o
OBJS += platform/psp/mp3.o
#OBJS += platform/psp/data/bg32.o
#OBJS += platform/psp/data/bg40.o
USE_FRONTEND = 1
endif
ifeq "$(PLATFORM)" "libretro" ifeq "$(PLATFORM)" "libretro"
OBJS += platform/libretro/libretro.o OBJS += platform/libretro/libretro.o
ifeq "$(USE_LIBRETRO_VFS)" "1" ifeq "$(USE_LIBRETRO_VFS)" "1"
@ -207,6 +223,7 @@ endif
endif # USE_FRONTEND endif # USE_FRONTEND
ifneq "$(PLATFORM)" "psp"
OBJS += platform/common/mp3.o platform/common/mp3_sync.o OBJS += platform/common/mp3.o platform/common/mp3_sync.o
ifeq "$(PLATFORM_MP3)" "1" ifeq "$(PLATFORM_MP3)" "1"
OBJS += platform/common/mp3_helix.o OBJS += platform/common/mp3_helix.o
@ -215,6 +232,7 @@ OBJS += platform/common/mp3_libavcodec.o
else else
OBJS += platform/common/mp3_minimp3.o OBJS += platform/common/mp3_minimp3.o
endif endif
endif
ifeq "$(PLATFORM_ZLIB)" "1" ifeq "$(PLATFORM_ZLIB)" "1"
# zlib # zlib
@ -259,6 +277,15 @@ else
$(LD) $(LINKOUT)$@ $^ $(LDFLAGS) $(LDLIBS) $(LD) $(LINKOUT)$@ $^ $(LDFLAGS) $(LDLIBS)
endif endif
ifeq "$(PLATFORM)" "psp"
PSPSDK = /home/.build/opt/pspdev/psp/sdk
PSP_EBOOT_TITLE = PicoDrive
LIBS += -lpng -lm -lz -lpspgu -lpsppower -lpspaudio -lpsprtc -lpspaudiocodec
EXTRA_TARGETS = EBOOT.PBP
include /home/.build/opt/pspdev/psp/sdk/lib/build.mak
# TODO image generation
endif
pprof: platform/linux/pprof.c pprof: platform/linux/pprof.c
$(CC) $(CFLAGS) -O2 -ggdb -DPPROF -DPPROF_TOOL -I../../ -I. $^ -o $@ $(LDFLAGS) $(LDLIBS) $(CC) $(CFLAGS) -O2 -ggdb -DPPROF -DPPROF_TOOL -I../../ -I. $^ -o $@ $(LDFLAGS) $(LDLIBS)

View file

@ -12,6 +12,9 @@
#if defined(USE_BGR555) #if defined(USE_BGR555)
#define PXCONV(t) (t) #define PXCONV(t) (t)
#define PXPRIO 0x8000 // prio in MSB #define PXPRIO 0x8000 // prio in MSB
#elif defined(USE_BGR565)
#define PXCONV(t) (((t)&m1) | (((t)&(m2|m3)) << 1))
#define PXPRIO 0x0020 // prio in LS green bit
#else // RGB565 #else // RGB565
#define PXCONV(t) ((((t)&m1) << 11) | (((t)&m2) << 1) | (((t)&m3) >> 10)) #define PXCONV(t) ((((t)&m1) << 11) | (((t)&m2) << 1) | (((t)&m3) >> 10))
#define PXPRIO 0x0020 // prio in LS green bit #define PXPRIO 0x0020 // prio in LS green bit

View file

@ -148,7 +148,11 @@ char *PDebugSpriteList(void)
} }
#define GREEN1 0x0700 #define GREEN1 0x0700
#ifdef USE_BGR555 #if defined(USE_BGR555)
#define YELLOW1 0x039c
#define BLUE1 0x7800
#define RED1 0x001e
#elif defined(USE_BGR565)
#define YELLOW1 0x071c #define YELLOW1 0x071c
#define BLUE1 0xf000 #define BLUE1 0xf000
#define RED1 0x001e #define RED1 0x001e

View file

@ -69,6 +69,10 @@ u32 VdpSATCache[128]; // VDP sprite cache (1st 32 sprite attr bits)
#define PXCONV(t) ((t & 0x000e000e)<< 1) | ((t & 0x00e000e0)<<2) | ((t & 0x0e000e00)<<3) #define PXCONV(t) ((t & 0x000e000e)<< 1) | ((t & 0x00e000e0)<<2) | ((t & 0x0e000e00)<<3)
#define PXMASKL 0x04210421 // 0x0c630c63, LSB for all colours #define PXMASKL 0x04210421 // 0x0c630c63, LSB for all colours
#define PXMASKH 0x39ce39ce // 0x3def3def, all but MSB for all colours #define PXMASKH 0x39ce39ce // 0x3def3def, all but MSB for all colours
#elif defined(USE_BGR565)
#define PXCONV(t) ((t & 0x000e000e)<< 1) | ((t & 0x00e000e0)<<3) | ((t & 0x0e000e00)<<4)
#define PXMASKL 0x08610861 // 0x18e318e3
#define PXMASKH 0x738e738e // 0x7bef7bef
#else // RGB565 #else // RGB565
#define PXCONV(t) ((t & 0x000e000e)<<12) | ((t & 0x00e000e0)<<3) | ((t & 0x0e000e00)>>7) #define PXCONV(t) ((t & 0x000e000e)<<12) | ((t & 0x00e000e0)<<3) | ((t & 0x0e000e00)>>7)
#define PXMASKL 0x08610861 // 0x18e318e3 #define PXMASKL 0x08610861 // 0x18e318e3
@ -2004,7 +2008,7 @@ void PicoDrawSetOutFormat(pdso_t which, int use_32x_line_mode)
void PicoDrawSetOutBufMD(void *dest, int increment) void PicoDrawSetOutBufMD(void *dest, int increment)
{ {
if (FinalizeLine == FinalizeLine8bit && increment == 328) { if (FinalizeLine == FinalizeLine8bit && increment >= 328) {
// kludge for no-copy mode // kludge for no-copy mode
PicoDrawSetInternalBuf(dest, increment); PicoDrawSetInternalBuf(dest, increment);
} }

View file

@ -8,7 +8,7 @@
* *
* this is highly specialized, be careful if changing related C code! * this is highly specialized, be careful if changing related C code!
* *
* NB only does RGB565 output, BGR555 isn't supported * NB only does RGB565 output, BGR isn't supported
*/ */
#include "pico_int_offs.h" #include "pico_int_offs.h"

View file

@ -337,9 +337,12 @@ void PicoDoHighPal555M4(void)
/* cram is always stored as shorts, even though real hardware probably uses bytes */ /* cram is always stored as shorts, even though real hardware probably uses bytes */
for (i = 0x20/2; i > 0; i--, spal++, dpal++) { for (i = 0x20/2; i > 0; i--, spal++, dpal++) {
t = *spal; t = *spal;
#ifdef USE_BGR555 #if defined(USE_BGR555)
t = ((t & 0x00030003)<< 3) | ((t & 0x000c000c)<<6) | ((t & 0x00300030)<<9); t = ((t & 0x00030003)<< 3) | ((t & 0x000c000c)<<6) | ((t & 0x00300030)<<9);
t |= (t >> 2) | ((t >> 4) & 0x04210421); t |= (t >> 2) | ((t >> 4) & 0x04210421);
#elif defined(USE_BGR565)
t = ((t & 0x00030003)<< 3) | ((t & 0x000c000c)<<7) | ((t & 0x00300030)<<10);
t |= (t >> 2) | ((t >> 4) & 0x08610861);
#else #else
t = ((t & 0x00030003)<<14) | ((t & 0x000c000c)<<7) | ((t & 0x00300030)>>1); t = ((t & 0x00030003)<<14) | ((t & 0x000c000c)<<7) | ((t & 0x00300030)>>1);
t |= (t >> 2) | ((t >> 4) & 0x08610861); t |= (t >> 2) | ((t >> 4) & 0x08610861);

View file

@ -23,6 +23,17 @@
#define MENU_X2 0 #define MENU_X2 0
#endif #endif
#if defined USE_BGR555
#define COL_ROM 0x5eff
#define COL_OTH 0x5ff5
#elif defined USE_BGR565
#define COL_ROM 0xfdf7
#define COL_OTH 0xaff5
#else
#define COL_ROM 0xbdff
#define COL_OTH 0xaff5
#endif
// FIXME // FIXME
#define REVISION "0" #define REVISION "0"
@ -49,9 +60,9 @@ static unsigned short fname2color(const char *fname)
} }
for (i = 0; rom_exts[i] != NULL; i++) for (i = 0; rom_exts[i] != NULL; i++)
if (strcasecmp(ext, rom_exts[i]) == 0) return 0xbdff; // FIXME: mk defines if (strcasecmp(ext, rom_exts[i]) == 0) return COL_ROM;
for (i = 0; i < array_size(other_exts); i++) for (i = 0; i < array_size(other_exts); i++)
if (strcasecmp(ext, other_exts[i]) == 0) return 0xaff5; if (strcasecmp(ext, other_exts[i]) == 0) return COL_OTH;
return 0xffff; return 0xffff;
} }
@ -62,6 +73,8 @@ static const char *men_dummy[] = { NULL };
/* platform specific options and handlers */ /* platform specific options and handlers */
#if defined(__GP2X__) #if defined(__GP2X__)
#include <platform/gp2x/menu.c> #include <platform/gp2x/menu.c>
#elif defined(__PSP__)
#include <platform/psp/menu.c>
#elif defined(PANDORA) #elif defined(PANDORA)
#include <platform/pandora/menu.c> #include <platform/pandora/menu.c>
#else #else
@ -72,8 +85,9 @@ static const char *men_dummy[] = { NULL };
static void make_bg(int no_scale) static void make_bg(int no_scale)
{ {
unsigned short *src = (void *)g_menubg_src_ptr; unsigned short *src = (void *)g_menubg_src_ptr;
int w = g_screen_width, h = g_screen_height; int w = g_menubg_src_w ? g_menubg_src_w : g_screen_width;
int pp = g_screen_ppitch; int h = g_menubg_src_h ? g_menubg_src_h : g_screen_height;
int pp = g_menubg_src_pp ? g_menubg_src_pp : g_screen_ppitch;
short *dst; short *dst;
int x, y; int x, y;

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,7 @@
extern int engineStateSuspend; extern int engineStateSuspend;
void emu_HandleResume(void); void emu_handle_resume(void);
void emu_msg_cb(const char *msg);
// actually comes from Pico/Misc_amips.s // actually comes from Pico/Misc_amips.s
void memset32_uncached(int *dest, int c, int count); void memset32_uncached(int *dest, int c, int count);

214
platform/psp/in_psp.c Normal file
View file

@ -0,0 +1,214 @@
/*
* (C) Gražvydas "notaz" Ignotas, 2006-2012
* (C) kub 2020
*
* This work is licensed under the terms of any of these licenses
* (at your option):
* - GNU GPL, version 2 or later.
* - GNU LGPL, version 2.1 or later.
* - MAME license.
* See the COPYING file in the top-level directory.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "../libpicofe/input.h"
#include "psp.h"
#include "in_psp.h"
#define IN_PSP_PREFIX "psp:"
#define IN_PSP_NBUTTONS 32
/* note: in_psp handles combos (if 2 btns have the same bind,
* both must be pressed for action to happen) */
static int in_psp_combo_keys = 0;
static int in_psp_combo_acts = 0;
static const char *in_psp_keys[IN_PSP_NBUTTONS] = {
[0 ... IN_PSP_NBUTTONS-1] = NULL,
};
/* credits to https://graphics.stanford.edu/~seander/bithacks.html */
static int lg2(unsigned v)
{
int r, s;
r = (v > 0xFFFF) << 4; v >>= r;
s = (v > 0xFF ) << 3; v >>= s; r |= s;
s = (v > 0xF ) << 2; v >>= s; r |= s;
s = (v > 0x3 ) << 1; v >>= s; r |= s;
r |= (v >> 1);
return r;
}
static int in_psp_get_bits(void)
{
return psp_pad_read(0);
}
static void in_psp_probe(const in_drv_t *drv)
{
in_register(IN_PSP_PREFIX "PSP pad", -1, NULL,
IN_PSP_NBUTTONS, in_psp_keys, 1);
}
static void in_psp_free(void *drv_data)
{
}
static const char * const *
in_psp_get_key_names(const in_drv_t *drv, int *count)
{
*count = IN_PSP_NBUTTONS;
return in_psp_keys;
}
/* ORs result with pressed buttons */
static int in_psp_update(void *drv_data, const int *binds, int *result)
{
int type_start = 0;
int i, t, keys;
keys = in_psp_get_bits();
if (keys & in_psp_combo_keys) {
result[IN_BINDTYPE_EMU] = in_combos_do(keys, binds, IN_PSP_NBUTTONS,
in_psp_combo_keys, in_psp_combo_acts);
type_start = IN_BINDTYPE_PLAYER12;
}
for (i = 0; keys; i++, keys >>= 1) {
if (!(keys & 1))
continue;
for (t = type_start; t < IN_BINDTYPE_COUNT; t++)
result[t] |= binds[IN_BIND_OFFS(i, t)];
}
return 0;
}
int in_psp_update_keycode(void *data, int *is_down)
{
static int old_val = 0;
int val, diff, i;
val = in_psp_get_bits();
diff = val ^ old_val;
if (diff == 0)
return -1;
/* take one bit only */
for (i = 0; i < sizeof(diff)*8; i++)
if (diff & (1<<i))
break;
old_val ^= 1 << i;
if (is_down)
*is_down = !!(val & (1<<i));
return i;
}
static const struct {
short key;
short pbtn;
} key_pbtn_map[] =
{
{ PSP_CTRL_UP, PBTN_UP },
{ PSP_CTRL_DOWN, PBTN_DOWN },
{ PSP_CTRL_LEFT, PBTN_LEFT },
{ PSP_CTRL_RIGHT, PBTN_RIGHT },
{ PSP_CTRL_CIRCLE, PBTN_MOK },
{ PSP_CTRL_CROSS, PBTN_MBACK },
{ PSP_CTRL_TRIANGLE, PBTN_MA2 },
{ PSP_CTRL_SQUARE, PBTN_MA3 },
{ PSP_CTRL_LTRIGGER, PBTN_L },
{ PSP_CTRL_RTRIGGER, PBTN_R },
{ PSP_CTRL_SELECT, PBTN_MENU },
};
#define KEY_PBTN_MAP_SIZE (sizeof(key_pbtn_map) / sizeof(key_pbtn_map[0]))
static int in_psp_menu_translate(void *drv_data, int keycode, char *charcode)
{
int i;
if (keycode < 0)
{
/* menu -> kc */
keycode = -keycode;
for (i = 0; i < KEY_PBTN_MAP_SIZE; i++)
if (key_pbtn_map[i].pbtn == keycode)
return lg2(key_pbtn_map[i].key);
}
else
{
for (i = 0; i < KEY_PBTN_MAP_SIZE; i++)
if (key_pbtn_map[i].key == 1<<keycode)
return key_pbtn_map[i].pbtn;
}
return 0;
}
/* remove binds of missing keys, count remaining ones */
static int in_psp_clean_binds(void *drv_data, int *binds, int *def_binds)
{
int i, count = 0;
for (i = 0; i < IN_PSP_NBUTTONS; i++) {
int t, offs;
for (t = 0; t < IN_BINDTYPE_COUNT; t++) {
offs = IN_BIND_OFFS(i, t);
if (in_psp_keys[i] == NULL)
binds[offs] = def_binds[offs] = 0;
if (binds[offs])
count++;
}
}
in_combos_find(binds, IN_PSP_NBUTTONS, &in_psp_combo_keys, &in_psp_combo_acts);
return count;
}
static const in_drv_t in_psp_drv = {
.prefix = IN_PSP_PREFIX,
.probe = in_psp_probe,
.free = in_psp_free,
.get_key_names = in_psp_get_key_names,
.clean_binds = in_psp_clean_binds,
.update = in_psp_update,
.update_keycode = in_psp_update_keycode,
.menu_translate = in_psp_menu_translate,
};
void in_psp_init(const struct in_default_bind *defbinds)
{
in_psp_combo_keys = in_psp_combo_acts = 0;
/* fill keys array, converting key bitmasks to indexes */
in_psp_keys[lg2(PSP_CTRL_UP)] = "Up";
in_psp_keys[lg2(PSP_CTRL_LEFT)] = "Left";
in_psp_keys[lg2(PSP_CTRL_DOWN)] = "Down";
in_psp_keys[lg2(PSP_CTRL_RIGHT)] = "Right";
in_psp_keys[lg2(PSP_CTRL_START)] = "Start";
in_psp_keys[lg2(PSP_CTRL_SELECT)] = "Select";
in_psp_keys[lg2(PSP_CTRL_LTRIGGER)] = "L";
in_psp_keys[lg2(PSP_CTRL_RTRIGGER)] = "R";
in_psp_keys[lg2(PSP_CTRL_TRIANGLE)] = "Triangle";
in_psp_keys[lg2(PSP_CTRL_CIRCLE)] = "Circle";
in_psp_keys[lg2(PSP_CTRL_CROSS)] = "Cross";
in_psp_keys[lg2(PSP_CTRL_SQUARE)] = "Square";
in_register_driver(&in_psp_drv, defbinds, NULL);
}

4
platform/psp/in_psp.h Normal file
View file

@ -0,0 +1,4 @@
struct in_default_bind;
void in_psp_init(const struct in_default_bind *defbinds);

View file

@ -11,9 +11,8 @@
#include "emu.h" #include "emu.h"
#include "menu.h" #include "menu.h"
#include "mp3.h" #include "mp3.h"
#include "../common/menu.h"
#include "../common/emu.h" #include "../common/emu.h"
#include "../common/config.h" #include "../libpicofe/menu.h"
#include "../libpicofe/lprintf.h" #include "../libpicofe/lprintf.h"
#ifdef GPROF #ifdef GPROF

File diff suppressed because it is too large Load diff

View file

@ -12,7 +12,6 @@
#include <pspkernel.h> #include <pspkernel.h>
#include <pspsdk.h> #include <pspsdk.h>
#include <pspaudiocodec.h> #include <pspaudiocodec.h>
#include <kubridge.h>
#include <pico/pico_int.h> #include <pico/pico_int.h>
#include <pico/sound/mix.h> #include <pico/sound/mix.h>
@ -136,19 +135,11 @@ static int read_next_frame(int which_buffer)
static SceUID load_start_module(const char *prxname) static SceUID load_start_module(const char *prxname)
{ {
SceUID mod, mod1; SceUID mod;
int status, ret;
mod = pspSdkLoadStartModule(prxname, PSP_MEMORY_PARTITION_KERNEL); mod = pspSdkLoadStartModule(prxname, PSP_MEMORY_PARTITION_KERNEL);
if (mod < 0) { if (mod < 0) {
lprintf("failed to load %s (%08x), trying kuKernelLoadModule\n", prxname, mod); lprintf("failed to load %s (%08x), trying kuKernelLoadModule\n", prxname, mod);
mod1 = kuKernelLoadModule(prxname, 0, NULL);
if (mod1 < 0) lprintf("kuKernelLoadModule failed with %08x\n", mod1);
else {
ret = sceKernelStartModule(mod1, 0, NULL, &status, 0);
if (ret < 0) lprintf("sceKernelStartModule failed with %08x\n", ret);
else mod = mod1;
}
} }
return mod; return mod;
} }
@ -467,7 +458,7 @@ int mp3_get_offset(void) // 0-1023
int cdda_on; int cdda_on;
cdda_on = (PicoIn.AHW & PAHW_MCD) && (PicoIn.opt&0x800) && !(Pico_mcd->s68k_regs[0x36] & 1) && cdda_on = (PicoIn.AHW & PAHW_MCD) && (PicoIn.opt&0x800) && !(Pico_mcd->s68k_regs[0x36] & 1) &&
(Pico_mcd->scd.Status_CDC & 1) && mp3_handle >= 0; /* TODO (Pico_mcd->scd.Status_CDC & 1) &&*/ mp3_handle >= 0;
if (cdda_on) { if (cdda_on) {
offs1024 = mp3_src_pos << 7; offs1024 = mp3_src_pos << 7;

314
platform/psp/plat.c Normal file
View file

@ -0,0 +1,314 @@
/*
* Platform interface functions for PSP picodrive frontend
*
* (C) 2020 kub
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include "../common/emu.h"
#include "../libpicofe/menu.h"
#include "../libpicofe/plat.h"
#include <pspiofilemgr.h>
#include <pspthreadman.h>
#include <pspdisplay.h>
#include <psputils.h>
#include <psppower.h>
#include <pspgu.h>
#include <pspaudio.h>
#include "psp.h"
#include "emu.h"
#include "asm_utils.h"
#include <pico/pico_int.h>
/* graphics buffer management in VRAM:
* - VRAM_FB0, VRAM_FB1 frame buffers
* - VRAM_DEPTH Z buffer (unused)
* - VRAM_BUF0, VRAM_BUF1 emulator render buffers
* Emulator screen output is using the MD screen resolutions and is rendered
* to VRAM_BUFx and subsequently projected (that is, scaled and blitted) into
* the associated frame buffer (in PSP output resolution). Additional emulator
* output is then directly rendered to that frame buffer.
* The emulator menu is rendered directly into the frame buffers, using the
* native PSP resolution.
* Menu background uses native resolution and is copied and shaded from a frame
* buffer, or read in from a file if no emulator screen output is present.
*/
/* System level intialization */
int plat_target_init(void)
{
psp_init();
/* buffer resolutions */
g_menuscreen_w = 480, g_menuscreen_h = 272, g_menuscreen_pp = 512;
g_screen_width = 328, g_screen_height = 256, g_screen_ppitch = 512;
g_menubg_src_w = 480, g_menubg_src_h = 272, g_menubg_src_pp = 512;
/* buffer settings for menu display on startup */
g_screen_ptr = VRAM_CACHED_STUFF + (psp_screen - VRAM_FB0);
g_menuscreen_ptr = psp_screen;
g_menubg_ptr = malloc(512*272*2);
return 0;
}
/* System level deinitialization */
void plat_target_finish(void)
{
psp_finish();
}
/* display a completed frame buffer and prepare a new render buffer */
void plat_video_flip(void)
{
g_menubg_src_ptr = psp_screen;
psp_video_flip(currentConfig.EmuOpt & EOPT_VSYNC);
g_screen_ptr = VRAM_CACHED_STUFF + (psp_screen - VRAM_FB0);
plat_video_set_buffer(g_screen_ptr);
}
/* wait for start of vertical blanking */
void plat_video_wait_vsync(void)
{
sceDisplayWaitVblankStart();
}
/* switch from emulation display to menu display */
void plat_video_menu_enter(int is_rom_loaded)
{
}
/* start rendering a menu screen */
void plat_video_menu_begin(void)
{
g_menuscreen_ptr = psp_screen;
}
/* display a completed menu screen */
void plat_video_menu_end(void)
{
plat_video_wait_vsync();
plat_video_flip();
}
/* terminate menu display */
void plat_video_menu_leave(void)
{
}
/* Preliminary initialization needed at program start */
void plat_early_init(void)
{
}
/* base directory for configuration and save files */
int plat_get_root_dir(char *dst, int len)
{
if (len > 0) *dst = 0;
return 0;
}
/* base directory for emulator resources */
int plat_get_skin_dir(char *dst, int len)
{
if (len > 0) *dst = 0;
return 0;
}
/* check if path is a directory */
int plat_is_dir(const char *path)
{
SceIoStat st;
int ret = sceIoGetstat(path, &st);
return (ret >= 0 && (st.st_mode & FIO_S_IFDIR));
}
/* current time in ms */
unsigned int plat_get_ticks_ms(void)
{
/* approximate /= 1000 */
unsigned long long v64;
v64 = (unsigned long long)plat_get_ticks_us() * 4294968;
return v64 >> 32;
}
/* current time in us */
unsigned int plat_get_ticks_us(void)
{
return sceKernelGetSystemTimeLow();
}
/* sleep for some time in ms */
void plat_sleep_ms(int ms)
{
psp_msleep(ms);
}
/* sleep for some time in us */
void plat_wait_till_us(unsigned int us_to)
{
unsigned int tval;
int diff;
tval = sceKernelGetSystemTimeLow();
diff = (int)us_to - (int)tval;
if (diff >= 512 && diff < 100*1024)
sceKernelDelayThread(diff);
}
/* wait until some event occurs, or timeout */
int plat_wait_event(int *fds_hnds, int count, int timeout_ms)
{
return 0; // unused
}
/* memory mapping functions */
void *plat_mmap(unsigned long addr, size_t size, int need_exec, int is_fixed)
{
return malloc(size);
}
void *plat_mremap(void *ptr, size_t oldsize, size_t newsize)
{
return realloc(ptr, newsize);
}
void plat_munmap(void *ptr, size_t size)
{
free(ptr);
}
void *plat_mem_get_for_drc(size_t size)
{
return NULL;
}
int plat_mem_set_exec(void *ptr, size_t size)
{
return 0;
}
/* get current CPU clock */
static int plat_cpu_clock_get(void)
{
return scePowerGetCpuClockFrequencyInt();
}
/* set CPU clock */
static int plat_cpu_clock_set(int clock)
{
if (clock < 33) clock = 33;
if (clock > 333) clock = 333;
return scePowerSetClockFrequency(clock, clock, clock/2);
}
/* get battery state in percent */
static int plat_bat_capacity_get(void)
{
return scePowerGetBatteryLifePercent();
}
struct plat_target plat_target = {
.cpu_clock_get = plat_cpu_clock_get,
.cpu_clock_set = plat_cpu_clock_set,
.bat_capacity_get = plat_bat_capacity_get,
// .gamma_set = plat_gamma_set,
// .hwfilter_set = plat_hwfilter_set,
// .hwfilters = plat_hwfilters,
};
/* replacement libc stuff */
int alphasort(const struct dirent **a, const struct dirent **b)
{
return strcoll ((*a)->d_name, (*b)->d_name);
}
int scandir(const char *dir, struct dirent ***namelist_out,
int(*filter)(const struct dirent *),
int(*compar)(const struct dirent **, const struct dirent **))
{
int ret = -1, dir_uid = -1, name_alloc = 4, name_count = 0;
struct dirent **namelist = NULL, *ent;
SceIoDirent sce_ent;
namelist = malloc(sizeof(*namelist) * name_alloc);
if (namelist == NULL) { lprintf("%s:%i: OOM\n", __FILE__, __LINE__); goto fail; }
// try to read first..
dir_uid = sceIoDopen(dir);
if (dir_uid >= 0)
{
/* it is very important to clear SceIoDirent to be passed to sceIoDread(), */
/* or else it may crash, probably misinterpreting something in it. */
memset(&sce_ent, 0, sizeof(sce_ent));
ret = sceIoDread(dir_uid, &sce_ent);
if (ret < 0)
{
lprintf("sceIoDread(\"%s\") failed with %i\n", dir, ret);
goto fail;
}
}
else
lprintf("sceIoDopen(\"%s\") failed with %i\n", dir, dir_uid);
while (ret > 0)
{
ent = malloc(sizeof(*ent));
if (ent == NULL) { lprintf("%s:%i: OOM\n", __FILE__, __LINE__); goto fail; }
ent->d_stat = sce_ent.d_stat;
ent->d_stat.st_attr &= FIO_SO_IFMT; // serves as d_type
strncpy(ent->d_name, sce_ent.d_name, sizeof(ent->d_name));
ent->d_name[sizeof(ent->d_name)-1] = 0;
if (filter == NULL || filter(ent))
namelist[name_count++] = ent;
else free(ent);
if (name_count >= name_alloc)
{
void *tmp;
name_alloc *= 2;
tmp = realloc(namelist, sizeof(*namelist) * name_alloc);
if (tmp == NULL) { lprintf("%s:%i: OOM\n", __FILE__, __LINE__); goto fail; }
namelist = tmp;
}
memset(&sce_ent, 0, sizeof(sce_ent));
ret = sceIoDread(dir_uid, &sce_ent);
}
// sort
if (compar != NULL && name_count > 3)
qsort(&namelist[2], name_count - 2, sizeof(namelist[0]), (int (*)()) compar);
// all done.
ret = name_count;
*namelist_out = namelist;
goto end;
fail:
if (namelist != NULL)
{
while (name_count--)
free(namelist[name_count]);
free(namelist);
}
end:
if (dir_uid >= 0) sceIoDclose(dir_uid);
return ret;
}
int _flush_cache (char *addr, const int size, const int op)
{
sceKernelDcacheWritebackRange(addr, size);
sceKernelIcacheInvalidateRange(addr, size);
return 0;
}

View file

@ -21,24 +21,26 @@
#include "psp.h" #include "psp.h"
#include "emu.h" #include "emu.h"
#include <pico/pico_int.h> #include <pico/pico_int.h>
#include "../common/emu.h"
#include "../common/version.h" #include "../common/version.h"
extern int pico_main(void); extern int pico_main(int argc, char *argv[]);
#ifndef FW15 #ifndef FW15
PSP_MODULE_INFO("PicoDrive", 0, 1, 51); PSP_MODULE_INFO("PicoDrive", 0, 1, 97);
PSP_HEAP_SIZE_MAX(); PSP_HEAP_SIZE_MAX();
int main() { return pico_main(); } /* just a wrapper */ int main(int argc, char *argv[]) { return pico_main(argc, argv); } /* just a wrapper */
#else #else
PSP_MODULE_INFO("PicoDrive", 0x1000, 1, 51); PSP_MODULE_INFO("PicoDrive", 0x1000, 1, 97);
PSP_MAIN_THREAD_ATTR(0); PSP_MAIN_THREAD_ATTR(0);
int main() int main(int argc, char *argv[])
{ {
SceUID thid; SceUID thid;
@ -47,7 +49,7 @@ int main()
thid = sceKernelCreateThread("pico_main", (SceKernelThreadEntry) pico_main, 32, 0x2000, PSP_THREAD_ATTR_USER, NULL); thid = sceKernelCreateThread("pico_main", (SceKernelThreadEntry) pico_main, 32, 0x2000, PSP_THREAD_ATTR_USER, NULL);
if (thid >= 0) if (thid >= 0)
sceKernelStartThread(thid, 0, 0); sceKernelStartThread(thid, argc, argv);
#ifndef GCOV #ifndef GCOV
sceKernelExitDeleteThread(0); sceKernelExitDeleteThread(0);
#else #else
@ -133,7 +135,7 @@ void psp_init(void)
lprintf("\n%s\n", "PicoDrive v" VERSION " " __DATE__ " " __TIME__); lprintf("\n%s\n", "PicoDrive v" VERSION " " __DATE__ " " __TIME__);
lprintf("running on %08x kernel\n", sceKernelDevkitVersion()), lprintf("running on %08x kernel\n", sceKernelDevkitVersion()),
lprintf("entered psp_init, threadId %08x, priority %i\n", main_thread_id, lprintf("entered psp_init, threadId %08x, priority %i\n", main_thread_id,
sceKernelGetThreadCurrentPriority()); sceKernelGetThreadCurrentPriority());
thid = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, 0, NULL); thid = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, 0, NULL);
if (thid >= 0) if (thid >= 0)
@ -153,8 +155,8 @@ void psp_init(void)
sceGuStart(GU_DIRECT, guCmdList); sceGuStart(GU_DIRECT, guCmdList);
sceGuDrawBuffer(GU_PSM_5650, (void *)VRAMOFFS_FB0, 512); sceGuDrawBuffer(GU_PSM_5650, (void *)VRAMOFFS_FB0, 512);
sceGuDispBuffer(480, 272, (void *)VRAMOFFS_FB1, 512); // don't care sceGuDispBuffer(480, 272, (void *)VRAMOFFS_FB1, 512); // don't care
sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT);
sceGuDepthBuffer((void *)VRAMOFFS_DEPTH, 512); sceGuDepthBuffer((void *)VRAMOFFS_DEPTH, 512);
sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT);
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);
@ -226,11 +228,11 @@ unsigned int psp_pad_read(int blocking)
buttons = pad.Buttons; buttons = pad.Buttons;
// analog.. // analog..
buttons &= ~(PBTN_NUB_UP|PBTN_NUB_DOWN|PBTN_NUB_LEFT|PBTN_NUB_RIGHT); buttons &= ~(PSP_NUB_UP|PSP_NUB_DOWN|PSP_NUB_LEFT|PSP_NUB_RIGHT);
if (pad.Lx < 128 - ANALOG_DEADZONE) buttons |= PBTN_NUB_LEFT; if (pad.Lx < 128 - ANALOG_DEADZONE) buttons |= PSP_NUB_LEFT;
if (pad.Lx > 128 + ANALOG_DEADZONE) buttons |= PBTN_NUB_RIGHT; if (pad.Lx > 128 + ANALOG_DEADZONE) buttons |= PSP_NUB_RIGHT;
if (pad.Ly < 128 - ANALOG_DEADZONE) buttons |= PBTN_NUB_UP; if (pad.Ly < 128 - ANALOG_DEADZONE) buttons |= PSP_NUB_UP;
if (pad.Ly > 128 + ANALOG_DEADZONE) buttons |= PBTN_NUB_DOWN; if (pad.Ly > 128 + ANALOG_DEADZONE) buttons |= PSP_NUB_DOWN;
return buttons; return buttons;
} }

View file

@ -50,24 +50,9 @@ char *psp_get_status_line(void);
void psp_wait_suspend(void); void psp_wait_suspend(void);
void psp_resume_suspend(void); void psp_resume_suspend(void);
/* shorter btn names */ /* fake 'nub' btns, mapped to the 4 unused upper bits of ctrl buttons */
#define PBTN_UP PSP_CTRL_UP #define PSP_NUB_UP (1 << 28)
#define PBTN_LEFT PSP_CTRL_LEFT #define PSP_NUB_RIGHT (1 << 29)
#define PBTN_RIGHT PSP_CTRL_RIGHT #define PSP_NUB_DOWN (1 << 30)
#define PBTN_DOWN PSP_CTRL_DOWN #define PSP_NUB_LEFT (1 << 31)
#define PBTN_L PSP_CTRL_LTRIGGER
#define PBTN_R PSP_CTRL_RTRIGGER
#define PBTN_TRIANGLE PSP_CTRL_TRIANGLE
#define PBTN_CIRCLE PSP_CTRL_CIRCLE
#define PBTN_X PSP_CTRL_CROSS
#define PBTN_SQUARE PSP_CTRL_SQUARE
#define PBTN_SELECT PSP_CTRL_SELECT
#define PBTN_START PSP_CTRL_START
#define PBTN_NOTE PSP_CTRL_NOTE // doesn't seem to work?
/* fake 'nub' btns */
#define PBTN_NUB_UP (1 << 28)
#define PBTN_NUB_RIGHT (1 << 29)
#define PBTN_NUB_DOWN (1 << 30)
#define PBTN_NUB_LEFT (1 << 31)