view src/gtk/system.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
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 <stdio.h>
20 #include <stdarg.h>
21 #include <string.h>
23 #include <SDL.h>
24 #include <SDL_thread.h>
26 #include "../common/System.h"
27 #include "../common/Util.h"
28 #include "../gba/GBAGlobals.h"
29 #include "../gb/gbGlobals.h"
30 #include "../gba/GBASound.h"
32 #include "window.h"
33 #include "intl.h"
35 // Required vars, used by the emulator core
36 //
37 int systemRedShift;
38 int systemGreenShift;
39 int systemBlueShift;
40 int systemColorDepth;
41 int systemDebug;
42 int systemVerbose;
43 int systemSaveUpdateCounter;
44 int systemFrameSkip;
45 u32 systemColorMap32[0x10000];
46 u16 systemColorMap16[0x10000];
47 u16 systemGbPalette[24];
48 bool systemSoundOn;
50 char filename[2048];
51 char biosFileName[2048];
52 //char captureDir[2048];
53 char saveDir[2048];
54 char batteryDir[2048];
56 int sensorX = 2047;
57 int sensorY = 2047;
58 bool sensorOn = false;
60 int emulating;
61 bool debugger;
62 int RGB_LOW_BITS_MASK;
64 int cartridgeType = 3;
65 int sizeOption = 0;
66 int captureFormat = 0;
67 int throttle = 0;
68 bool paused = false;
69 bool removeIntros = false;
70 int sdlFlashSize = 0;
71 int sdlRtcEnable = 0;
73 int sdlDefaultJoypad = 0;
75 SDL_Joystick **sdlDevices = NULL;
77 u16 motion[4] = {
78 SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2
79 };
81 struct EmulatedSystem emulator = {
82 NULL,
83 NULL,
84 NULL,
85 NULL,
86 NULL,
87 NULL,
88 NULL,
89 NULL,
90 NULL,
91 NULL,
92 NULL,
93 NULL,
94 false,
95 0
96 };
98 // Extra vars, only used for the GUI
99 //
100 int systemRenderedFrames;
101 int systemFPS;
103 // Sound stuff
104 //
105 const int iSoundSamples = 2048;
106 const int iSoundTotalLen = iSoundSamples * 4;
107 static u8 auiSoundBuffer[iSoundTotalLen];
108 static int iSoundLen;
109 static SDL_cond * pstSoundCond;
110 static SDL_mutex * pstSoundMutex;
112 inline VBA::Window * GUI()
113 {
114 return VBA::Window::poGetInstance();
115 }
117 void systemMessage(int _iId, const char * _csFormat, ...)
118 {
119 va_list args;
120 va_start(args, _csFormat);
122 GUI()->vPopupErrorV(_(_csFormat), args);
124 va_end(args);
125 }
127 void systemDrawScreen()
128 {
129 GUI()->vDrawScreen();
130 systemRenderedFrames++;
131 }
133 bool systemReadJoypads()
134 {
135 return true;
136 }
138 u32 systemReadJoypad(int,bool)
139 {
140 return GUI()->uiReadJoypad();
141 }
143 void systemShowSpeed(int _iSpeed)
144 {
145 systemFPS = systemRenderedFrames;
146 systemRenderedFrames = 0;
148 GUI()->vShowSpeed(_iSpeed);
149 }
151 void system10Frames(int _iRate)
152 {
153 GUI()->vComputeFrameskip(_iRate);
154 }
156 void systemFrame(int)
157 {
158 }
160 void systemSetTitle(const char * _csTitle)
161 {
162 GUI()->set_title(_csTitle);
163 }
165 int systemScreenCapture(int _iNum)
166 {
167 GUI()->vCaptureScreen(_iNum);
168 }
170 void systemSoundWriteToBuffer()
171 {
172 if (SDL_GetAudioStatus() != SDL_AUDIO_PLAYING)
173 {
174 SDL_PauseAudio(0);
175 }
177 bool bWait = true;
178 while (bWait && ! speedup && GUI()->iGetThrottle() == 0)
179 {
180 SDL_mutexP(pstSoundMutex);
181 if (iSoundLen < iSoundTotalLen)
182 {
183 bWait = false;
184 }
185 SDL_mutexV(pstSoundMutex);
186 }
188 int iLen = soundBufferLen;
189 int iCopied = 0;
190 if (iSoundLen + iLen >= iSoundTotalLen)
191 {
192 iCopied = iSoundTotalLen - iSoundLen;
193 memcpy(&auiSoundBuffer[iSoundLen], soundFinalWave, iCopied);
195 iSoundLen = iSoundTotalLen;
196 SDL_CondSignal(pstSoundCond);
198 bWait = true;
199 if (! speedup && GUI()->iGetThrottle() == 0)
200 {
201 while(bWait)
202 {
203 SDL_mutexP(pstSoundMutex);
204 if (iSoundLen < iSoundTotalLen)
205 {
206 bWait = false;
207 }
208 SDL_mutexV(pstSoundMutex);
209 }
211 memcpy(auiSoundBuffer, ((u8 *)soundFinalWave) + iCopied,
212 soundBufferLen - iCopied);
214 iSoundLen = soundBufferLen - iCopied;
215 }
216 else
217 {
218 memcpy(auiSoundBuffer, ((u8 *)soundFinalWave) + iCopied,
219 soundBufferLen);
220 }
221 }
222 else
223 {
224 memcpy(&auiSoundBuffer[iSoundLen], soundFinalWave, soundBufferLen);
225 iSoundLen += soundBufferLen;
226 }
227 }
229 static void vSoundCallback(void * _pvUserData, u8 * _puiStream, int _iLen)
230 {
231 if (! emulating)
232 {
233 return;
234 }
236 SDL_mutexP(pstSoundMutex);
237 if (! speedup && GUI()->iGetThrottle() == 0)
238 {
239 while (iSoundLen < iSoundTotalLen && emulating)
240 {
241 SDL_CondWait(pstSoundCond, pstSoundMutex);
242 }
243 }
244 if (emulating)
245 {
246 memcpy(_puiStream, auiSoundBuffer, _iLen);
247 }
248 iSoundLen = 0;
249 SDL_mutexV(pstSoundMutex);
250 }
252 bool systemSoundInit()
253 {
254 SDL_AudioSpec stAudio;
256 switch (soundQuality)
257 {
258 case 1:
259 stAudio.freq = 44100;
260 soundBufferLen = 1470 * 2;
261 break;
262 case 2:
263 stAudio.freq = 22050;
264 soundBufferLen = 736 * 2;
265 break;
266 case 4:
267 stAudio.freq = 11025;
268 soundBufferLen = 368 * 2;
269 break;
270 }
272 stAudio.format = AUDIO_S16SYS;
273 stAudio.channels = 2;
274 stAudio.samples = iSoundSamples;
275 stAudio.callback = vSoundCallback;
276 stAudio.userdata = NULL;
278 if (SDL_OpenAudio(&stAudio, NULL) < 0)
279 {
280 fprintf(stderr, "Failed to open audio: %s\n", SDL_GetError());
281 return false;
282 }
284 pstSoundCond = SDL_CreateCond();
285 pstSoundMutex = SDL_CreateMutex();
287 soundBufferTotalLen = soundBufferLen * 10;
288 iSoundLen = 0;
289 systemSoundOn = true;
291 return true;
292 }
294 void systemSoundShutdown()
295 {
296 SDL_mutexP(pstSoundMutex);
297 int iSave = emulating;
298 emulating = 0;
299 SDL_CondSignal(pstSoundCond);
300 SDL_mutexV(pstSoundMutex);
302 SDL_DestroyCond(pstSoundCond);
303 pstSoundCond = NULL;
305 SDL_DestroyMutex(pstSoundMutex);
306 pstSoundMutex = NULL;
308 SDL_CloseAudio();
310 emulating = iSave;
311 systemSoundOn = false;
312 }
314 void systemSoundPause()
315 {
316 SDL_PauseAudio(1);
317 }
319 void systemSoundResume()
320 {
321 SDL_PauseAudio(0);
322 }
324 void systemSoundReset()
325 {
326 }
328 u32 systemGetClock()
329 {
330 return SDL_GetTicks();
331 }
333 void systemUpdateMotionSensor()
334 {
335 }
337 int systemGetSensorX()
338 {
339 return 0;
340 }
342 int systemGetSensorY()
343 {
344 return 0;
345 }
347 void systemGbPrint(u8 * _puiData,
348 int _iPages,
349 int _iFeed,
350 int _iPalette,
351 int _iContrast)
352 {
353 }
355 void systemScreenMessage(const char * _csMsg, int slot, int duration, const char *colorList)
356 {
357 }
359 bool systemCanChangeSoundQuality()
360 {
361 return true;
362 }
364 bool systemPauseOnFrame()
365 {
366 return false;
367 }
369 void systemGbBorderOn()
370 {
371 }
373 void debuggerMain()
374 {
375 }
377 void debuggerSignal(int, int)
378 {
379 }
381 void debuggerOutput(char *, u32)
382 {
383 }
385 char *sdlGetFilename(char *name)
386 {
387 static char filebuffer[2048];
389 int len = strlen(name);
391 char *p = name + len - 1;
393 while(true) {
394 if(*p == '/' ||
395 *p == '\\') {
396 p++;
397 break;
398 }
399 len--;
400 p--;
401 if(len == 0)
402 break;
403 }
405 if(len == 0)
406 strcpy(filebuffer, name);
407 else
408 strcpy(filebuffer, p);
409 return filebuffer;
410 }
412 bool sdlCheckJoyKey(int key)
413 {
414 int dev = (key >> 12) - 1;
415 int what = key & 0xfff;
417 if(what >= 128) {
418 // joystick button
419 int button = what - 128;
421 if(button >= SDL_JoystickNumButtons(sdlDevices[dev]))
422 return false;
423 } else if (what < 0x20) {
424 // joystick axis
425 what >>= 1;
426 if(what >= SDL_JoystickNumAxes(sdlDevices[dev]))
427 return false;
428 } else if (what < 0x30) {
429 // joystick hat
430 what = (what & 15);
431 what >>= 2;
432 if(what >= SDL_JoystickNumHats(sdlDevices[dev]))
433 return false;
434 }
436 // no problem found
437 return true;
438 }
440 u16 checksumBIOS()
441 {
442 bool hasBIOS = false;
443 u8 * tempBIOS;
444 if(useBios)
445 {
446 tempBIOS = (u8 *)malloc(0x4000);
447 int size = 0x4000;
448 if(utilLoad(biosFileName,
449 utilIsGBABios,
450 tempBIOS,
451 size)) {
452 if(size == 0x4000)
453 hasBIOS = true;
454 }
455 }
457 u16 biosCheck = 0;
458 if(hasBIOS) {
459 for(int i = 0; i < 0x4000; i += 4)
460 biosCheck += *((u32 *)&tempBIOS[i]);
461 free(tempBIOS);
462 }
464 return biosCheck;
465 }
467 void (*dbgMain)() = debuggerMain;
468 void (*dbgSignal)(int, int) = debuggerSignal;
469 void (*dbgOutput)(char *, u32) = debuggerOutput;