diff 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 diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/gtk/system.cpp	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,469 @@
     1.4 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
     1.5 +// Copyright (C) 1999-2003 Forgotten
     1.6 +// Copyright (C) 2004 Forgotten and the VBA development team
     1.7 +
     1.8 +// This program is free software; you can redistribute it and/or modify
     1.9 +// it under the terms of the GNU General Public License as published by
    1.10 +// the Free Software Foundation; either version 2, or(at your option)
    1.11 +// any later version.
    1.12 +//
    1.13 +// This program is distributed in the hope that it will be useful,
    1.14 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.16 +// GNU General Public License for more details.
    1.17 +//
    1.18 +// You should have received a copy of the GNU General Public License
    1.19 +// along with this program; if not, write to the Free Software Foundation,
    1.20 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    1.21 +
    1.22 +#include <stdio.h>
    1.23 +#include <stdarg.h>
    1.24 +#include <string.h>
    1.25 +
    1.26 +#include <SDL.h>
    1.27 +#include <SDL_thread.h>
    1.28 +
    1.29 +#include "../common/System.h"
    1.30 +#include "../common/Util.h"
    1.31 +#include "../gba/GBAGlobals.h"
    1.32 +#include "../gb/gbGlobals.h"
    1.33 +#include "../gba/GBASound.h"
    1.34 +
    1.35 +#include "window.h"
    1.36 +#include "intl.h"
    1.37 +
    1.38 +// Required vars, used by the emulator core
    1.39 +//
    1.40 +int  systemRedShift;
    1.41 +int  systemGreenShift;
    1.42 +int  systemBlueShift;
    1.43 +int  systemColorDepth;
    1.44 +int  systemDebug;
    1.45 +int  systemVerbose;
    1.46 +int  systemSaveUpdateCounter;
    1.47 +int  systemFrameSkip;
    1.48 +u32  systemColorMap32[0x10000];
    1.49 +u16  systemColorMap16[0x10000];
    1.50 +u16  systemGbPalette[24];
    1.51 +bool systemSoundOn;
    1.52 +
    1.53 +char filename[2048];
    1.54 +char biosFileName[2048];
    1.55 +//char captureDir[2048];
    1.56 +char saveDir[2048];
    1.57 +char batteryDir[2048];
    1.58 +
    1.59 +int sensorX = 2047;
    1.60 +int sensorY = 2047;
    1.61 +bool sensorOn = false;
    1.62 +
    1.63 +int  emulating;
    1.64 +bool debugger;
    1.65 +int  RGB_LOW_BITS_MASK;
    1.66 +
    1.67 +int cartridgeType = 3;
    1.68 +int sizeOption = 0;
    1.69 +int captureFormat = 0;
    1.70 +int throttle = 0;
    1.71 +bool paused = false;
    1.72 +bool removeIntros = false;
    1.73 +int sdlFlashSize = 0;
    1.74 +int sdlRtcEnable = 0;
    1.75 +
    1.76 +int sdlDefaultJoypad = 0;
    1.77 +
    1.78 +SDL_Joystick **sdlDevices = NULL;
    1.79 +
    1.80 +u16 motion[4] = {
    1.81 +  SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2
    1.82 +};
    1.83 +
    1.84 +struct EmulatedSystem emulator = {
    1.85 +  NULL,
    1.86 +  NULL,
    1.87 +  NULL,
    1.88 +  NULL,
    1.89 +  NULL,
    1.90 +  NULL,
    1.91 +  NULL,
    1.92 +  NULL,
    1.93 +  NULL,
    1.94 +  NULL,
    1.95 +  NULL,
    1.96 +  NULL,
    1.97 +  false,
    1.98 +  0
    1.99 +};
   1.100 +
   1.101 +// Extra vars, only used for the GUI
   1.102 +//
   1.103 +int systemRenderedFrames;
   1.104 +int systemFPS;
   1.105 +
   1.106 +// Sound stuff
   1.107 +//
   1.108 +const  int         iSoundSamples  = 2048;
   1.109 +const  int         iSoundTotalLen = iSoundSamples * 4;
   1.110 +static u8          auiSoundBuffer[iSoundTotalLen];
   1.111 +static int         iSoundLen;
   1.112 +static SDL_cond *  pstSoundCond;
   1.113 +static SDL_mutex * pstSoundMutex;
   1.114 +
   1.115 +inline VBA::Window * GUI()
   1.116 +{
   1.117 +  return VBA::Window::poGetInstance();
   1.118 +}
   1.119 +
   1.120 +void systemMessage(int _iId, const char * _csFormat, ...)
   1.121 +{
   1.122 +  va_list args;
   1.123 +  va_start(args, _csFormat);
   1.124 +
   1.125 +  GUI()->vPopupErrorV(_(_csFormat), args);
   1.126 +
   1.127 +  va_end(args);
   1.128 +}
   1.129 +
   1.130 +void systemDrawScreen()
   1.131 +{
   1.132 +  GUI()->vDrawScreen();
   1.133 +  systemRenderedFrames++;
   1.134 +}
   1.135 +
   1.136 +bool systemReadJoypads()
   1.137 +{
   1.138 +  return true;
   1.139 +}
   1.140 +
   1.141 +u32 systemReadJoypad(int,bool)
   1.142 +{
   1.143 +  return GUI()->uiReadJoypad();
   1.144 +}
   1.145 +
   1.146 +void systemShowSpeed(int _iSpeed)
   1.147 +{
   1.148 +  systemFPS = systemRenderedFrames;
   1.149 +  systemRenderedFrames = 0;
   1.150 +
   1.151 +  GUI()->vShowSpeed(_iSpeed);
   1.152 +}
   1.153 +
   1.154 +void system10Frames(int _iRate)
   1.155 +{
   1.156 +  GUI()->vComputeFrameskip(_iRate);
   1.157 +}
   1.158 +
   1.159 +void systemFrame(int)
   1.160 +{
   1.161 +}
   1.162 +
   1.163 +void systemSetTitle(const char * _csTitle)
   1.164 +{
   1.165 +  GUI()->set_title(_csTitle);
   1.166 +}
   1.167 +
   1.168 +int systemScreenCapture(int _iNum)
   1.169 +{
   1.170 +  GUI()->vCaptureScreen(_iNum);
   1.171 +}
   1.172 +
   1.173 +void systemSoundWriteToBuffer()
   1.174 +{
   1.175 +  if (SDL_GetAudioStatus() != SDL_AUDIO_PLAYING)
   1.176 +  {
   1.177 +    SDL_PauseAudio(0);
   1.178 +  }
   1.179 +
   1.180 +  bool bWait = true;
   1.181 +  while (bWait && ! speedup && GUI()->iGetThrottle() == 0)
   1.182 +  {
   1.183 +    SDL_mutexP(pstSoundMutex);
   1.184 +    if (iSoundLen < iSoundTotalLen)
   1.185 +    {
   1.186 +      bWait = false;
   1.187 +    }
   1.188 +    SDL_mutexV(pstSoundMutex);
   1.189 +  }
   1.190 +
   1.191 +  int iLen = soundBufferLen;
   1.192 +  int iCopied = 0;
   1.193 +  if (iSoundLen + iLen >= iSoundTotalLen)
   1.194 +  {
   1.195 +    iCopied = iSoundTotalLen - iSoundLen;
   1.196 +    memcpy(&auiSoundBuffer[iSoundLen], soundFinalWave, iCopied);
   1.197 +
   1.198 +    iSoundLen = iSoundTotalLen;
   1.199 +    SDL_CondSignal(pstSoundCond);
   1.200 +
   1.201 +    bWait = true;
   1.202 +    if (! speedup && GUI()->iGetThrottle() == 0)
   1.203 +    {
   1.204 +      while(bWait)
   1.205 +      {
   1.206 +        SDL_mutexP(pstSoundMutex);
   1.207 +        if (iSoundLen < iSoundTotalLen)
   1.208 +        {
   1.209 +          bWait = false;
   1.210 +        }
   1.211 +        SDL_mutexV(pstSoundMutex);
   1.212 +      }
   1.213 +
   1.214 +      memcpy(auiSoundBuffer, ((u8 *)soundFinalWave) + iCopied,
   1.215 +             soundBufferLen - iCopied);
   1.216 +
   1.217 +      iSoundLen = soundBufferLen - iCopied;
   1.218 +    }
   1.219 +    else
   1.220 +    {
   1.221 +      memcpy(auiSoundBuffer, ((u8 *)soundFinalWave) + iCopied,
   1.222 +             soundBufferLen);
   1.223 +    }
   1.224 +  }
   1.225 +  else
   1.226 +  {
   1.227 +    memcpy(&auiSoundBuffer[iSoundLen], soundFinalWave, soundBufferLen);
   1.228 +    iSoundLen += soundBufferLen;
   1.229 +  }
   1.230 +}
   1.231 +
   1.232 +static void vSoundCallback(void * _pvUserData, u8 * _puiStream, int _iLen)
   1.233 +{
   1.234 +  if (! emulating)
   1.235 +  {
   1.236 +    return;
   1.237 +  }
   1.238 +
   1.239 +  SDL_mutexP(pstSoundMutex);
   1.240 +  if (! speedup && GUI()->iGetThrottle() == 0)
   1.241 +  {
   1.242 +    while (iSoundLen < iSoundTotalLen && emulating)
   1.243 +    {
   1.244 +      SDL_CondWait(pstSoundCond, pstSoundMutex);
   1.245 +    }
   1.246 +  }
   1.247 +  if (emulating)
   1.248 +  {
   1.249 +    memcpy(_puiStream, auiSoundBuffer, _iLen);
   1.250 +  }
   1.251 +  iSoundLen = 0;
   1.252 +  SDL_mutexV(pstSoundMutex);
   1.253 +}
   1.254 +
   1.255 +bool systemSoundInit()
   1.256 +{
   1.257 +  SDL_AudioSpec stAudio;
   1.258 +
   1.259 +  switch (soundQuality)
   1.260 +  {
   1.261 +  case 1:
   1.262 +    stAudio.freq = 44100;
   1.263 +    soundBufferLen = 1470 * 2;
   1.264 +    break;
   1.265 +  case 2:
   1.266 +    stAudio.freq = 22050;
   1.267 +    soundBufferLen = 736 * 2;
   1.268 +    break;
   1.269 +  case 4:
   1.270 +    stAudio.freq = 11025;
   1.271 +    soundBufferLen = 368 * 2;
   1.272 +    break;
   1.273 +  }
   1.274 +
   1.275 +  stAudio.format   = AUDIO_S16SYS;
   1.276 +  stAudio.channels = 2;
   1.277 +  stAudio.samples  = iSoundSamples;
   1.278 +  stAudio.callback = vSoundCallback;
   1.279 +  stAudio.userdata = NULL;
   1.280 +
   1.281 +  if (SDL_OpenAudio(&stAudio, NULL) < 0)
   1.282 +  {
   1.283 +    fprintf(stderr, "Failed to open audio: %s\n", SDL_GetError());
   1.284 +    return false;
   1.285 +  }
   1.286 +
   1.287 +  pstSoundCond  = SDL_CreateCond();
   1.288 +  pstSoundMutex = SDL_CreateMutex();
   1.289 +
   1.290 +  soundBufferTotalLen = soundBufferLen * 10;
   1.291 +  iSoundLen = 0;
   1.292 +  systemSoundOn = true;
   1.293 +
   1.294 +  return true;
   1.295 +}
   1.296 +
   1.297 +void systemSoundShutdown()
   1.298 +{
   1.299 +  SDL_mutexP(pstSoundMutex);
   1.300 +  int iSave = emulating;
   1.301 +  emulating = 0;
   1.302 +  SDL_CondSignal(pstSoundCond);
   1.303 +  SDL_mutexV(pstSoundMutex);
   1.304 +
   1.305 +  SDL_DestroyCond(pstSoundCond);
   1.306 +  pstSoundCond = NULL;
   1.307 +
   1.308 +  SDL_DestroyMutex(pstSoundMutex);
   1.309 +  pstSoundMutex = NULL;
   1.310 +
   1.311 +  SDL_CloseAudio();
   1.312 +
   1.313 +  emulating = iSave;
   1.314 +  systemSoundOn = false;
   1.315 +}
   1.316 +
   1.317 +void systemSoundPause()
   1.318 +{
   1.319 +  SDL_PauseAudio(1);
   1.320 +}
   1.321 +
   1.322 +void systemSoundResume()
   1.323 +{
   1.324 +  SDL_PauseAudio(0);
   1.325 +}
   1.326 +
   1.327 +void systemSoundReset()
   1.328 +{
   1.329 +}
   1.330 +
   1.331 +u32 systemGetClock()
   1.332 +{
   1.333 +  return SDL_GetTicks();
   1.334 +}
   1.335 +
   1.336 +void systemUpdateMotionSensor()
   1.337 +{
   1.338 +}
   1.339 +
   1.340 +int systemGetSensorX()
   1.341 +{
   1.342 +  return 0;
   1.343 +}
   1.344 +
   1.345 +int systemGetSensorY()
   1.346 +{
   1.347 +  return 0;
   1.348 +}
   1.349 +
   1.350 +void systemGbPrint(u8 * _puiData,
   1.351 +                   int  _iPages,
   1.352 +                   int  _iFeed,
   1.353 +                   int  _iPalette,
   1.354 +                   int  _iContrast)
   1.355 +{
   1.356 +}
   1.357 +
   1.358 +void systemScreenMessage(const char * _csMsg, int slot, int duration, const char *colorList)
   1.359 +{
   1.360 +}
   1.361 +
   1.362 +bool systemCanChangeSoundQuality()
   1.363 +{
   1.364 +  return true;
   1.365 +}
   1.366 +
   1.367 +bool systemPauseOnFrame()
   1.368 +{
   1.369 +  return false;
   1.370 +}
   1.371 +
   1.372 +void systemGbBorderOn()
   1.373 +{
   1.374 +}
   1.375 +
   1.376 +void debuggerMain()
   1.377 +{
   1.378 +}
   1.379 +
   1.380 +void debuggerSignal(int, int)
   1.381 +{
   1.382 +}
   1.383 +
   1.384 +void debuggerOutput(char *, u32)
   1.385 +{
   1.386 +}
   1.387 +
   1.388 +char *sdlGetFilename(char *name)
   1.389 +{
   1.390 +  static char filebuffer[2048];
   1.391 +
   1.392 +  int len = strlen(name);
   1.393 +  
   1.394 +  char *p = name + len - 1;
   1.395 +  
   1.396 +  while(true) {
   1.397 +    if(*p == '/' ||
   1.398 +       *p == '\\') {
   1.399 +      p++;
   1.400 +      break;
   1.401 +    }
   1.402 +    len--;
   1.403 +    p--;
   1.404 +    if(len == 0)
   1.405 +      break;
   1.406 +  }
   1.407 +  
   1.408 +  if(len == 0)
   1.409 +    strcpy(filebuffer, name);
   1.410 +  else
   1.411 +    strcpy(filebuffer, p);
   1.412 +  return filebuffer;
   1.413 +}
   1.414 +
   1.415 +bool sdlCheckJoyKey(int key)
   1.416 +{
   1.417 +  int dev = (key >> 12) - 1;
   1.418 +  int what = key & 0xfff;
   1.419 +
   1.420 +  if(what >= 128) {
   1.421 +    // joystick button
   1.422 +    int button = what - 128;
   1.423 +
   1.424 +    if(button >= SDL_JoystickNumButtons(sdlDevices[dev]))
   1.425 +      return false;
   1.426 +  } else if (what < 0x20) {
   1.427 +    // joystick axis    
   1.428 +    what >>= 1;
   1.429 +    if(what >= SDL_JoystickNumAxes(sdlDevices[dev]))
   1.430 +      return false;
   1.431 +  } else if (what < 0x30) {
   1.432 +    // joystick hat
   1.433 +    what = (what & 15);
   1.434 +    what >>= 2;
   1.435 +    if(what >= SDL_JoystickNumHats(sdlDevices[dev]))
   1.436 +      return false;
   1.437 +  }
   1.438 +
   1.439 +  // no problem found
   1.440 +  return true;
   1.441 +}
   1.442 +
   1.443 +u16 checksumBIOS()
   1.444 +{
   1.445 +	bool hasBIOS = false;
   1.446 +	u8 * tempBIOS;
   1.447 +	if(useBios)
   1.448 +	{
   1.449 +		tempBIOS = (u8 *)malloc(0x4000);
   1.450 +		int size = 0x4000;
   1.451 +		if(utilLoad(biosFileName,
   1.452 +					utilIsGBABios,
   1.453 +					tempBIOS,
   1.454 +					size)) {
   1.455 +		if(size == 0x4000)
   1.456 +			hasBIOS = true;
   1.457 +		}
   1.458 +	}
   1.459 +
   1.460 +	u16 biosCheck = 0;
   1.461 +	if(hasBIOS) {
   1.462 +		for(int i = 0; i < 0x4000; i += 4)
   1.463 +			biosCheck += *((u32 *)&tempBIOS[i]);
   1.464 +		free(tempBIOS);
   1.465 +	}
   1.466 +
   1.467 +	return biosCheck;
   1.468 +}
   1.469 +
   1.470 +void (*dbgMain)() = debuggerMain;
   1.471 +void (*dbgSignal)(int, int) = debuggerSignal;
   1.472 +void (*dbgOutput)(char *, u32) = debuggerOutput;