Mercurial > vba-linux
comparison 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 |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. | |
2 // Copyright (C) 1999-2003 Forgotten | |
3 // Copyright (C) 2004 Forgotten and the VBA development team | |
4 | |
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. | |
18 | |
19 #include <stdio.h> | |
20 #include <stdarg.h> | |
21 #include <string.h> | |
22 | |
23 #include <SDL.h> | |
24 #include <SDL_thread.h> | |
25 | |
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" | |
31 | |
32 #include "window.h" | |
33 #include "intl.h" | |
34 | |
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; | |
49 | |
50 char filename[2048]; | |
51 char biosFileName[2048]; | |
52 //char captureDir[2048]; | |
53 char saveDir[2048]; | |
54 char batteryDir[2048]; | |
55 | |
56 int sensorX = 2047; | |
57 int sensorY = 2047; | |
58 bool sensorOn = false; | |
59 | |
60 int emulating; | |
61 bool debugger; | |
62 int RGB_LOW_BITS_MASK; | |
63 | |
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; | |
72 | |
73 int sdlDefaultJoypad = 0; | |
74 | |
75 SDL_Joystick **sdlDevices = NULL; | |
76 | |
77 u16 motion[4] = { | |
78 SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2 | |
79 }; | |
80 | |
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 }; | |
97 | |
98 // Extra vars, only used for the GUI | |
99 // | |
100 int systemRenderedFrames; | |
101 int systemFPS; | |
102 | |
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; | |
111 | |
112 inline VBA::Window * GUI() | |
113 { | |
114 return VBA::Window::poGetInstance(); | |
115 } | |
116 | |
117 void systemMessage(int _iId, const char * _csFormat, ...) | |
118 { | |
119 va_list args; | |
120 va_start(args, _csFormat); | |
121 | |
122 GUI()->vPopupErrorV(_(_csFormat), args); | |
123 | |
124 va_end(args); | |
125 } | |
126 | |
127 void systemDrawScreen() | |
128 { | |
129 GUI()->vDrawScreen(); | |
130 systemRenderedFrames++; | |
131 } | |
132 | |
133 bool systemReadJoypads() | |
134 { | |
135 return true; | |
136 } | |
137 | |
138 u32 systemReadJoypad(int,bool) | |
139 { | |
140 return GUI()->uiReadJoypad(); | |
141 } | |
142 | |
143 void systemShowSpeed(int _iSpeed) | |
144 { | |
145 systemFPS = systemRenderedFrames; | |
146 systemRenderedFrames = 0; | |
147 | |
148 GUI()->vShowSpeed(_iSpeed); | |
149 } | |
150 | |
151 void system10Frames(int _iRate) | |
152 { | |
153 GUI()->vComputeFrameskip(_iRate); | |
154 } | |
155 | |
156 void systemFrame(int) | |
157 { | |
158 } | |
159 | |
160 void systemSetTitle(const char * _csTitle) | |
161 { | |
162 GUI()->set_title(_csTitle); | |
163 } | |
164 | |
165 int systemScreenCapture(int _iNum) | |
166 { | |
167 GUI()->vCaptureScreen(_iNum); | |
168 } | |
169 | |
170 void systemSoundWriteToBuffer() | |
171 { | |
172 if (SDL_GetAudioStatus() != SDL_AUDIO_PLAYING) | |
173 { | |
174 SDL_PauseAudio(0); | |
175 } | |
176 | |
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 } | |
187 | |
188 int iLen = soundBufferLen; | |
189 int iCopied = 0; | |
190 if (iSoundLen + iLen >= iSoundTotalLen) | |
191 { | |
192 iCopied = iSoundTotalLen - iSoundLen; | |
193 memcpy(&auiSoundBuffer[iSoundLen], soundFinalWave, iCopied); | |
194 | |
195 iSoundLen = iSoundTotalLen; | |
196 SDL_CondSignal(pstSoundCond); | |
197 | |
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 } | |
210 | |
211 memcpy(auiSoundBuffer, ((u8 *)soundFinalWave) + iCopied, | |
212 soundBufferLen - iCopied); | |
213 | |
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 } | |
228 | |
229 static void vSoundCallback(void * _pvUserData, u8 * _puiStream, int _iLen) | |
230 { | |
231 if (! emulating) | |
232 { | |
233 return; | |
234 } | |
235 | |
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 } | |
251 | |
252 bool systemSoundInit() | |
253 { | |
254 SDL_AudioSpec stAudio; | |
255 | |
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 } | |
271 | |
272 stAudio.format = AUDIO_S16SYS; | |
273 stAudio.channels = 2; | |
274 stAudio.samples = iSoundSamples; | |
275 stAudio.callback = vSoundCallback; | |
276 stAudio.userdata = NULL; | |
277 | |
278 if (SDL_OpenAudio(&stAudio, NULL) < 0) | |
279 { | |
280 fprintf(stderr, "Failed to open audio: %s\n", SDL_GetError()); | |
281 return false; | |
282 } | |
283 | |
284 pstSoundCond = SDL_CreateCond(); | |
285 pstSoundMutex = SDL_CreateMutex(); | |
286 | |
287 soundBufferTotalLen = soundBufferLen * 10; | |
288 iSoundLen = 0; | |
289 systemSoundOn = true; | |
290 | |
291 return true; | |
292 } | |
293 | |
294 void systemSoundShutdown() | |
295 { | |
296 SDL_mutexP(pstSoundMutex); | |
297 int iSave = emulating; | |
298 emulating = 0; | |
299 SDL_CondSignal(pstSoundCond); | |
300 SDL_mutexV(pstSoundMutex); | |
301 | |
302 SDL_DestroyCond(pstSoundCond); | |
303 pstSoundCond = NULL; | |
304 | |
305 SDL_DestroyMutex(pstSoundMutex); | |
306 pstSoundMutex = NULL; | |
307 | |
308 SDL_CloseAudio(); | |
309 | |
310 emulating = iSave; | |
311 systemSoundOn = false; | |
312 } | |
313 | |
314 void systemSoundPause() | |
315 { | |
316 SDL_PauseAudio(1); | |
317 } | |
318 | |
319 void systemSoundResume() | |
320 { | |
321 SDL_PauseAudio(0); | |
322 } | |
323 | |
324 void systemSoundReset() | |
325 { | |
326 } | |
327 | |
328 u32 systemGetClock() | |
329 { | |
330 return SDL_GetTicks(); | |
331 } | |
332 | |
333 void systemUpdateMotionSensor() | |
334 { | |
335 } | |
336 | |
337 int systemGetSensorX() | |
338 { | |
339 return 0; | |
340 } | |
341 | |
342 int systemGetSensorY() | |
343 { | |
344 return 0; | |
345 } | |
346 | |
347 void systemGbPrint(u8 * _puiData, | |
348 int _iPages, | |
349 int _iFeed, | |
350 int _iPalette, | |
351 int _iContrast) | |
352 { | |
353 } | |
354 | |
355 void systemScreenMessage(const char * _csMsg, int slot, int duration, const char *colorList) | |
356 { | |
357 } | |
358 | |
359 bool systemCanChangeSoundQuality() | |
360 { | |
361 return true; | |
362 } | |
363 | |
364 bool systemPauseOnFrame() | |
365 { | |
366 return false; | |
367 } | |
368 | |
369 void systemGbBorderOn() | |
370 { | |
371 } | |
372 | |
373 void debuggerMain() | |
374 { | |
375 } | |
376 | |
377 void debuggerSignal(int, int) | |
378 { | |
379 } | |
380 | |
381 void debuggerOutput(char *, u32) | |
382 { | |
383 } | |
384 | |
385 char *sdlGetFilename(char *name) | |
386 { | |
387 static char filebuffer[2048]; | |
388 | |
389 int len = strlen(name); | |
390 | |
391 char *p = name + len - 1; | |
392 | |
393 while(true) { | |
394 if(*p == '/' || | |
395 *p == '\\') { | |
396 p++; | |
397 break; | |
398 } | |
399 len--; | |
400 p--; | |
401 if(len == 0) | |
402 break; | |
403 } | |
404 | |
405 if(len == 0) | |
406 strcpy(filebuffer, name); | |
407 else | |
408 strcpy(filebuffer, p); | |
409 return filebuffer; | |
410 } | |
411 | |
412 bool sdlCheckJoyKey(int key) | |
413 { | |
414 int dev = (key >> 12) - 1; | |
415 int what = key & 0xfff; | |
416 | |
417 if(what >= 128) { | |
418 // joystick button | |
419 int button = what - 128; | |
420 | |
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 } | |
435 | |
436 // no problem found | |
437 return true; | |
438 } | |
439 | |
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 } | |
456 | |
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 } | |
463 | |
464 return biosCheck; | |
465 } | |
466 | |
467 void (*dbgMain)() = debuggerMain; | |
468 void (*dbgSignal)(int, int) = debuggerSignal; | |
469 void (*dbgOutput)(char *, u32) = debuggerOutput; |