Created
August 28, 2015 11:32
-
-
Save frangarcj/9e6748aa152d5ddff13d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "emumain.h" | |
#include <psp2/types.h> | |
#include <psp2/kernel/threadmgr.h> | |
#include "time.h" | |
#include <psp2/rtc.h> | |
#define SCE_KERNEL_OK 0 | |
#include "psplib/pl_rewind.h" | |
#include "psplib/pl_file.h" | |
#include "psplib/pl_snd.h" | |
#include "psplib/pl_perf.h" | |
#include "psplib/pl_util.h" | |
#include "psplib/pl_psp.h" | |
#include "psplib/video.h" | |
#include "psplib/ctrl.h" | |
#include "shared.h" | |
#include "sound.h" | |
#include "system.h" | |
#include "md_ntsc.h" | |
#include "sms_ntsc.h" | |
#include <debugnet.h> | |
#define ip_server "192.168.1.130" | |
#define port_server 18194 | |
PspImage *Screen; | |
pl_rewind Rewinder; | |
static pl_perf_counter FpsCounter; | |
static int ClearScreen; | |
static int ScreenX, ScreenY, ScreenW, ScreenH; | |
static int TicksPerUpdate; | |
static u32 TicksPerSecond; | |
static u64 LastTick; | |
static u64 CurrentTick; | |
static int Frame; | |
static int Rewinding; | |
extern pl_file_path CurrentGame; | |
extern EmulatorOptions Options; | |
extern const u64 ButtonMask[]; | |
extern const int ButtonMapId[]; | |
extern struct ButtonConfig ActiveConfig; | |
extern char *ScreenshotPath; | |
static short soundbuffer[SOUND_SAMPLES*3]; | |
static int totalSamples = 0; | |
static SceUID console_mtx; | |
static inline void RenderVideo(); | |
static void AudioCallback(pl_snd_sample* buf, | |
unsigned int samples, | |
void *userdata); | |
void MixerCallback(int16 **stream, int16 **output, int length); | |
md_ntsc_t *md_ntsc; | |
sms_ntsc_t *sms_ntsc; | |
int bEmulate; | |
void osd_input_update() | |
{ | |
/* Reset input */ | |
input.pad[0] = 0; | |
input.analog[0][0] = 0x7F; | |
static SceCtrlData pad; | |
static int autofire_status = 0; | |
/* Check the input */ | |
if (pspCtrlPollControls(&pad)) | |
{ | |
if (--autofire_status < 0) | |
autofire_status = Options.AutoFire; | |
/* Parse input */ | |
int i, on, code; | |
for (i = 0; ButtonMapId[i] >= 0; i++) | |
{ | |
code = ActiveConfig.ButtonMap[ButtonMapId[i]]; | |
on = (pad.buttons & ButtonMask[i]) == ButtonMask[i]; | |
/* Check to see if a button set is pressed. If so, unset it, so it */ | |
/* doesn't trigger any other combination presses. */ | |
if (on) pad.buttons &= ~ButtonMask[i]; | |
if (code & AFI) | |
{ | |
if (on && (autofire_status == 0)) | |
input.pad[0] |= CODE_MASK(code); | |
continue; | |
} | |
else if (code & JOY) | |
{ | |
if (on) { | |
input.pad[0] |= CODE_MASK(code); | |
} | |
continue; | |
} | |
else if (code & SYS) | |
{ | |
if (on) | |
{ | |
if (CODE_MASK(code) == (INPUT_START)) | |
input.system[0] |= INPUT_START; | |
} | |
continue; | |
} | |
if (code & SPC) | |
{ | |
switch (CODE_MASK(code)) | |
{ | |
case SPC_MENU: | |
if (on) bEmulate=0; | |
break; | |
case SPC_REWIND: | |
Rewinding = on; | |
break; | |
} | |
} | |
} | |
} | |
return; | |
} | |
void InitEmulator() | |
{ | |
debugNetInit(ip_server,port_server,DEBUG); | |
debugNetPrintf(DEBUG,"Test debug level "); | |
set_config_defaults(); | |
ClearScreen = 0; | |
/* Initialize screen buffer */ | |
Screen = pspImageCreateVram(720, 576, PSP_IMAGE_16BPP); | |
// pspImageClear(Screen, 0x8000); | |
console_mtx = sceKernelCreateMutex("sound_mutex", 0, 0, NULL); | |
if (console_mtx > 0) { | |
debugNetPrintf(DEBUG,"Sound Mutex UID: 0x%08X\n", console_mtx); | |
} | |
/* Set up bitmap structure */ | |
memset(&bitmap, 0, sizeof(t_bitmap)); | |
bitmap.width = Screen->Width; | |
bitmap.height = Screen->Height; | |
bitmap.pitch = (bitmap.width * 2); | |
bitmap.data = (unsigned char *)Screen->Pixels; | |
bitmap.viewport.changed = 3; | |
pl_snd_set_callback(0, AudioCallback, NULL); | |
} | |
void RunEmulator() | |
{ | |
float ratio; | |
debugNetPrintf(DEBUG,"RunEmulator\n"); | |
pspImageClear(Screen, 0); | |
debugNetPrintf(DEBUG,"ImageClear\n"); | |
if(bitmap.viewport.changed & 1) | |
{ | |
bitmap.viewport.changed &= ~1; | |
/* source bitmap */ | |
Screen->Viewport.Width = bitmap.viewport.w+2*bitmap.viewport.x; | |
Screen->Viewport.Height = bitmap.viewport.h+2*bitmap.viewport.y; | |
} | |
/* Recompute screen size/position */ | |
switch (Options.DisplayMode) | |
{ | |
default: | |
case DISPLAY_MODE_UNSCALED: | |
ScreenW = Screen->Viewport.Width; | |
ScreenH = Screen->Viewport.Height; | |
break; | |
case DISPLAY_MODE_FIT_HEIGHT: | |
ratio = (float)SCR_HEIGHT / (float)Screen->Viewport.Height; | |
ScreenW = (float)bitmap.viewport.w * ratio - 2; | |
ScreenH = SCR_HEIGHT; | |
break; | |
case DISPLAY_MODE_FILL_SCREEN: | |
ScreenW = SCR_WIDTH; | |
ScreenH = SCR_HEIGHT; | |
break; | |
case DISPLAY_MODE_2X: | |
ScreenW = Screen->Viewport.Width*2; | |
ScreenH = Screen->Viewport.Height*2; | |
break; | |
case DISPLAY_MODE_3X: | |
ScreenW = Screen->Viewport.Width*3; | |
ScreenH = Screen->Viewport.Height*3; | |
break; | |
} | |
debugNetPrintf(DEBUG,"screensize %d %d\n" ,Screen->Viewport.Width ,Screen->Viewport.Height); | |
ScreenX = (SCR_WIDTH / 2) - (ScreenW / 2); | |
ScreenY = (SCR_HEIGHT / 2) - (ScreenH / 2); | |
/* Init performance counter */ | |
pl_perf_init_counter(&FpsCounter); | |
/* Recompute update frequency */ | |
TicksPerSecond = sceRtcGetTickResolution(); | |
if (Options.UpdateFreq) | |
{ | |
TicksPerUpdate = TicksPerSecond | |
/ (Options.UpdateFreq / (Options.Frameskip + 1)); | |
sceRtcGetCurrentTick(&LastTick); | |
} | |
Frame = 0; | |
ClearScreen = 2; | |
Rewinding = 0; | |
//pl_rewind_realloc(&Rewinder); | |
int frames_until_save = 0; | |
/* Resume sound */ | |
pl_snd_resume(0); | |
/* Wait for V. refresh */ | |
pspVideoWaitVSync(); | |
bEmulate = 1; | |
/* Main emulation loop */ | |
while (!ExitPSP&&bEmulate) | |
{ | |
/* Rewind/save state */ | |
/*if (!Rewinding) | |
{ | |
if (--frames_until_save <= 0) | |
{ | |
frames_until_save = Options.RewindSaveRate; | |
pl_rewind_save(&Rewinder); | |
} | |
} | |
else | |
{ | |
frames_until_save = Options.RewindSaveRate; | |
if (!pl_rewind_restore(&Rewinder)) | |
continue; | |
}*/ | |
/* Run the system emulation for a frame */ | |
if (++Frame <= Options.Frameskip) | |
{ | |
/* Skip frame */ | |
if (system_hw == SYSTEM_MCD) | |
{ | |
system_frame_scd(1); | |
} | |
else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) | |
{ | |
system_frame_gen(1); | |
} | |
else | |
{ | |
system_frame_sms(1); | |
} | |
} | |
else | |
{ | |
if (system_hw == SYSTEM_MCD) | |
{ | |
system_frame_scd(0); | |
} | |
else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) | |
{ | |
system_frame_gen(0); | |
} | |
else | |
{ | |
system_frame_sms(0); | |
} | |
Frame = 0; | |
/* Display */ | |
if(bitmap.viewport.changed & 1) | |
{ | |
bitmap.viewport.changed &= ~1; | |
/* source bitmap */ | |
Screen->Viewport.Width = bitmap.viewport.w+2*bitmap.viewport.x; | |
Screen->Viewport.Height = bitmap.viewport.h+2*bitmap.viewport.y; | |
/* Recompute screen size/position */ | |
switch (Options.DisplayMode) | |
{ | |
default: | |
case DISPLAY_MODE_UNSCALED: | |
ScreenW = Screen->Viewport.Width; | |
ScreenH = Screen->Viewport.Height; | |
break; | |
case DISPLAY_MODE_FIT_HEIGHT: | |
ratio = (float)SCR_HEIGHT / (float)Screen->Viewport.Height; | |
ScreenW = (float)bitmap.viewport.w * ratio - 2; | |
ScreenH = SCR_HEIGHT; | |
break; | |
case DISPLAY_MODE_FILL_SCREEN: | |
ScreenW = SCR_WIDTH; | |
ScreenH = SCR_HEIGHT; | |
break; | |
case DISPLAY_MODE_2X: | |
ScreenW = Screen->Viewport.Width*2; | |
ScreenH = Screen->Viewport.Height*2; | |
break; | |
case DISPLAY_MODE_3X: | |
ScreenW = Screen->Viewport.Width*3; | |
ScreenH = Screen->Viewport.Height*3; | |
break; | |
} | |
ScreenX = (SCR_WIDTH / 2) - (ScreenW / 2); | |
ScreenY = (SCR_HEIGHT / 2) - (ScreenH / 2); | |
} | |
RenderVideo(); | |
int mtx_err = sceKernelLockMutex(console_mtx, 1,NULL); | |
totalSamples += audio_update(&soundbuffer[totalSamples*2]); | |
debugNetPrintf(DEBUG,"Filling %d\n",totalSamples); | |
if (mtx_err == SCE_KERNEL_OK) { | |
sceKernelUnlockMutex(console_mtx, 1); | |
} | |
} | |
} | |
/* Stop sound */ | |
pl_snd_pause(0); | |
} | |
void TrashEmulator() | |
{ | |
pl_rewind_destroy(&Rewinder); | |
/* Trash screen */ | |
if (Screen) pspImageDestroy(Screen); | |
if (CurrentGame[0] != '\0') | |
{ | |
/* Release emulation resources */ | |
audio_shutdown(); | |
error_shutdown(); | |
} | |
debugNetFinish(); | |
} | |
void RenderVideo() | |
{ | |
/* Update the display */ | |
pspVideoBegin(); | |
/* Clear the buffer first, if necessary */ | |
if (ClearScreen >= 0) | |
{ | |
ClearScreen--; | |
pspVideoClearScreen(); | |
} | |
pspVideoPutImage(Screen, ScreenX, ScreenY, ScreenW, ScreenH); | |
/* Show FPS counter */ | |
if (Options.ShowFps) | |
{ | |
static char fps_display[32]; | |
sprintf(fps_display, " %3.02f", pl_perf_update_counter(&FpsCounter)); | |
int width = pspFontGetTextWidth(&PspStockFont, fps_display); | |
int height = pspFontGetLineHeight(&PspStockFont); | |
pspVideoFillRect(SCR_WIDTH - width, 0, SCR_WIDTH, height, PSP_COLOR_BLACK); | |
pspVideoPrint(&PspStockFont, SCR_WIDTH - width, 0, fps_display, PSP_COLOR_WHITE); | |
} | |
pspVideoEnd(); | |
/* Wait if needed */ | |
if (Options.UpdateFreq) | |
{ | |
do { sceRtcGetCurrentTick(&CurrentTick); } | |
while (CurrentTick - LastTick < TicksPerUpdate); | |
LastTick = CurrentTick; | |
} | |
/* Wait for VSync signal */ | |
if (Options.VSync) | |
pspVideoWaitVSync(); | |
/* Swap buffers */ | |
pspVideoSwapBuffers(); | |
} | |
static void AudioCallback(pl_snd_sample *buf, | |
unsigned int samples, | |
void *userdata) | |
{ | |
int i; | |
int mtx_err = sceKernelLockMutex(console_mtx, 1,NULL); | |
if (!Rewinding&&totalSamples>SOUND_SAMPLES) | |
{ | |
debugNetPrintf(DEBUG,"FULL %d\n",totalSamples); | |
int size = totalSamples-SOUND_SAMPLES; | |
for (i = 0; i < SOUND_SAMPLES; i++) | |
{ | |
buf[i].stereo.l = soundbuffer[i*2]; | |
buf[i].stereo.r = soundbuffer[i*2+1]; | |
} | |
for (i=0; i < size; i++){ | |
soundbuffer[i*2]=soundbuffer[SOUND_SAMPLES+(i*2)]; | |
soundbuffer[i*2+1]=soundbuffer[SOUND_SAMPLES+(i*2)+1]; | |
} | |
totalSamples=size; | |
debugNetPrintf(DEBUG,"NEXT %d\n",totalSamples); | |
if (mtx_err == SCE_KERNEL_OK) { | |
sceKernelUnlockMutex(console_mtx, 1); | |
} | |
} | |
else{ | |
if (mtx_err == SCE_KERNEL_OK) { | |
sceKernelUnlockMutex(console_mtx, 1); | |
} | |
/* Render silence */ | |
for (i = 0; i < samples; i++) | |
buf[i].stereo.l = buf[i].stereo.r = 0; | |
}//return samples; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment