Subversion Repositories psp

[/] [branches/] [smsplus_adhoc/] [psp/] [emumain.c] - Blame information for rev 354

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 jack
#include "emumain.h"
2 23 jack
 
3 27 jack
#include <psptypes.h>
4
#include "time.h"
5
#include <psprtc.h>
6
 
7 241 jack
#include "menu.h"
8 20 jack
#include "audio.h"
9 19 jack
#include "video.h"
10
#include "psp.h"
11
#include "ctrl.h"
12
#include "perf.h"
13 28 jack
#include "util.h"
14 248 jack
#include "adhoc.h"
15 19 jack
#include "shared.h"
16
#include "sound.h"
17
#include "system.h"
18
 
19
PspImage *Screen;
20
 
21
static PspFpsCounter FpsCounter;
22 27 jack
static int ClearScreen;
23
static int ScreenX, ScreenY, ScreenW, ScreenH;
24
static int TicksPerUpdate;
25
static u32 TicksPerSecond;
26
static u64 LastTick;
27
static u64 CurrentTick;
28
static int Frame;
29 241 jack
static int ControlSamplingCount;
30 19 jack
 
31 241 jack
extern int AdhocMode;
32
extern PspMAC OpponentMAC;
33
 
34 27 jack
extern char *GameName;
35 77 jack
extern EmulatorOptions Options;
36 28 jack
extern const u64 ButtonMask[];
37
extern const int ButtonMapId[];
38
extern struct ButtonConfig ActiveConfig;
39
extern char *ScreenshotPath;
40 27 jack
 
41 166 jack
static inline int ParseInput();
42
static inline void RenderVideo();
43 27 jack
void AudioCallback(void* buf, unsigned int *length, void *userdata);
44 49 jack
void MixerCallback(int16 **stream, int16 **output, int length);
45 354 jack
 
46
/* In ADHOC games, this will differ for client */
47
static EmulatorOptions ActiveOptions;
48 19 jack
 
49 250 jack
typedef struct
50
{
51
  uint32 Pad;
52
  uint32 System;
53
  uint8  Special;
54
} NetplayPacket;
55
 
56
#define ADHOC_MENU 0x01
57
 
58 19 jack
void InitEmulator()
59
{
60 27 jack
  ClearScreen = 0;
61
 
62 19 jack
  /* Initialize screen buffer */
63 52 jack
  Screen = pspImageCreateVram(256, 192, PSP_IMAGE_INDEXED);
64 31 jack
 
65 51 jack
  // pspImageClear(Screen, 0x8000);
66 19 jack
 
67
  /* Set up bitmap structure */
68
  memset(&bitmap, 0, sizeof(bitmap_t));
69 22 jack
  bitmap.width  = Screen->Width;
70
  bitmap.height = Screen->Height;
71 51 jack
  bitmap.depth  = Screen->Depth;
72 19 jack
  bitmap.granularity = (bitmap.depth >> 3);
73 22 jack
  bitmap.pitch  = bitmap.width * bitmap.granularity;
74 19 jack
  bitmap.data   = (uint8 *)Screen->Pixels;
75
  bitmap.viewport.x = 0;
76
  bitmap.viewport.y = 0;
77
  bitmap.viewport.w = 256;
78
  bitmap.viewport.h = 192;
79
 
80
  /* Initialize sound structure */
81 77 jack
  snd.fm_which = Options.SoundEngine;
82 19 jack
  snd.fps = FPS_NTSC;
83
  snd.fm_clock = CLOCK_NTSC;
84
  snd.psg_clock = CLOCK_NTSC;
85
  snd.sample_rate = 44100;
86 49 jack
  snd.mixer_callback = MixerCallback;
87 19 jack
 
88 52 jack
  sms.use_fm = 0;
89 20 jack
  sms.territory = TERRITORY_EXPORT;
90 240 jack
 
91
  system_init();
92 19 jack
}
93
 
