From: kub Date: Mon, 5 Feb 2024 19:14:06 +0000 (+0100) Subject: fixes for audio and video, add psp-like scaling X-Git-Tag: v2.00~119^2~4 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4abc40d56b2f9d6bb3246b8a07925262abc55557;p=picodrive.git fixes for audio and video, add psp-like scaling --- diff --git a/platform/common/menu_pico.c b/platform/common/menu_pico.c index a9fc7900..78dfcc33 100644 --- a/platform/common/menu_pico.c +++ b/platform/common/menu_pico.c @@ -72,6 +72,8 @@ static int menu_w, menu_h; #include #elif defined(__PSP__) #include +#elif defined(__PS2__) +#include #elif defined(PANDORA) #include #else diff --git a/platform/ps2/emu.c b/platform/ps2/emu.c index 05d7d8dd..a5de6493 100644 --- a/platform/ps2/emu.c +++ b/platform/ps2/emu.c @@ -20,7 +20,7 @@ #include -#define OSD_FPS_X 220 +#define OSD_FPS_X (gsGlobal->Width - 80) /* turn black GS Screen */ #define GS_BLACK GS_SETREG_RGBA(0x00, 0x00, 0x00, 0x80) @@ -29,6 +29,8 @@ static int osd_buf_cnt, osd_cdleds; +static int out_x, out_y; +static int out_w, out_h; static float hscale, vscale; static struct in_default_bind in_ps2_defbinds[] = @@ -51,14 +53,18 @@ static struct in_default_bind in_ps2_defbinds[] = const char *renderer_names[] = { "16bit accurate", " 8bit accurate", " 8bit fast", NULL }; const char *renderer_names32x[] = { "accurate", "faster", "fastest", NULL }; enum renderer_types { RT_16BIT, RT_8BIT_ACC, RT_8BIT_FAST, RT_COUNT }; +static int is_bg_frame; static GSGLOBAL *gsGlobal; static GSTEXTURE *g_menuscreen; static GSPRIMUVPOINT *g_menuscreen_vertices; +static GSTEXTURE *g_screens[2]; +static int g_screen_index; static GSTEXTURE *g_screen; static GSPRIMUVPOINT *g_screen_vertices; +static u16 *g_screen_palette; static GSTEXTURE *osd; static uint32_t osd_vertices_count; @@ -72,84 +78,73 @@ static int32_t vsync_callback_id; static uint8_t vsync; /* 0 (Disabled), 1 (Enabled), 2 (Dynamic) */ /* sound stuff */ -#define SOUND_BLOCK_SIZE_NTSC (1470*2) // 1024 // 1152 -#define SOUND_BLOCK_SIZE_PAL (1764*2) #define SOUND_BLOCK_COUNT 8 +#define SOUND_BUFFER_SIZE (2*54000/50*SOUND_BLOCK_COUNT) // max.rate/min.frames -static short __attribute__((aligned(4))) sndBuffer[SOUND_BLOCK_SIZE_PAL*SOUND_BLOCK_COUNT + 54000/50*2]; +static short __attribute__((aligned(4))) sndBuffer[SOUND_BUFFER_SIZE]; static short *snd_playptr = NULL, *sndBuffer_endptr = NULL; static int samples_made = 0, samples_done = 0, samples_block = 0; static int sound_thread_exit = 0; static int32_t sound_sem = -1; -static uint8_t stack[0x10000] __attribute__((aligned(16))); +static uint8_t stack[0x4000] __attribute__((aligned(16))); extern void *_gp; static int mp3_init(void) { return 0; } static void writeSound(int len) { - int ret; - - // printf("writeSound, len: %i\n", len); + int ret, l; PicoIn.sndOut += len / 2; - /*if (PicoIn.sndOut > sndBuffer_endptr) { - memcpy((int *)(void *)sndBuffer, (int *)endptr, (PicoIn.sndOut - endptr + 1) * 2); - PicoIn.sndOut = &sndBuffer[PicoIn.sndOut - endptr]; - lprintf("mov\n"); - } - else*/ - if (PicoIn.sndOut > sndBuffer_endptr) lprintf("snd oflow %i!\n", PicoIn.sndOut - sndBuffer_endptr); - if (PicoIn.sndOut >= sndBuffer_endptr) + + l = PicoIn.sndOut - sndBuffer; + if (l > sizeof(sndBuffer)/2) + lprintf("ovfl %d %d\n", len, PicoIn.sndOut - sndBuffer); + if (l > samples_block * 6) { + sndBuffer_endptr = PicoIn.sndOut; PicoIn.sndOut = sndBuffer; + } + if (sndBuffer_endptr < PicoIn.sndOut) + sndBuffer_endptr = PicoIn.sndOut; // signal the snd thread samples_made += len / 2; - if (samples_made - samples_done > samples_block*2) { - lprintf("signal, %i/%i\n", samples_done, samples_made); - ret = SignalSema(sound_sem); - //if (ret < 0) lprintf("snd signal ret %08x\n", ret); - } +// lprintf("signal, %i/%i\n", samples_done, samples_made); + ret = SignalSema(sound_sem); +// if (ret < 0) lprintf("snd signal ret %08x\n", ret); } static int sound_thread(void *argp) { - int ret = 0; - while (!sound_thread_exit) { + int ret = 0; + if (samples_made - samples_done < samples_block) { // wait for data (use at least 2 blocks) - //lprintf("sthr: wait... (%i)\n", samples_made - samples_done); - while (samples_made - samples_done <= samples_block*2 && !sound_thread_exit) { - printf("sthr: WaitSema\n"); +// lprintf("sthr: wait... (%i)\n", samples_made - samples_done); + while (samples_made - samples_done < samples_block*2 && !sound_thread_exit) ret = WaitSema(sound_sem); - } if (ret < 0) lprintf("sthr: WaitSema: %i\n", ret); continue; } +// lprintf("sthr: got data: %i\n", samples_made - samples_done); + short *sndOut = PicoIn.sndOut, *sndEnd = sndBuffer_endptr; + int buflen = samples_block * 2; + if (sndOut >= snd_playptr) + buflen = sndOut - snd_playptr; + else buflen = sndEnd - snd_playptr; + if (buflen > samples_block) + buflen = samples_block; + ret = audsrv_play_audio((char *)snd_playptr, buflen*2); +// if (ret != buflen*2 && ret >= 0) lprintf("sthr: play ret: %i, buflen: %i\n", ret, buflen*2); + if (ret < 0) lprintf("sthr: play: ret %08x; pos %i/%i\n", ret, samples_done, samples_made); + + samples_done += buflen; + snd_playptr += buflen; - // lprintf("sthr: got data: %i\n", samples_made - samples_done); - int buflen = samples_block * 2; - ret = (audsrv_play_audio((char *)snd_playptr, buflen) != buflen) ? -1 : 0; - printf("audsrv_play_audio ret: %i, buflen: %i\n", ret, buflen); - // ret = sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, snd_playptr); - - samples_done += samples_block; - snd_playptr += samples_block; if (snd_playptr >= sndBuffer_endptr) snd_playptr = sndBuffer; - // 1.5 kernel returns 0, newer ones return # of samples queued - if (ret < 0) - lprintf("sthr: audsrv_play_audio: %08x; pos %i/%i\n", ret, samples_done, samples_made); - - // shouln't happen, but just in case - if (samples_made - samples_done >= samples_block*3) { - //lprintf("sthr: block skip (%i)\n", samples_made - samples_done); - samples_done += samples_block; // skip - snd_playptr += samples_block; - } - } lprintf("sthr: exit\n"); @@ -162,36 +157,39 @@ static void sound_init(void) int thid; int ret; ee_sema_t sema; - ee_thread_t thread; - - sema.max_count = 1; - sema.init_count = 0; - sema.option = (u32) "sndsem"; - if ((sound_sem = CreateSema(&sema)) < 0) - return; - - thread.func = &sound_thread; - thread.stack = stack; - thread.stack_size = sizeof(stack); - thread.gp_reg = &_gp; - thread.option = (u32) "sndthread"; - thread.initial_priority = 0x12; - thid = CreateThread(&thread); - - if (thid >= 0) { + ee_thread_t thread; + + sema.max_count = 1; + sema.init_count = 0; + sema.option = (u32) "sndsem"; + if ((sound_sem = CreateSema(&sema)) < 0) + return; + audsrv_init(); + + thread.func = &sound_thread; + thread.stack = stack; + thread.stack_size = sizeof(stack); + thread.gp_reg = &_gp; + thread.option = (u32) "sndthread"; + thread.initial_priority = 40; + thid = CreateThread(&thread); + + samples_block = 22050/50; // needs to be initialized before thread start + if (thid >= 0) { ret = StartThread(thid, NULL); if (ret < 0) lprintf("sound_init: StartThread returned %08x\n", ret); - }else { - DeleteSema(sound_sem); + ChangeThreadPriority(0, 64); + } else { + DeleteSema(sound_sem); lprintf("CreateThread failed: %i\n", thid); - } + } } void pemu_sound_start(void) { - static int PsndRate_old = 0, PicoOpt_old = 0, pal_old = 0; + static int PsndRate_old = 0, PicoOpt_old = 0, pal_old = 0; static int mp3_init_done; int ret, stereo; - struct audsrv_fmt_t format; + struct audsrv_fmt_t format; samples_made = samples_done = 0; @@ -215,49 +213,35 @@ void pemu_sound_start(void) { } stereo=(PicoIn.opt&8)>>3; - samples_block = Pico.m.pal ? SOUND_BLOCK_SIZE_PAL : SOUND_BLOCK_SIZE_NTSC; - printf("samples_block: %i\n", samples_block); - if (PicoIn.sndRate <= 22050) samples_block /= 2; - sndBuffer_endptr = &sndBuffer[samples_block*SOUND_BLOCK_COUNT]; + samples_block = PicoIn.sndRate * (stereo ? 2 : 1) / (Pico.m.pal ? 50 : 60); lprintf("starting audio: %i, len: %i, stereo: %i, pal: %i, block samples: %i\n", PicoIn.sndRate, Pico.snd.len, stereo, Pico.m.pal, samples_block); format.bits = 16; - format.freq = PicoIn.sndRate; - format.channels = 2; + format.freq = PicoIn.sndRate; + format.channels = 2; ret = audsrv_set_format(&format); - audsrv_set_volume(MAX_VOLUME); + audsrv_set_volume(MAX_VOLUME); if (ret < 0) { lprintf("audsrv_set_format() failed: %i\n", ret); emu_status_msg("sound init failed (%i), snd disabled", ret); currentConfig.EmuOpt &= ~EOPT_EN_SOUND; } else { PicoIn.writeSound = writeSound; - memset32((int *)(void *)sndBuffer, 0, sizeof(sndBuffer)/4); - snd_playptr = sndBuffer_endptr - samples_block; - samples_made = samples_block; // send 1 empty block first.. - PicoIn.sndOut = sndBuffer; + snd_playptr = PicoIn.sndOut = sndBuffer_endptr = sndBuffer; + PsndRate_old = PicoIn.sndRate; PicoOpt_old = PicoIn.opt; pal_old = Pico.m.pal; } + ret = audsrv_play_audio((char *)snd_playptr, 4); } void pemu_sound_stop(void) { - int i; - if (samples_done == 0) - { - // if no data is written between sceAudioSRCChReserve and sceAudioSRCChRelease calls, - // we get a deadlock on next sceAudioSRCChReserve call - // so this is yet another workaround: - memset32((int *)(void *)sndBuffer, 0, samples_block*4/4); - samples_made = samples_block * 3; - SignalSema(sound_sem); - } - plat_sleep_ms(100); samples_made = samples_done = 0; + plat_sleep_ms(100); audsrv_stop_audio(); } @@ -270,192 +254,297 @@ static void sound_deinit(void) } #define is_16bit_mode() \ - (currentConfig.renderer == RT_16BIT || (PicoIn.AHW & PAHW_32X)) + (currentConfig.renderer == RT_16BIT || (PicoIn.AHW & PAHW_32X) || is_bg_frame) static int vsync_handler(void) { - iSignalSema(vsync_sema_id); + iSignalSema(vsync_sema_id); + + ExitHandler(); + return 0; +} + +/* Copy of gsKit_sync_flip, but without the 'flip' */ +static void gsKit_sync(GSGLOBAL *gsGlobal) +{ + if (!gsGlobal->FirstFrame) + WaitSema(vsync_sema_id); + + while (PollSema(vsync_sema_id) >= 0); +} + +/* Copy of gsKit_sync_flip, but without the 'sync' */ +static void gsKit_flip(GSGLOBAL *gsGlobal) +{ + if (!gsGlobal->FirstFrame) + { + if (gsGlobal->DoubleBuffering == GS_SETTING_ON) + { + GS_SET_DISPFB2(gsGlobal->ScreenBuffer[gsGlobal->ActiveBuffer & 1] / 8192, + gsGlobal->Width / 64, gsGlobal->PSM, 0, 0); + + gsGlobal->ActiveBuffer ^= 1; + } + } + + gsKit_setactive(gsGlobal); +} + +static void flipScreen() +{ + gsKit_flip(gsGlobal); - ExitHandler(); - return 0; + gsKit_TexManager_nextFrame(gsGlobal); } -static void set_g_menuscreen_values() + +static void set_g_menuscreen_values(void) { - if (g_menuscreen != NULL) { - free(g_menuscreen->Mem); - free(g_menuscreen); - free(g_menubg_ptr); - free(g_menuscreen_vertices); - } - g_menuscreen = (GSTEXTURE *)calloc(1, sizeof(GSTEXTURE)); - size_t g_menuscreenSize = gsKit_texture_size_ee(gsGlobal->Width, gsGlobal->Height, GS_PSM_CT16); - g_menuscreen->Width = gsGlobal->Width; - g_menuscreen->Height = gsGlobal->Height; - g_menuscreen->PSM = GS_PSM_CT16; - g_menuscreen->Mem = malloc(g_menuscreenSize); + size_t g_menuscreenSize = gsKit_texture_size_ee(gsGlobal->Width, gsGlobal->Height, GS_PSM_CT16); - g_menubg_ptr = (uint8_t *)malloc(g_menuscreenSize); + g_menuscreen = (GSTEXTURE *)calloc(1, sizeof(GSTEXTURE)); + g_menuscreen->Mem = malloc(g_menuscreenSize); + g_menuscreen_vertices = (GSPRIMUVPOINT *)calloc(2, sizeof(GSPRIMUVPOINT)); - g_menuscreen_w = g_menuscreen->Width; - g_menuscreen_h = g_menuscreen->Height; - g_menuscreen_pp = g_menuscreen->Width; - g_menuscreen_ptr = g_menuscreen->Mem; + g_menuscreen->Width = gsGlobal->Width; + g_menuscreen->Height = gsGlobal->Height; + g_menuscreen->PSM = GS_PSM_CT16; - g_menubg_src_w = g_menuscreen->Width; - g_menubg_src_h = g_menuscreen->Height; - g_menubg_src_pp = g_menuscreen->Width; + g_menuscreen_w = g_menuscreen->Width; + g_menuscreen_h = g_menuscreen->Height; + g_menuscreen_pp = g_menuscreen->Width; + g_menuscreen_ptr = g_menuscreen->Mem; - g_menuscreen_vertices = (GSPRIMUVPOINT *)calloc(2, sizeof(GSPRIMUVPOINT)); - - g_menuscreen_vertices[0].xyz2 = vertex_to_XYZ2(gsGlobal, 0, 0, 2); + g_menuscreen_vertices[0].xyz2 = vertex_to_XYZ2(gsGlobal, 0, 0, 2); g_menuscreen_vertices[0].uv = vertex_to_UV(g_menuscreen, 0, 0); g_menuscreen_vertices[0].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); - g_menuscreen_vertices[1].xyz2 = vertex_to_XYZ2(gsGlobal, g_menuscreen->Width, g_menuscreen->Height, 2); - g_menuscreen_vertices[1].uv = vertex_to_UV(g_menuscreen, g_menuscreen->Width, g_menuscreen->Height); - g_menuscreen_vertices[1].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); + g_menuscreen_vertices[1].xyz2 = vertex_to_XYZ2(gsGlobal, g_menuscreen->Width, g_menuscreen->Height, 2); + g_menuscreen_vertices[1].uv = vertex_to_UV(g_menuscreen, g_menuscreen->Width, g_menuscreen->Height); + g_menuscreen_vertices[1].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); } void set_g_screen_values() { - if (g_screen != NULL) { - free(g_screen->Mem); - free(g_screen); - free(g_screen_vertices); - } - g_screen = (GSTEXTURE *)calloc(1, sizeof(GSTEXTURE)); - size_t g_screenSize = gsKit_texture_size_ee(328, 256, GS_PSM_CT16); - g_screen->Width = 328; - g_screen->Height = 256; - g_screen->PSM = GS_PSM_CT16; - g_screen->Mem = (uint32_t *)malloc(g_screenSize); - - g_screen_width = 328; - g_screen_height = 256; - g_screen_ppitch = 328; - g_screen_ptr = g_screen->Mem; - - g_screen_vertices = (GSPRIMUVPOINT *)calloc(2, sizeof(GSPRIMUVPOINT)); - - g_screen_vertices[0].xyz2 = vertex_to_XYZ2(gsGlobal, 0, 0, 0); - g_screen_vertices[0].uv = vertex_to_UV(g_screen, 0, 0); - g_screen_vertices[0].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); - - g_screen_vertices[1].xyz2 = vertex_to_XYZ2(gsGlobal, gsGlobal->Width, gsGlobal->Height, 0); - g_screen_vertices[1].uv = vertex_to_UV(g_screen, g_screen->Width, g_screen->Height); - g_screen_vertices[1].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); - - if (is_16bit_mode()) - PicoDrawSetOutBuf(g_screen_ptr, g_screen_ppitch * 2); - else - PicoDrawSetOutBuf(g_screen_ptr, g_screen_ppitch); + size_t g_screenSize = gsKit_texture_size_ee(328, 256, GS_PSM_CT16); + int i; + + g_screen_palette = malloc(gsKit_texture_size_ee(16, 16, GS_PSM_CT16)); + g_screen_vertices = (GSPRIMUVPOINT *)calloc(2, sizeof(GSPRIMUVPOINT)); + for (i = 0; i < 2; i++) { + g_screens[i] = (GSTEXTURE *)calloc(1, sizeof(GSTEXTURE)); + g_screens[i]->Mem = (uint32_t *)malloc(g_screenSize); + + g_screens[i]->Width = 328; + g_screens[i]->Height = 256; + g_screens[i]->PSM = GS_PSM_CT16; + g_screens[i]->Filter = GS_FILTER_LINEAR; + + g_screens[i]->Clut = g_screen_palette; + g_screens[i]->ClutPSM = GS_PSM_CT16; + } + g_screen = g_screens[g_screen_index]; + g_screen_ptr = g_screen->Mem; + + g_screen_width = 328; + g_screen_height = 256; + g_screen_ppitch = 328; + + g_screen_vertices[0].xyz2 = vertex_to_XYZ2(gsGlobal, 0, 0, 0); + g_screen_vertices[0].uv = vertex_to_UV(g_screen, 0, 0); + g_screen_vertices[0].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); + + g_screen_vertices[1].xyz2 = vertex_to_XYZ2(gsGlobal, gsGlobal->Width, gsGlobal->Height, 0); + g_screen_vertices[1].uv = vertex_to_UV(g_screen, g_screen->Width, g_screen->Height); + g_screen_vertices[1].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); } void set_cdleds_values() { - if (cdleds != NULL) { - free(cdleds->Mem); - free(cdleds); - free(cdleds_vertices); - } - cdleds = (GSTEXTURE *)calloc(1, sizeof(GSTEXTURE)); - size_t cdledsSize = gsKit_texture_size_ee(14, 5, GS_PSM_CT16); - cdleds->Width = 14; - cdleds->Height = 5; - cdleds->PSM = GS_PSM_CT16; - cdleds->Mem = (uint32_t *)malloc(cdledsSize); - - cdleds_vertices = (GSPRIMUVPOINT *)calloc(2, sizeof(GSPRIMUVPOINT)); - - cdleds_vertices[0].xyz2 = vertex_to_XYZ2(gsGlobal, 4, 1, 1); - cdleds_vertices[0].uv = vertex_to_UV(cdleds, 0, 0); - cdleds_vertices[0].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); - - cdleds_vertices[1].xyz2 = vertex_to_XYZ2(gsGlobal, cdleds->Width, cdleds->Height, 1); - cdleds_vertices[1].uv = vertex_to_UV(cdleds, cdleds->Width, cdleds->Height); - cdleds_vertices[1].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); + size_t cdledsSize = gsKit_texture_size_ee(14, 5, GS_PSM_CT16); + + cdleds = (GSTEXTURE *)calloc(1, sizeof(GSTEXTURE)); + cdleds->Mem = (uint32_t *)malloc(cdledsSize); + cdleds_vertices = (GSPRIMUVPOINT *)calloc(2, sizeof(GSPRIMUVPOINT)); + + cdleds->Width = 14; + cdleds->Height = 5; + cdleds->PSM = GS_PSM_CT16; + + cdleds_vertices[0].xyz2 = vertex_to_XYZ2(gsGlobal, 4, 1, 1); + cdleds_vertices[0].uv = vertex_to_UV(cdleds, 0, 0); + cdleds_vertices[0].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); + + cdleds_vertices[1].xyz2 = vertex_to_XYZ2(gsGlobal, cdleds->Width, cdleds->Height, 1); + cdleds_vertices[1].uv = vertex_to_UV(cdleds, cdleds->Width, cdleds->Height); + cdleds_vertices[1].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); } void set_osd_values() { - if (osd != NULL) { - free(osd->Mem); - free(osd); - free(osd_vertices); - } - osd = (GSTEXTURE *)calloc(1, sizeof(GSTEXTURE)); - size_t osdSize = gsKit_texture_size_ee(512, 8, GS_PSM_CT16); - osd->Width = 512; - osd->Height = 8; - osd->PSM = GS_PSM_CT16; - osd->Mem = (uint32_t *)malloc(osdSize); - - osd_vertices_count = 2; - osd_vertices = (GSPRIMUVPOINT *)calloc(osd_vertices_count, sizeof(GSPRIMUVPOINT)); - - osd_vertices[0].xyz2 = vertex_to_XYZ2(gsGlobal, 0, 0, 1); - osd_vertices[0].uv = vertex_to_UV(osd, 0, 0); - osd_vertices[0].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); - - osd_vertices[1].xyz2 = vertex_to_XYZ2(gsGlobal, osd->Width, osd->Height, 1); - osd_vertices[1].uv = vertex_to_UV(osd, osd->Width, osd->Height); - osd_vertices[1].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); + size_t osdSize = gsKit_texture_size_ee(gsGlobal->Width, 8, GS_PSM_CT16); + int num_osds = 4, i; + + osd = (GSTEXTURE *)calloc(1, sizeof(GSTEXTURE)); + osd->Mem = (uint32_t *)malloc(osdSize); + + osd_vertices_count = 2*num_osds; + osd_vertices = (GSPRIMUVPOINT *)calloc(osd_vertices_count, sizeof(GSPRIMUVPOINT)); + + osd->Width = gsGlobal->Width; + osd->Height = 8; + osd->PSM = GS_PSM_CT16; + + for (i = 0; i < 2*num_osds; i++) + osd_vertices[i].rgbaq = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0); } static void video_init(void) { - ee_sema_t sema; + ee_sema_t sema; + + sema.init_count = 0; + sema.max_count = 1; + sema.option = 0; - sema.init_count = 0; - sema.max_count = 1; - sema.option = 0; + vsync_sema_id = CreateSema(&sema); - vsync_sema_id = CreateSema(&sema); + gsGlobal = gsKit_init_global(); +// gsGlobal->Mode = GS_MODE_NTSC; +// gsGlobal->Height = 448; - gsGlobal = gsKit_init_global(); - gsGlobal->Mode = GS_MODE_NTSC; - gsGlobal->Height = 448; + gsGlobal->PSM = GS_PSM_CT16; + gsGlobal->PSMZ = GS_PSMZ_16S; + gsGlobal->ZBuffering = GS_SETTING_OFF; + gsGlobal->DoubleBuffering = GS_SETTING_ON; + gsGlobal->PrimAlphaEnable = GS_SETTING_OFF; + gsGlobal->Dithering = GS_SETTING_OFF; - gsGlobal->PSM = GS_PSM_CT24; - gsGlobal->PSMZ = GS_PSMZ_16S; - gsGlobal->ZBuffering = GS_SETTING_OFF; - gsGlobal->DoubleBuffering = GS_SETTING_ON; - gsGlobal->PrimAlphaEnable = GS_SETTING_OFF; - gsGlobal->Dithering = GS_SETTING_OFF; + dmaKit_init(D_CTRL_RELE_OFF, D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC, D_CTRL_STD_OFF, D_CTRL_RCYC_8, 1 << DMA_CHANNEL_GIF); + dmaKit_chan_init(DMA_CHANNEL_GIF); - dmaKit_init(D_CTRL_RELE_OFF, D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC, D_CTRL_STD_OFF, D_CTRL_RCYC_8, 1 << DMA_CHANNEL_GIF); - dmaKit_chan_init(DMA_CHANNEL_GIF); + gsKit_set_clamp(gsGlobal, GS_CMODE_REPEAT); - gsKit_set_clamp(gsGlobal, GS_CMODE_REPEAT); + gsKit_vram_clear(gsGlobal); + gsKit_init_screen(gsGlobal); + gsKit_TexManager_init(gsGlobal); + gsKit_mode_switch(gsGlobal, GS_ONESHOT); + gsKit_clear(gsGlobal, GS_BLACK); + vsync = 0; + vsync_callback_id = gsKit_add_vsync_handler(vsync_handler); - gsKit_vram_clear(gsGlobal); - gsKit_init_screen(gsGlobal); - gsKit_TexManager_init(gsGlobal); - gsKit_mode_switch(gsGlobal, GS_ONESHOT); - gsKit_clear(gsGlobal, GS_BLACK); - vsync = 0; - vsync_callback_id = gsKit_add_vsync_handler(vsync_handler); + set_g_screen_values(); + set_g_menuscreen_values(); + set_osd_values(); + set_cdleds_values(); - set_g_menuscreen_values(); + g_menubg_ptr = (uint8_t *)malloc(2 * g_menuscreen_pp * g_menuscreen_h); + g_menubg_src_w = g_screen->Width; + g_menubg_src_h = g_screen->Height; + g_menubg_src_pp = g_screen->Width; } static void video_deinit(void) { - free(g_menuscreen->Mem); - free(g_menuscreen); - free(g_menuscreen_vertices); - free(g_menubg_ptr); + free(g_screens[0]->Mem); + free(g_screens[0]); + free(g_screens[1]->Mem); + free(g_screens[1]); + free(g_screen_vertices); + free(g_screen_palette); - gsKit_clear(gsGlobal, GS_BLACK); - gsKit_vram_clear(gsGlobal); - gsKit_deinit_global(gsGlobal); - gsKit_remove_vsync_handler(vsync_callback_id); + free(g_menuscreen->Mem); + free(g_menuscreen); + free(g_menuscreen_vertices); + free(g_menubg_ptr); - if (vsync_sema_id >= 0) - DeleteSema(vsync_sema_id); + free(osd->Mem); + free(osd); + free(osd_vertices); + + free(cdleds->Mem); + free(cdleds); + free(cdleds_vertices); + + gsKit_clear(gsGlobal, GS_BLACK); + gsKit_vram_clear(gsGlobal); + gsKit_deinit_global(gsGlobal); + gsKit_remove_vsync_handler(vsync_callback_id); + + if (vsync_sema_id >= 0) + DeleteSema(vsync_sema_id); +} + +static void set_scaling_params(void) +{ + int width, height, xoffs, yoffs; + int u[2], v[2]; + + height = (int)(out_h * vscale + 0.5); + width = (int)(out_w * hscale + 0.5); + + if (width & 1) width++; // make even + if (height & 1) height++; + + if (width >= gsGlobal->Width) { + u[0] = out_x + (width-gsGlobal->Width)/2; + u[1] = out_x + out_w - (width-gsGlobal->Width)/2 - 1; + width = gsGlobal->Width; + xoffs = 0; + } else { + u[0] = out_x; + u[1] = out_x + out_w; + xoffs = gsGlobal->Width/2 - width/2; + } + + if (height >= gsGlobal->Height) { + v[0] = out_y + (height-gsGlobal->Height)/2; + v[1] = out_y + out_h - (height-gsGlobal->Height)/2; + height = gsGlobal->Height; + yoffs = 0; + } else { + v[0] = out_y; + v[1] = out_y + out_h; + yoffs = gsGlobal->Height/2 - height/2; + } + + if (xoffs < 0) xoffs = 0; + if (yoffs < 0) yoffs = 0; + g_screen_vertices[0].xyz2 = vertex_to_XYZ2(gsGlobal, xoffs, yoffs, 0); + g_screen_vertices[1].xyz2 = vertex_to_XYZ2(gsGlobal, xoffs + width, yoffs + height, 0); + + if (!is_16bit_mode()) { + // 8-bit modes have an 8 px overlap area on the left + u[0] += 8; u[1] += 8; + } + g_screen_vertices[0].uv = vertex_to_UV(g_screen, u[0], v[0]); + g_screen_vertices[1].uv = vertex_to_UV(g_screen, u[1], v[1]); + +// lprintf("set_scaling_params: wxh = %ix%i\n",gsGlobal->Width,gsGlobal->Height); +// lprintf("offs: %i, %i wh: %i, %i\n", xoffs, yoffs, width, height); +// lprintf("uv0, uv1: %i, %i; %i, %i\n", u[0], v[0], u[1], v[1]); +} + +static void make_ps2_palette(void) +{ + PicoDrawUpdateHighPal(); + + // Rotate CLUT. PS2 is special since entries in CLUT are not in sequence. + unsigned short int *pal=(void *)g_screen_palette; + int i; + + for (i = 0; i < 256; i+=8) { + if ((i&0x18) == 0x08) + memcpy(pal+i,Pico.est.HighPal+i+8,16); + else if ((i&0x18) == 0x10) + memcpy(pal+i,Pico.est.HighPal+i-8,16); + else + memcpy(pal+i,Pico.est.HighPal+i,16); + } } static int get_renderer(void) { + if (is_bg_frame) + return RT_16BIT; if (PicoIn.AHW & PAHW_32X) return currentConfig.renderer32x; else @@ -480,7 +569,6 @@ static void change_renderer(int diff) static void apply_renderer(void) { PicoIn.opt &= ~(POPT_ALT_RENDERER|POPT_EN_SOFTSCALE); - PicoIn.opt |= POPT_DIS_32C_BORDER; switch (get_renderer()) { case RT_16BIT: @@ -496,57 +584,65 @@ static void apply_renderer(void) } } -static void osd_text(int x, const char *text) +static void blit_screen(void) { - // int len = strlen(text) * 8; - // int *p, h; - // void *tmp = g_screen_ptr; - // printf("osd_text, text: %s\n", text); + if (!is_16bit_mode() && Pico.m.dirtyPal) + make_ps2_palette(); - // g_screen_ptr = osd_buf; - // for (h = 0; h < 8; h++) { - // p = (int *) (osd_buf+x+512*h); - // p = (int *) ((int)p & ~3); // align - // memset32_uncached(p, 0, len/2); - // } - // emu_text_out16(x, 0, text); - // g_screen_ptr = tmp; + g_screen->PSM = is_16bit_mode() ? GS_PSM_CT16 : GS_PSM_T8; + g_screen->Filter = (currentConfig.filter ? GS_FILTER_LINEAR : GS_FILTER_NEAREST); - // osd_buf_x[osd_buf_cnt] = x; - // osd_buf_l[osd_buf_cnt] = len; - // osd_buf_cnt ++; + gsKit_TexManager_bind(gsGlobal, g_screen); + gskit_prim_list_sprite_texture_uv_3d(gsGlobal, g_screen, 2, g_screen_vertices); } -static void blit_screen(void) +static void osd_text(int x, const char *text) { - gsKit_TexManager_invalidate(gsGlobal, g_screen); + void *old_ptr = g_screen_ptr; + int old_pitch = g_screen_ppitch; + + int len = strlen(text) * 8; + u16 *osd_buf = osd->Mem; + int *p, h; + + g_screen_ptr = osd_buf; + g_screen_ppitch = gsGlobal->Width; + for (h = 0; h < 8; h++) { + p = (int *) (osd_buf + x + gsGlobal->Width*h); + p = (int *) ((int)p & ~3); // align + memset32_uncached(p, 0, len/2); + } + emu_text_out16(x, 0, text); + g_screen_ptr = old_ptr; + g_screen_ppitch = old_pitch; - gsKit_TexManager_bind(gsGlobal, g_screen); - gskit_prim_list_sprite_texture_uv_3d( - gsGlobal, - g_screen, - 2, - g_screen_vertices - ); + osd_vertices[osd_buf_cnt].xyz2 = vertex_to_XYZ2(gsGlobal, x, gsGlobal->Height-8, 1); + osd_vertices[osd_buf_cnt].uv = vertex_to_UV(osd, x, 0); + osd_vertices[osd_buf_cnt+1].xyz2 = vertex_to_XYZ2(gsGlobal, x+len, gsGlobal->Height, 1); + osd_vertices[osd_buf_cnt+1].uv = vertex_to_UV(osd, x+len, 8); + osd_buf_cnt += 2; } static void blit_osd(void) { - + gsKit_TexManager_bind(gsGlobal, osd); + while (osd_buf_cnt > 0) { + osd_buf_cnt -= 2; + gskit_prim_list_sprite_texture_uv_3d(gsGlobal, osd, 2, osd_vertices+osd_buf_cnt); + } } static void cd_leds(void) { - unsigned int reg, col_g, col_r, *p; - gsKit_TexManager_invalidate(gsGlobal, cdleds); + unsigned int reg, col_g, col_r, *p; reg = Pico_mcd->s68k_regs[0]; p = (unsigned int *)cdleds->Mem; col_g = (reg & 2) ? 0x06000600 : 0; col_r = (reg & 1) ? 0x00180018 : 0; - *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += 512/2 - 12/2; - *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += 512/2 - 12/2; + *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += gsGlobal->Width/2 - 12/2; + *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += gsGlobal->Width/2 - 12/2; *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; osd_cdleds = 1; @@ -554,126 +650,131 @@ static void cd_leds(void) static void blit_cdleds(void) { - if (!osd_cdleds) return; + if (!osd_cdleds) return; - gsKit_TexManager_bind(gsGlobal, cdleds); - gskit_prim_list_sprite_texture_uv_3d( - gsGlobal, - cdleds, - 2, - cdleds_vertices - ); + gsKit_TexManager_bind(gsGlobal, cdleds); + gskit_prim_list_sprite_texture_uv_3d(gsGlobal, cdleds, 2, cdleds_vertices); } static void draw_pico_ptr(void) { - // unsigned char *p = (unsigned char *)g_screen_ptr + 8; + int x = pico_pen_x, y = pico_pen_y, offs; + int pp = g_screen_ppitch; - // // only if pen enabled and for 8bit mode - // if (pico_inp_mode == 0 || is_16bit_mode()) return; + x = (x * out_w * ((1ULL<<32) / 320)) >> 32; + y = (y * out_h * ((1ULL<<32) / 224)) >> 32; - // p += 512 * (pico_pen_y + PICO_PEN_ADJUST_Y); - // p += pico_pen_x + PICO_PEN_ADJUST_X; - // if (!(Pico.video.reg[12]&1) && !(PicoIn.opt & POPT_DIS_32C_BORDER)) - // p += 32; + offs = g_screen_ppitch * (out_y+y) + (out_x+x); - // p[ -1] = 0xe0; p[ 0] = 0xf0; p[ 1] = 0xe0; - // p[ 511] = 0xf0; p[ 512] = 0xf0; p[ 513] = 0xf0; - // p[1023] = 0xe0; p[1024] = 0xf0; p[1025] = 0xe0; -} + if (is_16bit_mode()) { + unsigned short *p = (unsigned short *)g_screen_ptr + offs; -static void vidResetMode(void) {} + p[ -1] = 0x0000; p[ 0] = 0x001f; p[ 1] = 0x0000; + p[ pp-1] = 0x001f; p[ pp] = 0x001f; p[ pp+1] = 0x001f; + p[2*pp-1] = 0x0000; p[2*pp] = 0x001f; p[2*pp+1] = 0x0000; + } else { + unsigned char *p = (unsigned char *)g_screen_ptr + offs + 8; -/* Copy of gsKit_sync_flip, but without the 'flip' */ -static void gsKit_sync(GSGLOBAL *gsGlobal) + p[ -1] = 0xe0; p[ 0] = 0xf0; p[ 1] = 0xe0; + p[ pp-1] = 0xf0; p[ pp] = 0xf0; p[ pp+1] = 0xf0; + p[2*pp-1] = 0xe0; p[2*pp] = 0xf0; p[2*pp+1] = 0xe0; + } +} + +static void vidResetMode(void) { - if (!gsGlobal->FirstFrame) - WaitSema(vsync_sema_id); + set_scaling_params(); - while (PollSema(vsync_sema_id) >= 0); + Pico.m.dirtyPal = 1; } -/* Copy of gsKit_sync_flip, but without the 'sync' */ -static void gsKit_flip(GSGLOBAL *gsGlobal) +/* finalize rendering a frame */ +void pemu_finalize_frame(const char *fps, const char *notice) { - if (!gsGlobal->FirstFrame) - { - if (gsGlobal->DoubleBuffering == GS_SETTING_ON) - { - GS_SET_DISPFB2(gsGlobal->ScreenBuffer[gsGlobal->ActiveBuffer & 1] / 8192, - gsGlobal->Width / 64, gsGlobal->PSM, 0, 0); + int emu_opt = currentConfig.EmuOpt; - gsGlobal->ActiveBuffer ^= 1; - } - } + if ((PicoIn.AHW & PAHW_PICO) && (currentConfig.EmuOpt & EOPT_PICO_PEN)) + if (pico_inp_mode) draw_pico_ptr(); - gsKit_setactive(gsGlobal); -} + osd_buf_cnt = 0; + if (notice) osd_text(4, notice); + if (emu_opt & 2) osd_text(OSD_FPS_X, fps); -static void flipScreen() -{ - gsKit_queue_exec(gsGlobal); - gsKit_finish(); - gsKit_flip(gsGlobal); + osd_cdleds = 0; + if ((emu_opt & 0x400) && (PicoIn.AHW & PAHW_MCD)) + cd_leds(); - gsKit_TexManager_nextFrame(gsGlobal); - gsKit_clear(gsGlobal, GS_BLACK); + FlushCache(WRITEBACK_DCACHE); } - /* display a completed frame buffer and prepare a new render buffer */ void plat_video_flip(void) { - blit_screen(); - blit_osd(); + gsKit_TexManager_invalidate(gsGlobal, osd); + gsKit_TexManager_invalidate(gsGlobal, cdleds); + gsKit_TexManager_invalidate(gsGlobal, g_screen); + + gsKit_finish(); + flipScreen(); + + gsKit_clear(gsGlobal, GS_BLACK); + blit_screen(); + blit_osd(); blit_cdleds(); - flipScreen(); + gsKit_queue_exec(gsGlobal); + + g_screen_index ^= 1; + g_screen = g_screens[g_screen_index]; + g_screen_ptr = g_screen->Mem; + + plat_video_set_buffer(g_screen_ptr); } /* wait for start of vertical blanking */ void plat_video_wait_vsync(void) { - gsKit_sync(gsGlobal); + gsKit_sync(gsGlobal); } /* switch from emulation display to menu display */ void plat_video_menu_enter(int is_rom_loaded) { + g_screen_ptr = NULL; } /* start rendering a menu screen */ void plat_video_menu_begin(void) { - gsKit_TexManager_invalidate(gsGlobal, g_menuscreen); } /* display a completed menu screen */ void plat_video_menu_end(void) { - gsKit_TexManager_bind(gsGlobal, g_menuscreen); - gskit_prim_list_sprite_texture_uv_3d( - gsGlobal, - g_menuscreen, - 2, - g_menuscreen_vertices - ); - flipScreen(1); + gsKit_TexManager_bind(gsGlobal, g_menuscreen); + gskit_prim_list_sprite_texture_uv_3d( gsGlobal, g_menuscreen, 2, g_menuscreen_vertices); + gsKit_queue_exec(gsGlobal); + gsKit_finish(); + gsKit_TexManager_invalidate(gsGlobal, g_menuscreen); + + flipScreen(); } /* terminate menu display */ void plat_video_menu_leave(void) { + g_screen_ptr = g_screen->Mem; + plat_video_set_buffer(g_screen_ptr); } /* set default configuration values */ void pemu_prep_defconfig(void) { - defaultConfig.s_PsndRate = 44100; + defaultConfig.s_PsndRate = 22050; defaultConfig.s_PicoCDBuffers = 64; defaultConfig.filter = EOPT_FILTER_BILINEAR; // bilinear filtering defaultConfig.scaling = EOPT_SCALE_43; defaultConfig.vscaling = EOPT_VSCALE_FULL; - defaultConfig.renderer = RT_16BIT; + defaultConfig.renderer = RT_8BIT_ACC; defaultConfig.renderer32x = RT_8BIT_ACC; defaultConfig.EmuOpt |= EOPT_SHOW_RTC; } @@ -681,47 +782,24 @@ void pemu_prep_defconfig(void) /* check configuration for inconsistencies */ void pemu_validate_config(void) { - if (currentConfig.gamma < -4 || currentConfig.gamma > 16) - currentConfig.gamma = 0; - if (currentConfig.gamma2 < 0 || currentConfig.gamma2 > 2) - currentConfig.gamma2 = 0; -} - -/* finalize rendering a frame */ -void pemu_finalize_frame(const char *fps, const char *notice) -{ - int emu_opt = currentConfig.EmuOpt; - - if (PicoIn.AHW & PAHW_PICO) - draw_pico_ptr(); - - osd_buf_cnt = 0; - if (notice) osd_text(4, notice); - if (emu_opt & 2) osd_text(OSD_FPS_X, fps); - - osd_cdleds = 0; - if ((emu_opt & 0x400) && (PicoIn.AHW & PAHW_MCD)) - cd_leds(); - - FlushCache(WRITEBACK_DCACHE); } -void plat_init(void) +void plat_init(void) { - video_init(); - init_joystick_driver(false); - in_ps2_init(in_ps2_defbinds); - in_probe(); - init_audio_driver(); - sound_init(); - plat_get_data_dir(rom_fname_loaded, sizeof(rom_fname_loaded)); + video_init(); + init_joystick_driver(false); + in_ps2_init(in_ps2_defbinds); + in_probe(); + init_audio_driver(); + sound_init(); + plat_get_data_dir(rom_fname_loaded, sizeof(rom_fname_loaded)); } void plat_finish(void) { - sound_deinit(); - deinit_audio_driver(); - deinit_joystick_driver(false); - video_deinit(); + sound_deinit(); + deinit_audio_driver(); + deinit_joystick_driver(false); + video_deinit(); } /* display emulator status messages before holding emulation */ @@ -754,37 +832,38 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co int h43 = (col_count >= 192 ? 320 : col_count); // ugh, mind GG... int v43 = (line_count >= 192 ? Pico.m.pal ? 240 : 224 : line_count); + out_y = start_line; out_x = start_col; + out_h = line_count; out_w = col_count; + if (col_count == 248) // mind aspect ratio when blanking 1st column col_count = 256; - - g_screen_vertices[0].uv = vertex_to_UV(g_screen, start_col, start_line); - g_screen_vertices[1].uv = vertex_to_UV(g_screen, col_count, line_count); switch (currentConfig.vscaling) { case EOPT_VSCALE_FULL: line_count = v43; - vscale = (float)270/line_count; + vscale = (float)gsGlobal->Height/line_count; break; case EOPT_VSCALE_NOBORDER: - vscale = (float)270/line_count; + vscale = (float)gsGlobal->Height/line_count; break; default: vscale = 1; break; } + hscale = vscale * (gsGlobal->Aspect == GS_ASPECT_16_9 ? (4./3)/(16./9) : 1); switch (currentConfig.scaling) { case EOPT_SCALE_43: - hscale = (vscale*h43)/col_count; + hscale = (hscale*h43)/col_count; break; case EOPT_SCALE_STRETCH: - hscale = (vscale*h43/2 + 480/2)/col_count; + hscale = (hscale*h43/2 + gsGlobal->Width/2)/col_count; break; case EOPT_SCALE_WIDE: - hscale = (float)480/col_count; + hscale = (float)gsGlobal->Width/col_count; break; default: - hscale = vscale; + // hscale = vscale, computed before switch break; } @@ -794,11 +873,15 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co /* render one frame in RGB */ void pemu_forced_frame(int no_scale, int do_emu) { + is_bg_frame = 1; Pico.m.dirtyPal = 1; if (!no_scale) no_scale = currentConfig.scaling == EOPT_SCALE_NONE; emu_cmn_forced_frame(no_scale, do_emu, g_screen_ptr); + + g_menubg_src_ptr = g_screen_ptr; + is_bg_frame = 0; } /* change the platform output rendering */ @@ -819,8 +902,17 @@ void plat_video_toggle_renderer(int change, int is_menu_call) emu_status_msg(renderer_names[get_renderer()]); } +/* set the buffer for emulator output rendering */ +void plat_video_set_buffer(void *buf) +{ + if (is_16bit_mode()) + PicoDrawSetOutBuf(g_screen_ptr, g_screen_ppitch * 2); + else + PicoDrawSetOutBuf(g_screen_ptr, g_screen_ppitch); +} + /* prepare for emulator output rendering */ -void plat_video_loop_prepare(void) +void plat_video_loop_prepare(void) { apply_renderer(); vidResetMode(); @@ -829,12 +921,11 @@ void plat_video_loop_prepare(void) /* prepare for entering the emulator loop */ void pemu_loop_prep(void) { - set_g_screen_values(); - set_cdleds_values(); } /* terminate the emulator loop */ void pemu_loop_end(void) { - pemu_sound_stop(); -} \ No newline at end of file + pemu_sound_stop(); + pemu_forced_frame(0, 1); +} diff --git a/platform/ps2/menu.c b/platform/ps2/menu.c new file mode 100644 index 00000000..c4416448 --- /dev/null +++ b/platform/ps2/menu.c @@ -0,0 +1,21 @@ + +static const char *men_vscaling_opts[] = { "OFF", "fullscreen", "borderless", NULL }; +static const char *men_hscaling_opts[] = { "1:1", "4:3", "extended", "fullwidth", NULL }; +static const char *men_filter_opts[] = { "nearest", "bilinear", NULL }; + +#define MENU_OPTIONS_GFX \ + mee_enum ("Vertical scaling", MA_OPT_VSCALING, currentConfig.vscaling, men_vscaling_opts), \ + mee_enum ("Aspect ratio", MA_OPT_SCALING, currentConfig.scaling, men_hscaling_opts), \ + mee_enum ("Scaler type", MA_OPT3_FILTERING, currentConfig.filter, men_filter_opts), \ + mee_onoff ("Wait for vsync", MA_OPT3_VSYNC, currentConfig.EmuOpt, EOPT_VSYNC), \ + +#define MENU_OPTIONS_ADV + +static menu_entry e_menu_sms_options[]; +static menu_entry e_menu_keyconfig[]; + +void psp_menu_init(void) +{ + me_enable(e_menu_sms_options, MA_SMSOPT_GHOSTING, 0); + me_enable(e_menu_keyconfig, MA_CTRL_DEADZONE, 0); +} diff --git a/platform/ps2/menu.h b/platform/ps2/menu.h new file mode 100644 index 00000000..d5aa6082 --- /dev/null +++ b/platform/ps2/menu.h @@ -0,0 +1,10 @@ + +void menu_loop(void); +int menu_loop_tray(void); +void menu_romload_prepare(const char *rom_name); +void menu_romload_end(void); + + +#define CONFIGURABLE_KEYS (PBTN_UP|PBTN_LEFT|PBTN_RIGHT|PBTN_DOWN|PBTN_L|PBTN_R|PBTN_TRIANGLE|PBTN_CIRCLE|PBTN_X|PBTN_SQUARE|PBTN_START| \ + PBTN_NUB_UP|PBTN_NUB_RIGHT|PBTN_NUB_DOWN|PBTN_NUB_LEFT|PBTN_NOTE) + diff --git a/platform/ps2/plat.c b/platform/ps2/plat.c index 7b6d2267..d645b5ef 100644 --- a/platform/ps2/plat.c +++ b/platform/ps2/plat.c @@ -19,7 +19,8 @@ #include "../libpicofe/plat.h" -struct plat_target plat_target = {}; +static int sound_rates[] = { 11025, 22050, 44100, -1 }; +struct plat_target plat_target = { .sound_rates = sound_rates }; static void reset_IOP() { SifInitRpc(0); @@ -205,4 +206,4 @@ void lprintf(const char *fmt, ...) va_end(vl); } -void plat_debug_cat(char *str) {} \ No newline at end of file +void plat_debug_cat(char *str) {}