1 #include "emumain.h"
2 
3 #include <psp2/types.h>
4 #include <psp2/kernel/threadmgr.h>
5 #include "time.h"
6 #include <psp2/rtc.h>
7 
8 #define SCE_KERNEL_OK 0
9 
10 #include "psplib/pl_rewind.h"
11 #include "psplib/pl_file.h"
12 #include "psplib/pl_snd.h"
13 #include "psplib/pl_perf.h"
14 #include "psplib/pl_util.h"
15 #include "psplib/pl_psp.h"
16 #include "psplib/video.h"
17 #include "psplib/ctrl.h"
18 
19 #include "shared.h"
20 #include "sound.h"
21 #include "system.h"
22 #include "md_ntsc.h"
23 #include "sms_ntsc.h"
24 
25 //#include <debugnet.h>
26 
27 #define ip_server "192.168.1.130"
28 #define port_server 18194
29 
30 PspImage *Screen;
31 pl_rewind Rewinder;
32 
33 static pl_perf_counter FpsCounter;
34 static int ClearScreen;
35 static int ScreenX, ScreenY, ScreenW, ScreenH;
36 static int TicksPerUpdate;
37 static u32 TicksPerSecond;
38 static u64 LastTick;
39 static u64 CurrentTick;
40 static int Frame;
41 
42 static int Rewinding;
43 
44 extern pl_file_path CurrentGame;
45 extern EmulatorOptions Options;
46 extern const u64 ButtonMask[];
47 extern const int ButtonMapId[];
48 extern struct ButtonConfig ActiveConfig;
49 extern char *ScreenshotPath;
50 
51 static short soundbuffer[SOUND_SAMPLES*2*10];
52 static int soundPosWrite = 0;
53 static int soundPosRead = 0;
54 static SceUID console_mtx;
55 
56 
57 
58 static inline void RenderVideo();
59 static void AudioCallback(pl_snd_sample* buf,
60                           unsigned int samples,
61                           void *userdata);
62 void MixerCallback(int16 **stream, int16 **output, int length);
63 md_ntsc_t *md_ntsc;
64 sms_ntsc_t *sms_ntsc;
65 
66 int bEmulate;
67 
osd_input_update()68 void osd_input_update()
69 {
70 
71     /* Reset input */
72     input.pad[0]    = 0;
73     input.analog[0][0] = 0x7F;
74 
75     static SceCtrlData pad;
76     static int autofire_status = 0;
77 
78     /* Check the input */
79     if (pspCtrlPollControls(&pad))
80     {
81       if (--autofire_status < 0)
82         autofire_status = Options.AutoFire;
83 
84       /* Parse input */
85       int i, on, code;
86       for (i = 0; ButtonMapId[i] >= 0; i++)
87       {
88         code = ActiveConfig.ButtonMap[ButtonMapId[i]];
89         on = (pad.buttons & ButtonMask[i]) == ButtonMask[i];
90 
91         /* Check to see if a button set is pressed. If so, unset it, so it */
92         /* doesn't trigger any other combination presses. */
93         if (on) pad.buttons &= ~ButtonMask[i];
94 
95           if (code & AFI)
96           {
97             if (on && (autofire_status == 0))
98               input.pad[0] |= CODE_MASK(code);
99             continue;
100           }
101           else if (code & JOY)
102           {
103             if (on) {
104               input.pad[0] |= CODE_MASK(code);
105             }
106             continue;
107           }
108           else if (code & SYS)
109           {
110             if (on)
111             {
112               if (CODE_MASK(code) == (INPUT_START))
113                 input.system[0] |= INPUT_START;
114             }
115             continue;
116           }
117 
118 
119         if (code & SPC)
120         {
121           switch (CODE_MASK(code))
122           {
123           case SPC_MENU:
124             if (on) bEmulate=0;
125             break;
126           case SPC_REWIND:
127             Rewinding = on;
128             break;
129           }
130         }
131       }
132     }
133 
134     return;
135   }
136 
InitEmulator()137 void InitEmulator()
138 {
139 
140 	//debugNetInit(ip_server,port_server,DEBUG);
141 
142   set_config_defaults();
143 
144   ClearScreen = 0;
145 
146   /* Initialize screen buffer */
147   Screen = pspImageCreateVram(720, 576, PSP_IMAGE_16BPP);
148 
149   // pspImageClear(Screen, 0x8000);
150 
151   console_mtx = sceKernelCreateSema("sound_sema", 0, 0, 1, 0);
152 	/*if (console_mtx > 0) {
153 		debugNetPrintf(DEBUG,"Sound Mutex UID: 0x%08X\n", console_mtx);
154 	}*/
155 
156   /* Set up bitmap structure */
157   memset(&bitmap, 0, sizeof(t_bitmap));
158   bitmap.width  = Screen->Width;
159   bitmap.height = Screen->Height;
160   bitmap.pitch  = (bitmap.width * 2);
161   bitmap.data   = (unsigned char *)Screen->Pixels;
162   bitmap.viewport.changed = 3;
163 
164   pl_snd_set_callback(0, AudioCallback, NULL);
165 }
166 
RunEmulator()167 void RunEmulator()
168 {
169   float ratio;
170   //debugNetPrintf(DEBUG,"RunEmulator\n");
171 
172   pspImageClear(Screen, 0);
173   //debugNetPrintf(DEBUG,"ImageClear\n");
174 
175 
176   if(bitmap.viewport.changed & 1)
177   {
178     bitmap.viewport.changed &= ~1;
179 
180     /* source bitmap */
181     Screen->Viewport.Width = bitmap.viewport.w+2*bitmap.viewport.x;
182     Screen->Viewport.Height = bitmap.viewport.h+2*bitmap.viewport.y;
183 
184   }
185 
186   /* Recompute screen size/position */
187   switch (Options.DisplayMode)
188   {
189   default:
190   case DISPLAY_MODE_UNSCALED:
191     ScreenW = Screen->Viewport.Width;
192     ScreenH = Screen->Viewport.Height;
193     break;
194   case DISPLAY_MODE_FIT_HEIGHT:
195     ratio = (float)SCR_HEIGHT / (float)Screen->Viewport.Height;
196     ScreenW = (float)bitmap.viewport.w * ratio - 2;
197     ScreenH = SCR_HEIGHT;
198     break;
199   case DISPLAY_MODE_FILL_SCREEN:
200     ScreenW = SCR_WIDTH;
201     ScreenH = SCR_HEIGHT;
202     break;
203   case DISPLAY_MODE_2X:
204       ScreenW = Screen->Viewport.Width*2;
205       ScreenH = Screen->Viewport.Height*2;
206       break;
207   case DISPLAY_MODE_3X:
208       ScreenW = Screen->Viewport.Width*3;
209       ScreenH = Screen->Viewport.Height*3;
210       break;
211   }
212   //debugNetPrintf(DEBUG,"screensize %d %d\n" ,Screen->Viewport.Width ,Screen->Viewport.Height);
213 
214   ScreenX = (SCR_WIDTH / 2) - (ScreenW / 2);
215   ScreenY = (SCR_HEIGHT / 2) - (ScreenH / 2);
216 
217   /* Init performance counter */
218   pl_perf_init_counter(&FpsCounter);
219 
220   /* Recompute update frequency */
221   TicksPerSecond = sceRtcGetTickResolution();
222   if (Options.UpdateFreq)
223   {
224     TicksPerUpdate = TicksPerSecond
225       / (Options.UpdateFreq / (Options.Frameskip + 1));
226     sceRtcGetCurrentTick(&LastTick);
227   }
228   Frame = 0;
229   ClearScreen = 2;
230   Rewinding = 0;
231 
232 //pl_rewind_realloc(&Rewinder);
233 
234   int frames_until_save = 0;
235 
236   /* Resume sound */
237   pl_snd_resume(0);
238 
239   /* Wait for V. refresh */
240   pspVideoWaitVSync();
241 
242   bEmulate = 1;
243   /* Main emulation loop */
244   while (!ExitPSP&&bEmulate)
245   {
246     /* Rewind/save state */
247     /*if (!Rewinding)
248     {
249       if (--frames_until_save <= 0)
250       {
251         frames_until_save = Options.RewindSaveRate;
252         pl_rewind_save(&Rewinder);
253       }
254     }
255     else
256     {
257       frames_until_save = Options.RewindSaveRate;
258       if (!pl_rewind_restore(&Rewinder))
259         continue;
260     }*/
261 
262     /* Run the system emulation for a frame */
263     if (++Frame <= Options.Frameskip)
264     {
265       /* Skip frame */
266       if (system_hw == SYSTEM_MCD)
267       {
268         system_frame_scd(1);
269       }
270       else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
271       {
272         system_frame_gen(1);
273       }
274       else
275       {
276         system_frame_sms(1);
277       }
278     }
279     else
280     {
281       if (system_hw == SYSTEM_MCD)
282       {
283         system_frame_scd(0);
284       }
285       else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
286       {
287         system_frame_gen(0);
288       }
289       else
290       {
291         system_frame_sms(0);
292       }
293 
294       Frame = 0;
295       /* Display */
296       if(bitmap.viewport.changed & 1)
297       {
298         bitmap.viewport.changed &= ~1;
299 
300         /* source bitmap */
301         Screen->Viewport.Width = bitmap.viewport.w+2*bitmap.viewport.x;
302         Screen->Viewport.Height = bitmap.viewport.h+2*bitmap.viewport.y;
303 
304         /* Recompute screen size/position */
305         switch (Options.DisplayMode)
306         {
307         default:
308         case DISPLAY_MODE_UNSCALED:
309           ScreenW = Screen->Viewport.Width;
310           ScreenH = Screen->Viewport.Height;
311           break;
312         case DISPLAY_MODE_FIT_HEIGHT:
313           ratio = (float)SCR_HEIGHT / (float)Screen->Viewport.Height;
314           ScreenW = (float)bitmap.viewport.w * ratio - 2;
315           ScreenH = SCR_HEIGHT;
316           break;
317         case DISPLAY_MODE_FILL_SCREEN:
318           ScreenW = SCR_WIDTH;
319           ScreenH = SCR_HEIGHT;
320           break;
321         case DISPLAY_MODE_2X:
322             ScreenW = Screen->Viewport.Width*2;
323             ScreenH = Screen->Viewport.Height*2;
324             break;
325         case DISPLAY_MODE_3X:
326             ScreenW = Screen->Viewport.Width*3;
327             ScreenH = Screen->Viewport.Height*3;
328             break;
329         }
330 
331         ScreenX = (SCR_WIDTH / 2) - (ScreenW / 2);
332         ScreenY = (SCR_HEIGHT / 2) - (ScreenH / 2);
333 
334       }
335       //debugNetPrintf(DEBUG,"main %d %d \n",soundPosRead,soundPosWrite);
336       int size = audio_update(&soundbuffer[soundPosRead])*2;
337       //debugNetPrintf(DEBUG,"filling %d \n",size);
338 
339       soundPosRead +=size;
340       if(soundPosRead+size>=(SOUND_SAMPLES*2*10)){
341           soundPosRead = 0;
342       }
343       if((soundPosRead-soundPosWrite)>=(SOUND_SAMPLES*2)||(soundPosRead-soundPosWrite)<0){
344         sceKernelSignalSema(console_mtx, 1); //lock
345       }
346       RenderVideo();
347 
348     }
349   }
350 
351   /* Stop sound */
352   pl_snd_pause(0);
353 }
354 
TrashEmulator()355 void TrashEmulator()
356 {
357   pl_rewind_destroy(&Rewinder);
358 
359   /* Trash screen */
360   if (Screen) pspImageDestroy(Screen);
361 
362   if (CurrentGame[0] != '\0')
363   {
364     /* Release emulation resources */
365     audio_shutdown();
366     error_shutdown();
367   }
368   //debugNetFinish();
369 
370 }
371 
372 
373 
RenderVideo()374 void RenderVideo()
375 {
376   /* Update the display */
377   pspVideoBegin();
378 
379   /* Clear the buffer first, if necessary */
380   if (ClearScreen >= 0)
381   {
382     ClearScreen--;
383     pspVideoClearScreen();
384   }
385 
386   pspVideoPutImage(Screen, ScreenX, ScreenY, ScreenW, ScreenH);
387 
388   /* Show FPS counter */
389   if (Options.ShowFps)
390   {
391     static char fps_display[32];
392     sprintf(fps_display, " %3.02f", pl_perf_update_counter(&FpsCounter));
393 
394     int width = pspFontGetTextWidth(&PspStockFont, fps_display);
395     int height = pspFontGetLineHeight(&PspStockFont);
396 
397     pspVideoFillRect(SCR_WIDTH - width, 0, SCR_WIDTH, height, PSP_COLOR_BLACK);
398     pspVideoPrint(&PspStockFont, SCR_WIDTH - width, 0, fps_display, PSP_COLOR_WHITE);
399   }
400 
401   pspVideoEnd();
402 
403   /* Wait if needed */
404   if (Options.UpdateFreq)
405   {
406     do { sceRtcGetCurrentTick(&CurrentTick); }
407     while (CurrentTick - LastTick < TicksPerUpdate);
408     LastTick = CurrentTick;
409   }
410 
411   /* Wait for VSync signal */
412   if (Options.VSync)
413     pspVideoWaitVSync();
414 
415   /* Swap buffers */
416   pspVideoSwapBuffers();
417 }
418 
AudioCallback(pl_snd_sample * buf,unsigned int samples,void * userdata)419 static void AudioCallback(pl_snd_sample *buf,
420                           unsigned int samples,
421                           void *userdata)
422 {
423   int i;
424   //debugNetPrintf(DEBUG,"wait %d %d \n",totalSamples,samples);
425   if (!Rewinding)
426   {
427       short* ptr_s = (short*)buf;
428       //debugNetPrintf(DEBUG,"wait %d %d \n",soundPosRead,soundPosWrite);
429       if((soundPosRead-soundPosWrite)<SOUND_SAMPLES*2){
430         sceKernelWaitSema(console_mtx, 1, 0); //lock
431         //debugNetPrintf(DEBUG,"start %d %d \n",soundPosRead,soundPosWrite);
432       }
433       memcpy(ptr_s,&soundbuffer[soundPosWrite],sizeof(short)*samples*2);
434       soundPosWrite +=samples*2;
435       if(soundPosWrite+(samples*2)>=(SOUND_SAMPLES*2*10)){
436           soundPosWrite = 0;
437       }
438   }
439   else /* Render silence */
440     for (i = 0; i < samples; i++)
441       buf[i].stereo.l = buf[i].stereo.r = 0;
442 }
443