94
void RunEmulator()
95
{
96 27 jack
  float ratio;
97 19 jack
 
98 354 jack
  memcpy(&ActiveOptions, &Options, sizeof(Options));
99
 
100
  if (AdhocMode == ADHOC_HOST)
101
  {
102
    /* Send Options object */
103
    sceKernelDelayThread(1000000);
104
    pspAdhocSendWithAck(OpponentMAC, &ActiveOptions, sizeof(Options));
105
  }
106
  else if (AdhocMode == ADHOC_CLIENT)
107
  {
108
    /* Receive Options object */
109
    pspAdhocRecvWithAck(&ActiveOptions, sizeof(Options));
110
  }
111
 
112
  /* Set clock frequency during emulation */
113
  pspSetClockFrequency(ActiveOptions.ClockFreq);
114
 
115 43 jack
  /* Reset viewport */
116
  if (IS_GG)
117
  {
118 52 jack
    bitmap.viewport.x = Screen->Viewport.X = 48;
119
    bitmap.viewport.y = Screen->Viewport.Y = 24;
120
    bitmap.viewport.w = Screen->Viewport.Width = 160;
121
    bitmap.viewport.h = Screen->Viewport.Height = 144;
122 43 jack
  }
123
  else
124
  {
125 52 jack
    bitmap.viewport.x = Screen->Viewport.X = 0;
126
    bitmap.viewport.y = Screen->Viewport.Y = 0;
127
    bitmap.viewport.w = Screen->Viewport.Width = 256;
128
    bitmap.viewport.h = Screen->Viewport.Height = 192;
129 49 jack
 
130 77 jack
    if (!Options.VertStrip)
131 49 jack
    {
132
      Screen->Viewport.X += 8;
133
      Screen->Viewport.Width -= 8;
134
    }
135 43 jack
  }
136
 
137 52 jack
  pspImageClear(Screen, 0);
138 49 jack
 
139 27 jack
  /* Recompute screen size/position */
140 77 jack
  switch (Options.DisplayMode)
141 27 jack
  {
142
  default:
143
  case DISPLAY_MODE_UNSCALED:
144 30 jack
    ScreenW = Screen->Viewport.Width;
145
    ScreenH = Screen->Viewport.Height;
146 27 jack
    break;
147
  case DISPLAY_MODE_FIT_HEIGHT:
148 30 jack
    ratio = (float)SCR_HEIGHT / (float)Screen->Viewport.Height;
149 172 jack
    ScreenW = (float)bitmap.viewport.w * ratio - 2;
150 27 jack
    ScreenH = SCR_HEIGHT;
151
    break;
152
  case DISPLAY_MODE_FILL_SCREEN:
153 54 jack
    ScreenW = SCR_WIDTH - 3;
154 27 jack
    ScreenH = SCR_HEIGHT;
155
    break;
156
  }
157 30 jack
 
158 27 jack
  ScreenX = (SCR_WIDTH / 2) - (ScreenW / 2);
159
  ScreenY = (SCR_HEIGHT / 2) - (ScreenH / 2);
160
 
161 19 jack
  /* Init performance counter */
162
  pspPerfInitFps(&FpsCounter);
163 27 jack
 
164
  /* Recompute update frequency */
165
  TicksPerSecond = sceRtcGetTickResolution();
166 354 jack
  if (ActiveOptions.UpdateFreq)
167 27 jack
  {
168
    TicksPerUpdate = TicksPerSecond
169 354 jack
      / (ActiveOptions.UpdateFreq / (ActiveOptions.Frameskip + 1));
170 27 jack
    sceRtcGetCurrentTick(&LastTick);
171
  }
172
  Frame = 0;
173
  ClearScreen = 1;
174 241 jack
  ControlSamplingCount = 0;
175 27 jack
 
176 241 jack
  input.pad[0]    = 0;
177
  input.pad[1]    = 0;
178
 
179 27 jack
  /* Resume sound */
180
  pspAudioSetChannelCallback(0, AudioCallback, 0);
181
 
182
  /* Wait for V. refresh */
183
  pspVideoWaitVSync();
184
 
185 19 jack
  /* Main emulation loop */
186
  while (!ExitPSP)
187
  {
188
    /* Check input */
189 27 jack
    if (ParseInput()) break;
190 19 jack
 
191
    /* Run the system emulation for a frame */
192 354 jack
    if (++Frame <= ActiveOptions.Frameskip)
193 27 jack
    {
194
      /* Skip frame */
195
      system_frame(1);
196
    }
197
    else
198
    {
199
      system_frame(0);
200
      Frame = 0;
201 19 jack
 
202 27 jack
      /* Display */
203
      RenderVideo();
204
    }
205 19 jack
  }
206
 
207 27 jack
  /* Stop sound */
208
  pspAudioSetChannelCallback(0, NULL, 0);
209 19 jack
}
210
 
