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)
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.
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.
24 #include <SDL_thread.h>
28 #include "../gb/gbGlobals.h"
35 // Required vars, used by the emulator core
43 int systemSaveUpdateCounter
;
45 u32 systemColorMap32
[0x10000];
46 u16 systemColorMap16
[0x10000];
47 u16 systemGbPalette
[24];
52 int RGB_LOW_BITS_MASK
;
54 // Extra vars, only used for the GUI
56 int systemRenderedFrames
;
61 const int iSoundSamples
= 2048;
62 const int iSoundTotalLen
= iSoundSamples
* 4;
63 static u8 auiSoundBuffer
[iSoundTotalLen
];
65 static SDL_cond
* pstSoundCond
;
66 static SDL_mutex
* pstSoundMutex
;
68 inline VBA::Window
* GUI()
70 return VBA::Window::poGetInstance();
73 void systemMessage(int _iId
, const char * _csFormat
, ...)
76 va_start(args
, _csFormat
);
78 GUI()->vPopupErrorV(_(_csFormat
), args
);
83 void systemDrawScreen()
86 systemRenderedFrames
++;
89 bool systemReadJoypads()
94 u32
systemReadJoypad(int)
96 return GUI()->uiReadJoypad();
99 void systemShowSpeed(int _iSpeed
)
101 systemFPS
= systemRenderedFrames
;
102 systemRenderedFrames
= 0;
104 GUI()->vShowSpeed(_iSpeed
);
107 void system10Frames(int _iRate
)
109 GUI()->vComputeFrameskip(_iRate
);
116 void systemSetTitle(const char * _csTitle
)
118 GUI()->set_title(_csTitle
);
121 void systemScreenCapture(int _iNum
)
123 GUI()->vCaptureScreen(_iNum
);
126 void systemWriteDataToSoundBuffer()
128 if (SDL_GetAudioStatus() != SDL_AUDIO_PLAYING
)
134 while (bWait
&& ! speedup
&& GUI()->iGetThrottle() == 0)
136 SDL_mutexP(pstSoundMutex
);
137 if (iSoundLen
< iSoundTotalLen
)
141 SDL_mutexV(pstSoundMutex
);
144 int iLen
= soundBufferLen
;
146 if (iSoundLen
+ iLen
>= iSoundTotalLen
)
148 iCopied
= iSoundTotalLen
- iSoundLen
;
149 memcpy(&auiSoundBuffer
[iSoundLen
], soundFinalWave
, iCopied
);
151 iSoundLen
= iSoundTotalLen
;
152 SDL_CondSignal(pstSoundCond
);
155 if (! speedup
&& GUI()->iGetThrottle() == 0)
159 SDL_mutexP(pstSoundMutex
);
160 if (iSoundLen
< iSoundTotalLen
)
164 SDL_mutexV(pstSoundMutex
);
167 memcpy(auiSoundBuffer
, ((u8
*)soundFinalWave
) + iCopied
,
168 soundBufferLen
- iCopied
);
170 iSoundLen
= soundBufferLen
- iCopied
;
174 memcpy(auiSoundBuffer
, ((u8
*)soundFinalWave
) + iCopied
,
180 memcpy(&auiSoundBuffer
[iSoundLen
], soundFinalWave
, soundBufferLen
);
181 iSoundLen
+= soundBufferLen
;
185 static void vSoundCallback(void * _pvUserData
, u8
* _puiStream
, int _iLen
)
192 SDL_mutexP(pstSoundMutex
);
193 if (! speedup
&& GUI()->iGetThrottle() == 0)
195 while (iSoundLen
< iSoundTotalLen
&& emulating
)
197 SDL_CondWait(pstSoundCond
, pstSoundMutex
);
202 memcpy(_puiStream
, auiSoundBuffer
, _iLen
);
205 SDL_mutexV(pstSoundMutex
);
208 bool systemSoundInit()
210 SDL_AudioSpec stAudio
;
212 switch (soundQuality
)
215 stAudio
.freq
= 44100;
216 soundBufferLen
= 1470 * 2;
219 stAudio
.freq
= 22050;
220 soundBufferLen
= 736 * 2;
223 stAudio
.freq
= 11025;
224 soundBufferLen
= 368 * 2;
228 stAudio
.format
= AUDIO_S16SYS
;
229 stAudio
.channels
= 2;
230 stAudio
.samples
= iSoundSamples
;
231 stAudio
.callback
= vSoundCallback
;
232 stAudio
.userdata
= NULL
;
234 if (SDL_OpenAudio(&stAudio
, NULL
) < 0)
236 fprintf(stderr
, "Failed to open audio: %s\n", SDL_GetError());
240 pstSoundCond
= SDL_CreateCond();
241 pstSoundMutex
= SDL_CreateMutex();
243 soundBufferTotalLen
= soundBufferLen
* 10;
245 systemSoundOn
= true;
250 void systemSoundShutdown()
252 SDL_mutexP(pstSoundMutex
);
253 int iSave
= emulating
;
255 SDL_CondSignal(pstSoundCond
);
256 SDL_mutexV(pstSoundMutex
);
258 SDL_DestroyCond(pstSoundCond
);
261 SDL_DestroyMutex(pstSoundMutex
);
262 pstSoundMutex
= NULL
;
267 systemSoundOn
= false;
270 void systemSoundPause()
275 void systemSoundResume()
280 void systemSoundReset()
286 return SDL_GetTicks();
289 void systemUpdateMotionSensor()
293 int systemGetSensorX()
298 int systemGetSensorY()
303 void systemGbPrint(u8
* _puiData
,
311 void systemScreenMessage(const char * _csMsg
)
315 bool systemCanChangeSoundQuality()
320 bool systemPauseOnFrame()
325 void systemGbBorderOn()
333 void debuggerSignal(int, int)
337 void debuggerOutput(char *, u32
)
341 void debuggerBreakOnWrite(u32 address
, u32 oldvalue
, u32 value
, int size
, int t
)
345 void (*dbgMain
)() = debuggerMain
;
346 void (*dbgSignal
)(int, int) = debuggerSignal
;
347 void (*dbgOutput
)(char *, u32
) = debuggerOutput
;