view src/sdl/TestEmu.cpp @ 530:8d3177d19d5f

added full recording function.
author Robert McIntyre <rlm@mit.edu>
date Sun, 24 Jun 2012 16:47:18 -0500
parents f9f4f1b99eed
children
line wrap: on
line source
1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2004 Forgotten and the VBA development team
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or(at your option)
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
26 #include "AutoBuild.h"
28 #include "SDL.h"
29 #include "debugger.h"
30 #include "common/System.h"
31 #include "common/unzip.h"
32 #include "common/Util.h"
33 #include "gba/GBA.h"
34 #include "gba/GBAGlobals.h"
35 #include "gba/GBASound.h"
36 #include "gb/GB.h"
37 #include "gb/gbGlobals.h"
39 #ifndef WIN32
40 # include <unistd.h>
41 # define GETCWD getcwd
42 #else // WIN32
43 # include <direct.h>
44 # define GETCWD _getcwd
45 #endif // WIN32
47 #ifdef MMX
48 extern "C" bool cpu_mmx;
49 #endif
50 extern bool8 soundEcho;
51 extern bool8 soundLowPass;
52 extern bool8 soundReverse;
54 extern void remoteInit();
55 extern void remoteCleanUp();
56 extern void remoteStubMain();
57 extern void remoteStubSignal(int,int);
58 extern void remoteOutput(char *, u32);
59 extern void remoteSetProtocol(int);
60 extern void remoteSetPort(int);
61 extern void debuggerOutput(char *, u32);
63 struct EmulatedSystem emulator;
65 int systemRedShift = 0;
66 int systemBlueShift = 16;
67 int systemGreenShift = 8;
68 int systemColorDepth = 32;
69 int systemDebug = 0;
70 int systemVerbose = 0;
71 int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
73 int sensorX = 2047;
74 int sensorY = 2047;
75 bool sensorOn = false;
77 int cartridgeType = 3;
78 int captureFormat = 0;
80 int emulating = 0;
81 int RGB_LOW_BITS_MASK=0x821;
82 int systemFrameSkip = 0;
83 u32 systemColorMap32[0x10000];
84 u16 systemColorMap16[0x10000];
85 u16 systemGbPalette[24];
86 char filename[2048];
87 char biosFileName[2048];
88 char captureDir[2048];
89 char saveDir[2048];
90 char batteryDir[2048];
92 int throttle = 0;
94 bool paused = false;
95 bool debugger = true;
96 bool debuggerStub = false;
97 bool systemSoundOn = false;
98 bool removeIntros = false;
99 int sdlFlashSize = 0;
100 int sdlAutoIPS = 1;
101 int sdlRtcEnable = 0;
102 int sdlAgbPrint = 0;
104 int sdlDefaultJoypad = 0;
106 u16 motion[4] = {
107 SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2
108 };
110 extern void debuggerSignal(int,int);
112 void (*dbgMain)() = debuggerMain;
113 void (*dbgSignal)(int,int) = debuggerSignal;
114 void (*dbgOutput)(char *, u32) = debuggerOutput;
116 char *sdlGetFilename(char *name)
117 {
118 static char filebuffer[2048];
120 int len = strlen(name);
122 char *p = name + len - 1;
124 while(true) {
125 if(*p == '/' ||
126 *p == '\\') {
127 p++;
128 break;
129 }
130 len--;
131 p--;
132 if(len == 0)
133 break;
134 }
136 if(len == 0)
137 strcpy(filebuffer, name);
138 else
139 strcpy(filebuffer, p);
140 return filebuffer;
141 }
143 void usage(char *cmd)
144 {
145 printf("%s file-name\n",cmd);
146 }
148 int main(int argc, char **argv)
149 {
150 fprintf(stderr,"VisualBoyAdvance-Test version %s\n", VERSION);
152 captureDir[0] = 0;
153 saveDir[0] = 0;
154 batteryDir[0] = 0;
156 char buffer[1024];
158 systemFrameSkip = frameSkip = 2;
159 gbBorderOn = 0;
161 parseDebug = true;
163 if(!debuggerStub) {
164 if(argc <= 1) {
165 systemMessage(0,"Missing image name");
166 usage(argv[0]);
167 exit(-1);
168 }
169 }
171 for(int i = 0; i < 24;) {
172 systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10);
173 systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10);
174 systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10);
175 systemGbPalette[i++] = 0;
176 }
178 if(argc == 2) {
179 char *szFile = argv[optind];
180 bool failed = false;
181 if(utilIsZipFile(szFile)) {
182 unzFile unz = unzOpen(szFile);
184 if(unz == NULL) {
185 systemMessage(0, "Cannot open file %s", szFile);
186 exit(-1);
187 }
188 int r = unzGoToFirstFile(unz);
190 if(r != UNZ_OK) {
191 unzClose(unz);
192 systemMessage(0, "Bad ZIP file %s", szFile);
193 exit(-1);
194 }
196 bool found = false;
198 unz_file_info info;
200 while(true) {
201 r = unzGetCurrentFileInfo(unz,
202 &info,
203 buffer,
204 sizeof(buffer),
205 NULL,
206 0,
207 NULL,
208 0);
210 if(r != UNZ_OK) {
211 unzClose(unz);
212 systemMessage(0,"Bad ZIP file %s", szFile);
213 exit(-1);
214 }
216 if(utilIsGBImage(buffer)) {
217 found = true;
218 cartridgeType = 1;
219 break;
220 }
221 if(utilIsGBAImage(buffer)) {
222 found = true;
223 cartridgeType = 0;
224 break;
225 }
227 r = unzGoToNextFile(unz);
229 if(r != UNZ_OK)
230 break;
231 }
233 if(!found) {
234 unzClose(unz);
235 systemMessage(0, "No image found on ZIP file %s", szFile);
236 exit(-1);
237 }
239 unzClose(unz);
240 }
242 if(utilIsGBImage(szFile) || cartridgeType == 1) {
243 failed = !gbLoadRom(szFile);
244 cartridgeType = 1;
245 emulator = GBSystem;
246 } else if(utilIsGBAImage(szFile) || cartridgeType == 0) {
247 failed = !CPULoadRom(szFile);
248 cartridgeType = 0;
249 emulator = GBASystem;
251 //CPUInit(biosFileName, useBios);
252 CPUInit();
253 CPUReset();
254 } else {
255 systemMessage(0, "Unknown file type %s", szFile);
256 exit(-1);
257 }
259 if(failed) {
260 systemMessage(0, "Failed to load file %s", szFile);
261 exit(-1);
262 }
263 strcpy(filename, szFile);
264 char *p = strrchr(filename, '.');
266 if(p)
267 *p = 0;
268 } else {
269 cartridgeType = 0;
270 strcpy(filename, "gnu_stub");
271 rom = (u8 *)malloc(0x2000000);
272 workRAM = (u8 *)calloc(1, 0x40000);
273 bios = (u8 *)calloc(1,0x4000);
274 internalRAM = (u8 *)calloc(1,0x8000);
275 paletteRAM = (u8 *)calloc(1,0x400);
276 vram = (u8 *)calloc(1, 0x20000);
277 oam = (u8 *)calloc(1, 0x400);
278 pix = (u8 *)calloc(1, 4 * 240 * 160);
279 ioMem = (u8 *)calloc(1, 0x400);
281 emulator = GBASystem;
283 //CPUInit(biosFileName, useBios);
284 CPUInit();
285 CPUReset();
286 }
288 if(debuggerStub)
289 remoteInit();
291 if(cartridgeType == 0) {
292 } else if (cartridgeType == 1) {
293 if(gbBorderOn) {
294 gbBorderLineSkip = 256;
295 gbBorderColumnSkip = 48;
296 gbBorderRowSkip = 40;
297 } else {
298 gbBorderLineSkip = 160;
299 gbBorderColumnSkip = 0;
300 gbBorderRowSkip = 0;
301 }
302 } else {
303 }
305 for(int i = 0; i < 0x10000; i++) {
306 systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
307 (((i & 0x3e0) >> 5) << systemGreenShift) |
308 (((i & 0x7c00) >> 10) << systemBlueShift);
309 }
311 emulating = 1;
312 soundInit();
314 while(emulating) {
315 if(!paused) {
316 if(debugger && emulator.emuHasDebugger)
317 dbgMain();
318 else
319 emulator.emuMain(emulator.emuCount);
320 }
321 }
322 emulating = 0;
323 fprintf(stderr,"Shutting down\n");
324 remoteCleanUp();
325 soundShutdown();
327 if(gbRom != NULL || rom != NULL) {
328 emulator.emuCleanUp();
329 }
331 return 0;
332 }
334 void systemMessage(int num, const char *msg, ...)
335 {
336 char buffer[2048];
337 va_list valist;
339 va_start(valist, msg);
340 vsprintf(buffer, msg, valist);
342 fprintf(stderr, "%s\n", buffer);
343 va_end(valist);
344 }
346 void systemDrawScreen()
347 {
348 }
350 bool systemReadJoypads()
351 {
352 return true;
353 }
355 u32 systemReadJoypad(int,bool)
356 {
357 return 0;
358 }
360 void systemShowSpeed(int speed)
361 {
362 }
364 void system10Frames(int rate)
365 {
366 }
368 void systemFrame(int)
369 {
370 }
372 void systemSetTitle(const char *title)
373 {
374 }
376 int systemScreenCapture(int a)
377 {
378 char buffer[2048];
380 if(captureFormat) {
381 if(captureDir[0])
382 sprintf(buffer, "%s/%s%02d.bmp", captureDir, sdlGetFilename(filename), a);
383 else
384 sprintf(buffer, "%s%02d.bmp", filename, a);
386 emulator.emuWriteBMP(buffer);
387 } else {
388 if(captureDir[0])
389 sprintf(buffer, "%s/%s%02d.png", captureDir, sdlGetFilename(filename), a);
390 else
391 sprintf(buffer, "%s%02d.png", filename, a);
392 emulator.emuWritePNG(buffer);
393 }
395 systemScreenMessage("Screen capture");
396 }
398 u32 systemReadJoypadExtended()
399 {
400 return 0;
401 }
403 void systemWriteDataToSoundBuffer()
404 {
405 }
407 bool systemSoundInit()
408 {
409 return true;
410 }
412 void systemSoundShutdown()
413 {
414 }
416 void systemSoundPause()
417 {
418 }
420 void systemSoundResume()
421 {
422 }
424 void systemSoundReset()
425 {
426 }
428 static int ticks = 0;
430 u32 systemGetClock()
431 {
432 return ticks++;
433 }
435 void systemUpdateMotionSensor()
436 {
437 }
439 int systemGetSensorX()
440 {
441 return 0;
442 }
444 int systemGetSensorY()
445 {
446 return 0;
447 }
449 void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast)
450 {
451 }
453 void systemScreenMessage(const char *msg, int slot, int duration, const char *colorList)
454 {
455 }
457 bool systemCanChangeSoundQuality()
458 {
459 return false;
460 }
462 bool systemPauseOnFrame()
463 {
464 return false;
465 }
467 void systemGbBorderOn()
468 {
469 }
471 bool sdlCheckJoyKey(int)
472 {
473 return true;
474 }
476 u16 checksumBIOS()
477 {
478 bool hasBIOS = false;
479 u8 * tempBIOS;
480 if(useBios)
481 {
482 tempBIOS = (u8 *)malloc(0x4000);
483 int size = 0x4000;
484 if(utilLoad(biosFileName,
485 utilIsGBABios,
486 tempBIOS,
487 size)) {
488 if(size == 0x4000)
489 hasBIOS = true;
490 }
491 }
493 u16 biosCheck = 0;
494 if(hasBIOS) {
495 for(int i = 0; i < 0x4000; i += 4)
496 biosCheck += *((u32 *)&tempBIOS[i]);
497 free(tempBIOS);
498 }
500 return biosCheck;
501 }