211
void TrashEmulator()
212
{
213
  /* Trash screen */
214
  if (Screen) pspImageDestroy(Screen);
215
 
216 27 jack
  if (GameName)
217
  {
218
    /* Release emulation resources */
219
    system_poweroff();
220
    system_shutdown();
221
  }
222 19 jack
}
223
 
224 27 jack
int ParseInput()
225 19 jack
{
226 250 jack
  static NetplayPacket in_packet, out_packet;
227 353 jack
  unsigned int packet_size = sizeof(NetplayPacket);
228 250 jack
 
229 19 jack
  /* Reset input */
230
  input.system    = 0;
231
  input.analog[0] = 0x7F;
232
  input.analog[1] = 0x7F;
233
 
234 241 jack
  if (AdhocMode)
235
  {
236
    if (++ControlSamplingCount < 5)
237
      return 0;
238
    ControlSamplingCount = 0;
239
  }
240
 
241
  int player = (AdhocMode == ADHOC_CLIENT);
242 250 jack
  int back_to_menu = 0;
243 241 jack
 
244
  /* Reset input */
245
  input.pad[0]    = 0;
246
  input.pad[1]    = 0;
247
 
248 19 jack
  static SceCtrlData pad;
249
 
250
  /* Check the input */
251
  if (pspCtrlPollControls(&pad))
252 166 jack
  {
253 112 jack
#ifdef PSP_DEBUG
254 28 jack
    if ((pad.Buttons & (PSP_CTRL_SELECT | PSP_CTRL_START))
255
      == (PSP_CTRL_SELECT | PSP_CTRL_START))
256 166 jack
        pspUtilSaveVramSeq(ScreenshotPath, "game");
257 112 jack
#endif
258 27 jack
 
259 28 jack
    /* Parse input */
260
    int i, on, code;
261
    for (i = 0; ButtonMapId[i] >= 0; i++)
262
    {
263
      code = ActiveConfig.ButtonMap[ButtonMapId[i]];
264
      on = (pad.Buttons & ButtonMask[i]) == ButtonMask[i];
265 19 jack
 
266 28 jack
      /* Check to see if a button set is pressed. If so, unset it, so it */
267
      /* doesn't trigger any other combination presses. */
268
      if (on) pad.Buttons &= ~ButtonMask[i];
269 19 jack
 
270 28 jack
      if (code & JOY)
271
      {
272 241 jack
        if (on) input.pad[player] |= CODE_MASK(code);
273 28 jack
      }
274 250 jack
      else if ((code & SYS) && (AdhocMode != ADHOC_CLIENT))
275 28 jack
      {
276
        if (on)
277
        {
278
          if (CODE_MASK(code) == (INPUT_START | INPUT_PAUSE))
279
            input.system |= (IS_GG) ? INPUT_START : INPUT_PAUSE;
280
        }
281
      }
282
      else if (code & SPC)
283
      {
284
        switch (CODE_MASK(code))
285
        {
286
        case SPC_MENU:
287 250 jack
          if (on) back_to_menu = 1;
288 28 jack
          break;
289
        }
290
      }
291
    }
292 19 jack
  }
293 27 jack
 
294 244 jack
  if (AdhocMode)
295
  {
296 250 jack
    out_packet.Special = back_to_menu;
297 241 jack
 
298
    if (AdhocMode == ADHOC_HOST)
299
    {
300 250 jack
      out_packet.Pad = input.pad[0];
301
      out_packet.System = input.system;
302
 
303 352 jack
      pl_adhoc_send(OpponentMAC, &out_packet, packet_size);
304 353 jack
      pl_adhoc_recv_blocking(&in_packet, &packet_size);
305 250 jack
 
306
      /* Only care about client's pad input */
307
      input.pad[1] = in_packet.Pad;
308 241 jack
    }
309
    else
310
    {
311 250 jack
      out_packet.Pad = input.pad[1];
312 353 jack
//      out_packet.System = 0;
313 250 jack
 
314 353 jack
      pl_adhoc_recv_blocking(&in_packet, &packet_size);
315 352 jack
      pl_adhoc_send(OpponentMAC, &out_packet, packet_size);
316 250 jack
 
317
      /* Host sets both pad and system input */
318
      input.pad[0] = in_packet.Pad;
319
      input.system = in_packet.System;
320 241 jack
    }
321 250 jack
 
322
    switch (in_packet.Special)
323
    {
324
    case ADHOC_MENU:
325
      back_to_menu = 1;
326
      break;
327
    }
328 244 jack
  }
329 241 jack
 
330 250 jack
  return back_to_menu;
331 19 jack
}
332 23 jack
 
333 19 jack
void RenderVideo()
334
{
335
  /* Update the display */
336
  pspVideoBegin();
337
 
338 27 jack
  /* Clear the buffer first, if necessary */
339
  if (ClearScreen >= 0)
340
  {
341
    ClearScreen--;
342
    pspVideoClearScreen();
343
  }
344
 
345 51 jack
        if (Screen->Depth == PSP_IMAGE_INDEXED && bitmap.pal.update)
346
        {
347 52 jack
    unsigned char r, g, b;
348
    unsigned short c, i;
349
 
350 51 jack
                for(i = 0; i < PALETTE_SIZE; i++)
351
                {
352 52 jack
      if (bitmap.pal.dirty[i])
353
      {
354
        r = bitmap.pal.color[i][0];
355
        g = bitmap.pal.color[i][1];
356
        b = bitmap.pal.color[i][2];
357
        c = MAKE_PIXEL(r,g,b);
358 51 jack
 
359 52 jack
        Screen->Palette[i] = c;
360
        Screen->Palette[i|0x20] = c;
361
        Screen->Palette[i|0x40] = c;
362
        Screen->Palette[i|0x60] = c;
363
      }
364
    }
365
  }
366 51 jack
 
367 19 jack
  /* Draw the screen */
368 51 jack
  pspVideoPutImage(Screen, ScreenX, ScreenY, ScreenW, ScreenH);
369 19 jack
 
370
  /* Show FPS counter */
371 77 jack
  if (Options.ShowFps)
372 19 jack
  {
373 20 jack
    static char fps_display[32];
374 23 jack
    sprintf(fps_display, " %3.02f", pspPerfGetFps(&FpsCounter));
375
 
376 19 jack
    int width = pspFontGetTextWidth(&PspStockFont, fps_display);
377
    int height = pspFontGetLineHeight(&PspStockFont);
378 23 jack
 
379 61 jack
    pspVideoFillRect(SCR_WIDTH - width, 0, SCR_WIDTH, height, PSP_COLOR_BLACK);
380
    pspVideoPrint(&PspStockFont, SCR_WIDTH - width, 0, fps_display, PSP_COLOR_WHITE);
381 19 jack
  }
382
 
383
  pspVideoEnd();
384
 
385 27 jack
  /* Wait if needed */
386 354 jack
  if (ActiveOptions.UpdateFreq)// && AdhocMode != ADHOC_CLIENT)
387 27 jack
  {
388
    do { sceRtcGetCurrentTick(&CurrentTick); }
389
    while (CurrentTick - LastTick < TicksPerUpdate);
390
    LastTick = CurrentTick;
391
  }
392
 
393 19 jack
  /* Wait for VSync signal */
394 354 jack
  if (ActiveOptions.VSync)
395
    pspVideoWaitVSync();
396 19 jack
 
397
  /* Swap buffers */
398
  pspVideoSwapBuffers();
399
}
400
 
401 49 jack
/* Generic FM+PSG stereo mixer callback */
402
void MixerCallback(int16 **stream, int16 **output, int length)
403
{
404
  /* Set up buffer pointers */
405
  int16 **fm_buffer = (int16 **)&stream[STREAM_FM_MO];
406
  int16 **psg_buffer = (int16 **)&stream[STREAM_PSG_L];
407
  int i;
408
 
409
  for(i = 0; i < length; i++)
410
  {
411
    int16 temp = (fm_buffer[0][i] + fm_buffer[1][i]) >> 1;
412 77 jack
    output[0][i] = (temp + psg_buffer[0][i]) << Options.SoundBoost;
413
    output[1][i] = (temp + psg_buffer[1][i]) << Options.SoundBoost;
414 49 jack
  }
415
}
416
 
417 23 jack
void AudioCallback(void* buf, unsigned int *length, void *userdata)
418
{
419 204 jack
  PspStereoSample *OutBuf = (PspStereoSample*)buf;
420 23 jack
  int i;
421
 
422
  for(i = 0; i < *length; i++)
423
  {
424 52 jack
    OutBuf[i].Left = snd.output[0][i];
425
    OutBuf[i].Right = snd.output[1][i];
426 23 jack
  }
427
}