Mercurial > vba-linux
diff src/sdl/SDL.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children | 48369c6aeaa0 |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/sdl/SDL.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,3623 @@ 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 <stdarg.h> 1.23 +#include <stdlib.h> 1.24 +#include <stdio.h> 1.25 +#include <string.h> 1.26 +#include <sys/types.h> 1.27 +#include <sys/stat.h> 1.28 + 1.29 +#include "AutoBuild.h" 1.30 + 1.31 +#include "Port.h" 1.32 +#include "SDL.h" 1.33 +#include "debugger.h" 1.34 +#include "gba/GBA.h" 1.35 +#include "gba/GBAGlobals.h" 1.36 +#include "gba/agbprint.h" 1.37 +#include "gba/Flash.h" 1.38 +#include "gba/RTC.h" 1.39 +#include "gba/GBASound.h" 1.40 +#include "gb/GB.h" 1.41 +#include "gb/gbGlobals.h" 1.42 +#include "common/Text.h" 1.43 +#include "common/unzip.h" 1.44 +#include "common/Util.h" 1.45 +#include "common/movie.h" 1.46 +#include "common/System.h" 1.47 +#include "common/inputGlobal.h" 1.48 +#include "../common/vbalua.h" 1.49 +#include "SoundSDL.h" 1.50 + 1.51 + 1.52 +#define GBC_CAPABLE ((gbRom[0x143] & 0x80) != 0) 1.53 +#define SGB_CAPABLE (gbRom[0x146] == 0x03) 1.54 + 1.55 +#ifndef WIN32 1.56 +# include <unistd.h> 1.57 +# define GETCWD getcwd 1.58 +#else // WIN32 1.59 +# include <direct.h> 1.60 +# define GETCWD _getcwd 1.61 +#endif // WIN32 1.62 + 1.63 +#ifndef __GNUC__ 1.64 +# define HAVE_DECL_GETOPT 0 1.65 +# define __STDC__ 1 1.66 +# include "getopt.h" 1.67 +#else // ! __GNUC__ 1.68 +# define HAVE_DECL_GETOPT 1 1.69 +# include "getopt.h" 1.70 +#endif // ! __GNUC__ 1.71 + 1.72 +#ifdef MMX 1.73 +extern "C" bool cpu_mmx; 1.74 +#endif 1.75 +extern bool8 soundEcho; 1.76 +extern bool8 soundLowPass; 1.77 +extern bool8 soundReverse; 1.78 +extern int Init_2xSaI(u32); 1.79 +extern void _2xSaI(u8*,u32,u8*,u8*,u32,int,int); 1.80 +extern void _2xSaI32(u8*,u32,u8*,u8*,u32,int,int); 1.81 +extern void Super2xSaI(u8*,u32,u8*,u8*,u32,int,int); 1.82 +extern void Super2xSaI32(u8*,u32,u8*,u8*,u32,int,int); 1.83 +extern void SuperEagle(u8*,u32,u8*,u8*,u32,int,int); 1.84 +extern void SuperEagle32(u8*,u32,u8*,u8*,u32,int,int); 1.85 +extern void Pixelate2x16(u8*,u32,u8*,u8*,u32,int,int); 1.86 +extern void Pixelate2x32(u8*,u32,u8*,u8*,u32,int,int); 1.87 +extern void MotionBlur(u8*,u32,u8*,u8*,u32,int,int); 1.88 +extern void MotionBlur32(u8*,u32,u8*,u8*,u32,int,int); 1.89 +extern void AdMame2x(u8*,u32,u8*,u8*,u32,int,int); 1.90 +extern void AdMame2x32(u8*,u32,u8*,u8*,u32,int,int); 1.91 +extern void Simple2x16(u8*,u32,u8*,u8*,u32,int,int); 1.92 +extern void Simple2x32(u8*,u32,u8*,u8*,u32,int,int); 1.93 +extern void Bilinear(u8*,u32,u8*,u8*,u32,int,int); 1.94 +extern void Bilinear32(u8*,u32,u8*,u8*,u32,int,int); 1.95 +extern void BilinearPlus(u8*,u32,u8*,u8*,u32,int,int); 1.96 +extern void BilinearPlus32(u8*,u32,u8*,u8*,u32,int,int); 1.97 +extern void Scanlines(u8*,u32,u8*,u8*,u32,int,int); 1.98 +extern void Scanlines32(u8*,u32,u8*,u8*,u32,int,int); 1.99 +extern void ScanlinesTV(u8*,u32,u8*,u8*,u32,int,int); 1.100 +extern void ScanlinesTV32(u8*,u32,u8*,u8*,u32,int,int); 1.101 +extern void hq2x(u8*,u32,u8*,u8*,u32,int,int); 1.102 +extern void hq2x32(u8*,u32,u8*,u8*,u32,int,int); 1.103 +extern void lq2x(u8*,u32,u8*,u8*,u32,int,int); 1.104 +extern void lq2x32(u8*,u32,u8*,u8*,u32,int,int); 1.105 + 1.106 +extern void SmartIB(u8*,u32,int,int); 1.107 +extern void SmartIB32(u8*,u32,int,int); 1.108 +extern void MotionBlurIB(u8*,u32,int,int); 1.109 +extern void MotionBlurIB32(u8*,u32,int,int); 1.110 + 1.111 +void Init_Overlay(SDL_Surface *surface, int overlaytype); 1.112 +void Quit_Overlay(void); 1.113 +void Draw_Overlay(SDL_Surface *surface, int size); 1.114 + 1.115 +extern void remoteInit(); 1.116 +extern void remoteCleanUp(); 1.117 +extern void remoteStubMain(); 1.118 +extern void remoteStubSignal(int,int); 1.119 +extern void remoteOutput(char *, u32); 1.120 +extern void remoteSetProtocol(int); 1.121 +extern void remoteSetPort(int); 1.122 +extern void debuggerOutput(char *, u32); 1.123 + 1.124 +extern void CPUUpdateRenderBuffers(bool); 1.125 + 1.126 +struct EmulatedSystem theEmulator = { 1.127 + NULL, 1.128 + NULL, 1.129 + NULL, 1.130 + NULL, 1.131 + NULL, 1.132 + NULL, 1.133 + NULL, 1.134 + NULL, 1.135 + NULL, 1.136 + NULL, 1.137 + NULL, 1.138 + NULL, 1.139 + false, 1.140 + 0 1.141 +}; 1.142 + 1.143 +SDL_Surface *surface = NULL; 1.144 +SDL_Overlay *overlay = NULL; 1.145 +SDL_Rect overlay_rect; 1.146 + 1.147 +int systemSpeed = 0; 1.148 +int systemRedShift = 0; 1.149 +int systemBlueShift = 0; 1.150 +int systemGreenShift = 0; 1.151 +int systemColorDepth = 0; 1.152 +int systemDebug = 0; 1.153 +int systemVerbose = 0; 1.154 +int systemFrameSkip = 0; 1.155 +int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; 1.156 + 1.157 +int srcPitch = 0; 1.158 +int srcWidth = 0; 1.159 +int srcHeight = 0; 1.160 +int destWidth = 0; 1.161 +int destHeight = 0; 1.162 + 1.163 +int sensorX = 2047; 1.164 +int sensorY = 2047; 1.165 +bool sensorOn = false; 1.166 + 1.167 +int filter = 0; 1.168 +u8 *delta = NULL; 1.169 + 1.170 +int sdlPrintUsage = 0; 1.171 +int disableMMX = 0; 1.172 + 1.173 +int systemCartridgeType = 3; 1.174 +int sizeOption = 0; 1.175 +int captureFormat = 0; 1.176 +int useMovie = 0; 1.177 + 1.178 +int pauseWhenInactive = 0; 1.179 +int active = 1; 1.180 +int emulating = 0; 1.181 +int RGB_LOW_BITS_MASK=0x821; 1.182 +u32 systemColorMap32[0x10000]; 1.183 +u16 systemColorMap16[0x10000]; 1.184 +u16 systemGbPalette[24]; 1.185 +void (*filterFunction)(u8*,u32,u8*,u8*,u32,int,int) = NULL; 1.186 +void (*ifbFunction)(u8*,u32,int,int) = NULL; 1.187 +int ifbType = 0; 1.188 +char filename[2048]; 1.189 +char ipsname[2048]; 1.190 +char biosFileName[2048]; 1.191 +char movieFileName[2048]; 1.192 +char captureDir[2048]; 1.193 +char saveDir[2048]; 1.194 +char batteryDir[2048]; 1.195 + 1.196 +static char *rewindMemory = NULL; 1.197 +static int rewindPos = 0; 1.198 +static int rewindTopPos = 0; 1.199 +static int rewindCounter = 0; 1.200 +static int rewindCount = 0; 1.201 +static bool rewindSaveNeeded = false; 1.202 +static int rewindTimer = 0; 1.203 + 1.204 +#define REWIND_SIZE 400000 1.205 + 1.206 +#define _stricmp strcasecmp 1.207 + 1.208 +/*bool sdlButtons[4][12] = { 1.209 + { false, false, false, false, false, false, 1.210 + false, false, false, false, false, false }, 1.211 + { false, false, false, false, false, false, 1.212 + false, false, false, false, false, false }, 1.213 + { false, false, false, false, false, false, 1.214 + false, false, false, false, false, false }, 1.215 + { false, false, false, false, false, false, 1.216 + false, false, false, false, false, false } 1.217 +};*/ 1.218 +/* 1.219 + I'm changing the way the SDL GUI handles the button 1.220 + input to match the one in win32, this is needed in 1.221 + order to be compatible with the format required by 1.222 + common/movie.cpp 1.223 + --Felipe 1.224 +*/ 1.225 + 1.226 +u16 currentButtons[4] = {0, 0, 0, 0}; 1.227 + 1.228 +bool sdlMotionButtons[4] = { false, false, false, false }; 1.229 +const int32 INITIAL_SENSOR_VALUE = 2047; 1.230 + 1.231 +int sdlNumDevices = 0; 1.232 +SDL_Joystick **sdlDevices = NULL; 1.233 + 1.234 +bool wasPaused = false; 1.235 +int autoFrameSkip = 0; 1.236 +int frameskipadjust = 0; 1.237 +int showRenderedFrames = 0; 1.238 +int renderedFrames = 0; 1.239 + 1.240 +int throttle = 0; 1.241 +u32 throttleLastTime = 0; 1.242 +u32 autoFrameSkipLastTime = 0; 1.243 + 1.244 +int showSpeed = 1; 1.245 +int showSpeedTransparent = 1; 1.246 +bool disableStatusMessages = false; 1.247 +bool paused = false; 1.248 +bool pauseNextFrame = false; 1.249 +bool debugger = false; 1.250 +bool debuggerStub = false; 1.251 +int fullscreen = 0; 1.252 +bool systemSoundOn = false; 1.253 +bool yuv = false; 1.254 +int yuvType = 0; 1.255 +bool removeIntros = false; 1.256 +int sdlFlashSize = 0; 1.257 +int sdlAutoIPS = 1; 1.258 +int sdlRtcEnable = 0; 1.259 +int sdlAgbPrint = 0; 1.260 + 1.261 +int sdlDefaultJoypad = 0; 1.262 + 1.263 +extern void debuggerSignal(int,int); 1.264 + 1.265 +void (*dbgMain)() = debuggerMain; 1.266 +void (*dbgSignal)(int,int) = debuggerSignal; 1.267 +void (*dbgOutput)(char *, u32) = debuggerOutput; 1.268 + 1.269 +int mouseCounter = 0; 1.270 +int autoFire = 0; 1.271 +bool autoFireToggle = false; 1.272 + 1.273 +bool screenMessage[8] = {false,false,false,false,false,false,false,false}; 1.274 +char screenMessageBuffer[8][21]; 1.275 +u32 screenMessageTime[8] = {0,0,0,0,0,0,0,0}; 1.276 +u32 screenMessageDuration[8] = {0,0,0,0,0,0,0,0}; 1.277 + 1.278 +SDL_cond *cond = NULL; 1.279 +SDL_mutex *mutex = NULL; 1.280 +u8* sdlBuffer; 1.281 +int sdlSoundLen = 0; 1.282 +SoundSDL* soundDriver = NULL; 1.283 + 1.284 +char *arg0; 1.285 + 1.286 +#ifndef C_CORE 1.287 +u8 sdlStretcher[16384]; 1.288 +int sdlStretcherPos; 1.289 +#else 1.290 +void (*sdlStretcher)(u8 *, u8*) = NULL; 1.291 +#endif 1.292 + 1.293 +u16 joypad[4][12] = { 1.294 + { SDLK_LEFT, SDLK_RIGHT, 1.295 + SDLK_UP, SDLK_DOWN, 1.296 + SDLK_z, SDLK_x, 1.297 + SDLK_RETURN,SDLK_BACKSPACE, 1.298 + SDLK_a, SDLK_s, 1.299 + SDLK_SPACE, SDLK_F12 1.300 + }, 1.301 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1.302 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1.303 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 1.304 +}; 1.305 + 1.306 +u16 defaultJoypad[12] = { 1.307 + SDLK_LEFT, SDLK_RIGHT, 1.308 + SDLK_UP, SDLK_DOWN, 1.309 + SDLK_z, SDLK_x, 1.310 + SDLK_RETURN,SDLK_BACKSPACE, 1.311 + SDLK_a, SDLK_s, 1.312 + SDLK_SPACE, SDLK_F12 1.313 +}; 1.314 + 1.315 +u16 motion[4] = { 1.316 + SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2 1.317 +}; 1.318 + 1.319 +u16 defaultMotion[4] = { 1.320 + SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2 1.321 +}; 1.322 + 1.323 +struct option sdlOptions[] = { 1.324 + { "agb-print", no_argument, &sdlAgbPrint, 1 }, 1.325 + { "auto-frameskip", no_argument, &autoFrameSkip, 1 }, 1.326 + { "bios", required_argument, 0, 'b' }, 1.327 + { "config", required_argument, 0, 'c' }, 1.328 + { "debug", no_argument, 0, 'd' }, 1.329 + { "filter", required_argument, 0, 'f' }, 1.330 + { "filter-normal", no_argument, &filter, 0 }, 1.331 + { "filter-tv-mode", no_argument, &filter, 1 }, 1.332 + { "filter-2xsai", no_argument, &filter, 2 }, 1.333 + { "filter-super-2xsai", no_argument, &filter, 3 }, 1.334 + { "filter-super-eagle", no_argument, &filter, 4 }, 1.335 + { "filter-pixelate", no_argument, &filter, 5 }, 1.336 + { "filter-motion-blur", no_argument, &filter, 6 }, 1.337 + { "filter-advmame", no_argument, &filter, 7 }, 1.338 + { "filter-simple2x", no_argument, &filter, 8 }, 1.339 + { "filter-bilinear", no_argument, &filter, 9 }, 1.340 + { "filter-bilinear+", no_argument, &filter, 10 }, 1.341 + { "filter-scanlines", no_argument, &filter, 11 }, 1.342 + { "filter-hq2x", no_argument, &filter, 12 }, 1.343 + { "filter-lq2x", no_argument, &filter, 13 }, 1.344 + { "flash-size", required_argument, 0, 'S' }, 1.345 + { "flash-64k", no_argument, &sdlFlashSize, 0 }, 1.346 + { "flash-128k", no_argument, &sdlFlashSize, 1 }, 1.347 + { "frameskip", required_argument, 0, 's' }, 1.348 + { "fullscreen", no_argument, &fullscreen, 1 }, 1.349 + { "gdb", required_argument, 0, 'G' }, 1.350 + { "help", no_argument, &sdlPrintUsage, 1 }, 1.351 + { "ifb-none", no_argument, &ifbType, 0 }, 1.352 + { "ifb-motion-blur", no_argument, &ifbType, 1 }, 1.353 + { "ifb-smart", no_argument, &ifbType, 2 }, 1.354 + { "ips", required_argument, 0, 'i' }, 1.355 + { "no-agb-print", no_argument, &sdlAgbPrint, 0 }, 1.356 + { "no-auto-frameskip", no_argument, &autoFrameSkip, 0 }, 1.357 + { "no-debug", no_argument, 0, 'N' }, 1.358 + { "no-ips", no_argument, &sdlAutoIPS, 0 }, 1.359 + { "no-mmx", no_argument, &disableMMX, 1 }, 1.360 + { "no-pause-when-inactive", no_argument, &pauseWhenInactive, 0 }, 1.361 + { "no-rtc", no_argument, &sdlRtcEnable, 0 }, 1.362 + { "no-show-speed", no_argument, &showSpeed, 0 }, 1.363 + { "no-throttle", no_argument, &throttle, 0 }, 1.364 + { "pause-when-inactive", no_argument, &pauseWhenInactive, 1 }, 1.365 + { "profile", optional_argument, 0, 'P' }, 1.366 + { "rtc", no_argument, &sdlRtcEnable, 1 }, 1.367 + { "save-type", required_argument, 0, 't' }, 1.368 + { "save-auto", no_argument, &cpuSaveType, 0 }, 1.369 + { "save-eeprom", no_argument, &cpuSaveType, 1 }, 1.370 + { "save-sram", no_argument, &cpuSaveType, 2 }, 1.371 + { "save-flash", no_argument, &cpuSaveType, 3 }, 1.372 + { "save-sensor", no_argument, &cpuSaveType, 4 }, 1.373 + { "save-none", no_argument, &cpuSaveType, 5 }, 1.374 + { "show-speed-normal", no_argument, &showSpeed, 1 }, 1.375 + { "show-speed-detailed", no_argument, &showSpeed, 2 }, 1.376 + { "throttle", required_argument, 0, 'T' }, 1.377 + { "verbose", required_argument, 0, 'v' }, 1.378 + { "video-1x", no_argument, &sizeOption, 0 }, 1.379 + { "video-2x", no_argument, &sizeOption, 1 }, 1.380 + { "video-3x", no_argument, &sizeOption, 2 }, 1.381 + { "video-4x", no_argument, &sizeOption, 3 }, 1.382 + { "yuv", required_argument, 0, 'Y' }, 1.383 + { "recordmovie", required_argument, 0, 'r' }, 1.384 + { "playmovie", required_argument, 0, 'p' }, 1.385 + { "watchmovie", required_argument, 0, 'w' }, 1.386 + { NULL, no_argument, NULL, 0 } 1.387 +}; 1.388 + 1.389 +#ifndef C_CORE 1.390 +#define SDL_LONG(val) \ 1.391 + *((u32 *)&sdlStretcher[sdlStretcherPos]) = val;\ 1.392 + sdlStretcherPos+=4; 1.393 + 1.394 +#define SDL_AND_EAX(val) \ 1.395 + sdlStretcher[sdlStretcherPos++] = 0x25;\ 1.396 + SDL_LONG(val); 1.397 + 1.398 +#define SDL_AND_EBX(val) \ 1.399 + sdlStretcher[sdlStretcherPos++] = 0x81;\ 1.400 + sdlStretcher[sdlStretcherPos++] = 0xe3;\ 1.401 + SDL_LONG(val); 1.402 + 1.403 +#define SDL_OR_EAX_EBX \ 1.404 + sdlStretcher[sdlStretcherPos++] = 0x09;\ 1.405 + sdlStretcher[sdlStretcherPos++] = 0xd8; 1.406 + 1.407 +#define SDL_LOADL_EBX \ 1.408 + sdlStretcher[sdlStretcherPos++] = 0x8b;\ 1.409 + sdlStretcher[sdlStretcherPos++] = 0x1f; 1.410 + 1.411 +#define SDL_LOADW \ 1.412 + sdlStretcher[sdlStretcherPos++] = 0x66;\ 1.413 + sdlStretcher[sdlStretcherPos++] = 0x8b;\ 1.414 + sdlStretcher[sdlStretcherPos++] = 0x06;\ 1.415 + sdlStretcher[sdlStretcherPos++] = 0x83;\ 1.416 + sdlStretcher[sdlStretcherPos++] = 0xc6;\ 1.417 + sdlStretcher[sdlStretcherPos++] = 0x02; 1.418 + 1.419 +#define SDL_LOADL \ 1.420 + sdlStretcher[sdlStretcherPos++] = 0x8b;\ 1.421 + sdlStretcher[sdlStretcherPos++] = 0x06;\ 1.422 + sdlStretcher[sdlStretcherPos++] = 0x83;\ 1.423 + sdlStretcher[sdlStretcherPos++] = 0xc6;\ 1.424 + sdlStretcher[sdlStretcherPos++] = 0x04; 1.425 + 1.426 +#define SDL_LOADL2 \ 1.427 + sdlStretcher[sdlStretcherPos++] = 0x8b;\ 1.428 + sdlStretcher[sdlStretcherPos++] = 0x06;\ 1.429 + sdlStretcher[sdlStretcherPos++] = 0x83;\ 1.430 + sdlStretcher[sdlStretcherPos++] = 0xc6;\ 1.431 + sdlStretcher[sdlStretcherPos++] = 0x03; 1.432 + 1.433 +#define SDL_STOREW \ 1.434 + sdlStretcher[sdlStretcherPos++] = 0x66;\ 1.435 + sdlStretcher[sdlStretcherPos++] = 0x89;\ 1.436 + sdlStretcher[sdlStretcherPos++] = 0x07;\ 1.437 + sdlStretcher[sdlStretcherPos++] = 0x83;\ 1.438 + sdlStretcher[sdlStretcherPos++] = 0xc7;\ 1.439 + sdlStretcher[sdlStretcherPos++] = 0x02; 1.440 + 1.441 +#define SDL_STOREL \ 1.442 + sdlStretcher[sdlStretcherPos++] = 0x89;\ 1.443 + sdlStretcher[sdlStretcherPos++] = 0x07;\ 1.444 + sdlStretcher[sdlStretcherPos++] = 0x83;\ 1.445 + sdlStretcher[sdlStretcherPos++] = 0xc7;\ 1.446 + sdlStretcher[sdlStretcherPos++] = 0x04; 1.447 + 1.448 +#define SDL_STOREL2 \ 1.449 + sdlStretcher[sdlStretcherPos++] = 0x89;\ 1.450 + sdlStretcher[sdlStretcherPos++] = 0x07;\ 1.451 + sdlStretcher[sdlStretcherPos++] = 0x83;\ 1.452 + sdlStretcher[sdlStretcherPos++] = 0xc7;\ 1.453 + sdlStretcher[sdlStretcherPos++] = 0x03; 1.454 + 1.455 +#define SDL_RET \ 1.456 + sdlStretcher[sdlStretcherPos++] = 0xc3; 1.457 + 1.458 +#define SDL_PUSH_EAX \ 1.459 + sdlStretcher[sdlStretcherPos++] = 0x50; 1.460 + 1.461 +#define SDL_PUSH_ECX \ 1.462 + sdlStretcher[sdlStretcherPos++] = 0x51; 1.463 + 1.464 +#define SDL_PUSH_EBX \ 1.465 + sdlStretcher[sdlStretcherPos++] = 0x53; 1.466 + 1.467 +#define SDL_PUSH_ESI \ 1.468 + sdlStretcher[sdlStretcherPos++] = 0x56; 1.469 + 1.470 +#define SDL_PUSH_EDI \ 1.471 + sdlStretcher[sdlStretcherPos++] = 0x57; 1.472 + 1.473 +#define SDL_POP_EAX \ 1.474 + sdlStretcher[sdlStretcherPos++] = 0x58; 1.475 + 1.476 +#define SDL_POP_ECX \ 1.477 + sdlStretcher[sdlStretcherPos++] = 0x59; 1.478 + 1.479 +#define SDL_POP_EBX \ 1.480 + sdlStretcher[sdlStretcherPos++] = 0x5b; 1.481 + 1.482 +#define SDL_POP_ESI \ 1.483 + sdlStretcher[sdlStretcherPos++] = 0x5e; 1.484 + 1.485 +#define SDL_POP_EDI \ 1.486 + sdlStretcher[sdlStretcherPos++] = 0x5f; 1.487 + 1.488 +#define SDL_MOV_ECX(val) \ 1.489 + sdlStretcher[sdlStretcherPos++] = 0xb9;\ 1.490 + SDL_LONG(val); 1.491 + 1.492 +#define SDL_REP_MOVSB \ 1.493 + sdlStretcher[sdlStretcherPos++] = 0xf3;\ 1.494 + sdlStretcher[sdlStretcherPos++] = 0xa4; 1.495 + 1.496 +#define SDL_REP_MOVSW \ 1.497 + sdlStretcher[sdlStretcherPos++] = 0xf3;\ 1.498 + sdlStretcher[sdlStretcherPos++] = 0x66;\ 1.499 + sdlStretcher[sdlStretcherPos++] = 0xa5; 1.500 + 1.501 +#define SDL_REP_MOVSL \ 1.502 + sdlStretcher[sdlStretcherPos++] = 0xf3;\ 1.503 + sdlStretcher[sdlStretcherPos++] = 0xa5; 1.504 + 1.505 +void sdlMakeStretcher(int width) 1.506 +{ 1.507 + sdlStretcherPos = 0; 1.508 + switch(systemColorDepth) { 1.509 + case 16: 1.510 + if(sizeOption) { 1.511 + SDL_PUSH_EAX; 1.512 + SDL_PUSH_ESI; 1.513 + SDL_PUSH_EDI; 1.514 + for(int i = 0; i < width; i++) { 1.515 + SDL_LOADW; 1.516 + SDL_STOREW; 1.517 + SDL_STOREW; 1.518 + if(sizeOption > 1) { 1.519 + SDL_STOREW; 1.520 + } 1.521 + if(sizeOption > 2) { 1.522 + SDL_STOREW; 1.523 + } 1.524 + } 1.525 + SDL_POP_EDI; 1.526 + SDL_POP_ESI; 1.527 + SDL_POP_EAX; 1.528 + SDL_RET; 1.529 + } else { 1.530 + SDL_PUSH_ESI; 1.531 + SDL_PUSH_EDI; 1.532 + SDL_PUSH_ECX; 1.533 + SDL_MOV_ECX(width); 1.534 + SDL_REP_MOVSW; 1.535 + SDL_POP_ECX; 1.536 + SDL_POP_EDI; 1.537 + SDL_POP_ESI; 1.538 + SDL_RET; 1.539 + } 1.540 + break; 1.541 + case 24: 1.542 + if(sizeOption) { 1.543 + SDL_PUSH_EAX; 1.544 + SDL_PUSH_ESI; 1.545 + SDL_PUSH_EDI; 1.546 + int w = width - 1; 1.547 + for(int i = 0; i < w; i++) { 1.548 + SDL_LOADL2; 1.549 + SDL_STOREL2; 1.550 + SDL_STOREL2; 1.551 + if(sizeOption > 1) { 1.552 + SDL_STOREL2; 1.553 + } 1.554 + if(sizeOption > 2) { 1.555 + SDL_STOREL2; 1.556 + } 1.557 + } 1.558 + // need to write the last one 1.559 + SDL_LOADL2; 1.560 + SDL_STOREL2; 1.561 + if(sizeOption > 1) { 1.562 + SDL_STOREL2; 1.563 + } 1.564 + if(sizeOption > 2) { 1.565 + SDL_STOREL2; 1.566 + } 1.567 + SDL_AND_EAX(0x00ffffff); 1.568 + SDL_PUSH_EBX; 1.569 + SDL_LOADL_EBX; 1.570 + SDL_AND_EBX(0xff000000); 1.571 + SDL_OR_EAX_EBX; 1.572 + SDL_POP_EBX; 1.573 + SDL_STOREL2; 1.574 + SDL_POP_EDI; 1.575 + SDL_POP_ESI; 1.576 + SDL_POP_EAX; 1.577 + SDL_RET; 1.578 + } else { 1.579 + SDL_PUSH_ESI; 1.580 + SDL_PUSH_EDI; 1.581 + SDL_PUSH_ECX; 1.582 + SDL_MOV_ECX(3*width); 1.583 + SDL_REP_MOVSB; 1.584 + SDL_POP_ECX; 1.585 + SDL_POP_EDI; 1.586 + SDL_POP_ESI; 1.587 + SDL_RET; 1.588 + } 1.589 + break; 1.590 + case 32: 1.591 + if(sizeOption) { 1.592 + SDL_PUSH_EAX; 1.593 + SDL_PUSH_ESI; 1.594 + SDL_PUSH_EDI; 1.595 + for(int i = 0; i < width; i++) { 1.596 + SDL_LOADL; 1.597 + SDL_STOREL; 1.598 + SDL_STOREL; 1.599 + if(sizeOption > 1) { 1.600 + SDL_STOREL; 1.601 + } 1.602 + if(sizeOption > 2) { 1.603 + SDL_STOREL; 1.604 + } 1.605 + } 1.606 + SDL_POP_EDI; 1.607 + SDL_POP_ESI; 1.608 + SDL_POP_EAX; 1.609 + SDL_RET; 1.610 + } else { 1.611 + SDL_PUSH_ESI; 1.612 + SDL_PUSH_EDI; 1.613 + SDL_PUSH_ECX; 1.614 + SDL_MOV_ECX(width); 1.615 + SDL_REP_MOVSL; 1.616 + SDL_POP_ECX; 1.617 + SDL_POP_EDI; 1.618 + SDL_POP_ESI; 1.619 + SDL_RET; 1.620 + } 1.621 + break; 1.622 + } 1.623 +} 1.624 + 1.625 +#ifdef _MSC_VER 1.626 +#define SDL_CALL_STRETCHER \ 1.627 + {\ 1.628 + __asm mov eax, stretcher\ 1.629 + __asm mov edi, dest\ 1.630 + __asm mov esi, src\ 1.631 + __asm call eax\ 1.632 + } 1.633 +#else 1.634 +#define SDL_CALL_STRETCHER \ 1.635 + asm volatile("call *%%eax"::"a" (stretcher),"S" (src),"D" (dest)) 1.636 +#endif 1.637 +#else 1.638 +#define SDL_CALL_STRETCHER \ 1.639 + sdlStretcher(src, dest) 1.640 + 1.641 +void sdlStretch16x1(u8 *src, u8 *dest) 1.642 +{ 1.643 + u16 *s = (u16 *)src; 1.644 + u16 *d = (u16 *)dest; 1.645 + for(int i = 0; i < srcWidth; i++) 1.646 + *d++ = *s++; 1.647 +} 1.648 + 1.649 +void sdlStretch16x2(u8 *src, u8 *dest) 1.650 +{ 1.651 + u16 *s = (u16 *)src; 1.652 + u16 *d = (u16 *)dest; 1.653 + for(int i = 0; i < srcWidth; i++) { 1.654 + *d++ = *s; 1.655 + *d++ = *s++; 1.656 + } 1.657 +} 1.658 + 1.659 +void sdlStretch16x3(u8 *src, u8 *dest) 1.660 +{ 1.661 + u16 *s = (u16 *)src; 1.662 + u16 *d = (u16 *)dest; 1.663 + for(int i = 0; i < srcWidth; i++) { 1.664 + *d++ = *s; 1.665 + *d++ = *s; 1.666 + *d++ = *s++; 1.667 + } 1.668 +} 1.669 + 1.670 +void sdlStretch16x4(u8 *src, u8 *dest) 1.671 +{ 1.672 + u16 *s = (u16 *)src; 1.673 + u16 *d = (u16 *)dest; 1.674 + for(int i = 0; i < srcWidth; i++) { 1.675 + *d++ = *s; 1.676 + *d++ = *s; 1.677 + *d++ = *s; 1.678 + *d++ = *s++; 1.679 + } 1.680 +} 1.681 + 1.682 +void (*sdlStretcher16[4])(u8 *, u8 *) = { 1.683 + sdlStretch16x1, 1.684 + sdlStretch16x2, 1.685 + sdlStretch16x3, 1.686 + sdlStretch16x4 1.687 +}; 1.688 + 1.689 +void sdlStretch32x1(u8 *src, u8 *dest) 1.690 +{ 1.691 + u32 *s = (u32 *)src; 1.692 + u32 *d = (u32 *)dest; 1.693 + for(int i = 0; i < srcWidth; i++) 1.694 + *d++ = *s++; 1.695 +} 1.696 + 1.697 +void sdlStretch32x2(u8 *src, u8 *dest) 1.698 +{ 1.699 + u32 *s = (u32 *)src; 1.700 + u32 *d = (u32 *)dest; 1.701 + for(int i = 0; i < srcWidth; i++) { 1.702 + *d++ = *s; 1.703 + *d++ = *s++; 1.704 + } 1.705 +} 1.706 + 1.707 +void sdlStretch32x3(u8 *src, u8 *dest) 1.708 +{ 1.709 + u32 *s = (u32 *)src; 1.710 + u32 *d = (u32 *)dest; 1.711 + for(int i = 0; i < srcWidth; i++) { 1.712 + *d++ = *s; 1.713 + *d++ = *s; 1.714 + *d++ = *s++; 1.715 + } 1.716 +} 1.717 + 1.718 +void sdlStretch32x4(u8 *src, u8 *dest) 1.719 +{ 1.720 + u32 *s = (u32 *)src; 1.721 + u32 *d = (u32 *)dest; 1.722 + for(int i = 0; i < srcWidth; i++) { 1.723 + *d++ = *s; 1.724 + *d++ = *s; 1.725 + *d++ = *s; 1.726 + *d++ = *s++; 1.727 + } 1.728 +} 1.729 + 1.730 +void (*sdlStretcher32[4])(u8 *, u8 *) = { 1.731 + sdlStretch32x1, 1.732 + sdlStretch32x2, 1.733 + sdlStretch32x3, 1.734 + sdlStretch32x4 1.735 +}; 1.736 + 1.737 +void sdlStretch24x1(u8 *src, u8 *dest) 1.738 +{ 1.739 + u8 *s = src; 1.740 + u8 *d = dest; 1.741 + for(int i = 0; i < srcWidth; i++) { 1.742 + *d++ = *s++; 1.743 + *d++ = *s++; 1.744 + *d++ = *s++; 1.745 + } 1.746 +} 1.747 + 1.748 +void sdlStretch24x2(u8 *src, u8 *dest) 1.749 +{ 1.750 + u8 *s = (u8 *)src; 1.751 + u8 *d = (u8 *)dest; 1.752 + for(int i = 0; i < srcWidth; i++) { 1.753 + *d++ = *s; 1.754 + *d++ = *(s+1); 1.755 + *d++ = *(s+2); 1.756 + s += 3; 1.757 + *d++ = *s; 1.758 + *d++ = *(s+1); 1.759 + *d++ = *(s+2); 1.760 + s += 3; 1.761 + } 1.762 +} 1.763 + 1.764 +void sdlStretch24x3(u8 *src, u8 *dest) 1.765 +{ 1.766 + u8 *s = (u8 *)src; 1.767 + u8 *d = (u8 *)dest; 1.768 + for(int i = 0; i < srcWidth; i++) { 1.769 + *d++ = *s; 1.770 + *d++ = *(s+1); 1.771 + *d++ = *(s+2); 1.772 + s += 3; 1.773 + *d++ = *s; 1.774 + *d++ = *(s+1); 1.775 + *d++ = *(s+2); 1.776 + s += 3; 1.777 + *d++ = *s; 1.778 + *d++ = *(s+1); 1.779 + *d++ = *(s+2); 1.780 + s += 3; 1.781 + } 1.782 +} 1.783 + 1.784 +void sdlStretch24x4(u8 *src, u8 *dest) 1.785 +{ 1.786 + u8 *s = (u8 *)src; 1.787 + u8 *d = (u8 *)dest; 1.788 + for(int i = 0; i < srcWidth; i++) { 1.789 + *d++ = *s; 1.790 + *d++ = *(s+1); 1.791 + *d++ = *(s+2); 1.792 + s += 3; 1.793 + *d++ = *s; 1.794 + *d++ = *(s+1); 1.795 + *d++ = *(s+2); 1.796 + s += 3; 1.797 + *d++ = *s; 1.798 + *d++ = *(s+1); 1.799 + *d++ = *(s+2); 1.800 + s += 3; 1.801 + *d++ = *s; 1.802 + *d++ = *(s+1); 1.803 + *d++ = *(s+2); 1.804 + s += 3; 1.805 + } 1.806 +} 1.807 + 1.808 +void (*sdlStretcher24[4])(u8 *, u8 *) = { 1.809 + sdlStretch24x1, 1.810 + sdlStretch24x2, 1.811 + sdlStretch24x3, 1.812 + sdlStretch24x4 1.813 +}; 1.814 + 1.815 +#endif 1.816 + 1.817 +u32 sdlFromHex(char *s) 1.818 +{ 1.819 + u32 value; 1.820 + sscanf(s, "%x", &value); 1.821 + return value; 1.822 +} 1.823 + 1.824 +#ifdef __MSC__ 1.825 +#define stat _stat 1.826 +#define S_IFDIR _S_IFDIR 1.827 +#endif 1.828 + 1.829 +void sdlCheckDirectory(char *dir) 1.830 +{ 1.831 + struct stat buf; 1.832 + 1.833 + int len = strlen(dir); 1.834 + 1.835 + char *p = dir + len - 1; 1.836 + 1.837 + if(*p == '/' || 1.838 + *p == '\\') 1.839 + *p = 0; 1.840 + 1.841 + if(stat(dir, &buf) == 0) { 1.842 + if(!(buf.st_mode & S_IFDIR)) { 1.843 + fprintf(stderr, "Error: %s is not a directory\n", dir); 1.844 + dir[0] = 0; 1.845 + } 1.846 + } else { 1.847 + fprintf(stderr, "Error: %s does not exist\n", dir); 1.848 + dir[0] = 0; 1.849 + } 1.850 +} 1.851 + 1.852 +char *sdlGetFilename(char *name) 1.853 +{ 1.854 + static char filebuffer[2048]; 1.855 + 1.856 + int len = strlen(name); 1.857 + 1.858 + char *p = name + len - 1; 1.859 + 1.860 + while(true) { 1.861 + if(*p == '/' || 1.862 + *p == '\\') { 1.863 + p++; 1.864 + break; 1.865 + } 1.866 + len--; 1.867 + p--; 1.868 + if(len == 0) 1.869 + break; 1.870 + } 1.871 + 1.872 + if(len == 0) 1.873 + strcpy(filebuffer, name); 1.874 + else 1.875 + strcpy(filebuffer, p); 1.876 + return filebuffer; 1.877 +} 1.878 + 1.879 +FILE *sdlFindFile(const char *name) 1.880 +{ 1.881 + char buffer[4096]; 1.882 + char path[2048]; 1.883 + 1.884 +#ifdef WIN32 1.885 +#define PATH_SEP ";" 1.886 +#define FILE_SEP '\\' 1.887 +#define EXE_NAME "VisualBoyAdvance-SDL.exe" 1.888 +#else // ! WIN32 1.889 +#define PATH_SEP ":" 1.890 +#define FILE_SEP '/' 1.891 +#define EXE_NAME "VisualBoyAdvance" 1.892 +#endif // ! WIN32 1.893 + 1.894 + fprintf(stderr, "Searching for file %s\n", name); 1.895 + 1.896 + if(GETCWD(buffer, 2048)) { 1.897 + fprintf(stderr, "Searching current directory: %s\n", buffer); 1.898 + } 1.899 + 1.900 + FILE *f = fopen(name, "r"); 1.901 + if(f != NULL) { 1.902 + return f; 1.903 + } 1.904 + 1.905 + char *home = getenv("HOME"); 1.906 + 1.907 + if(home != NULL) { 1.908 + fprintf(stderr, "Searching home directory: %s\n", home); 1.909 + sprintf(path, "%s%c%s", home, FILE_SEP, name); 1.910 + f = fopen(path, "r"); 1.911 + if(f != NULL) 1.912 + return f; 1.913 + } 1.914 + 1.915 +#ifdef WIN32 1.916 + home = getenv("USERPROFILE"); 1.917 + if(home != NULL) { 1.918 + fprintf(stderr, "Searching user profile directory: %s\n", home); 1.919 + sprintf(path, "%s%c%s", home, FILE_SEP, name); 1.920 + f = fopen(path, "r"); 1.921 + if(f != NULL) 1.922 + return f; 1.923 + } 1.924 +#else // ! WIN32 1.925 + fprintf(stderr, "Searching system config directory: %s\n", SYSCONFDIR); 1.926 + sprintf(path, "%s%c%s", SYSCONFDIR, FILE_SEP, name); 1.927 + f = fopen(path, "r"); 1.928 + if(f != NULL) 1.929 + return f; 1.930 +#endif // ! WIN32 1.931 + 1.932 + if(!strchr(arg0, '/') && 1.933 + !strchr(arg0, '\\')) { 1.934 + char *path = getenv("PATH"); 1.935 + 1.936 + if(path != NULL) { 1.937 + fprintf(stderr, "Searching PATH\n"); 1.938 + strncpy(buffer, path, 4096); 1.939 + buffer[4095] = 0; 1.940 + char *tok = strtok(buffer, PATH_SEP); 1.941 + 1.942 + while(tok) { 1.943 + sprintf(path, "%s%c%s", tok, FILE_SEP, EXE_NAME); 1.944 + f = fopen(path, "r"); 1.945 + if(f != NULL) { 1.946 + char path2[2048]; 1.947 + fclose(f); 1.948 + sprintf(path2, "%s%c%s", tok, FILE_SEP, name); 1.949 + f = fopen(path2, "r"); 1.950 + if(f != NULL) { 1.951 + fprintf(stderr, "Found at %s\n", path2); 1.952 + return f; 1.953 + } 1.954 + } 1.955 + tok = strtok(NULL, PATH_SEP); 1.956 + } 1.957 + } 1.958 + } else { 1.959 + // executable is relative to some directory 1.960 + fprintf(stderr, "Searching executable directory\n"); 1.961 + strcpy(buffer, arg0); 1.962 + char *p = strrchr(buffer, FILE_SEP); 1.963 + if(p) { 1.964 + *p = 0; 1.965 + sprintf(path, "%s%c%s", buffer, FILE_SEP, name); 1.966 + f = fopen(path, "r"); 1.967 + if(f != NULL) 1.968 + return f; 1.969 + } 1.970 + } 1.971 + return NULL; 1.972 +} 1.973 + 1.974 +void sdlReadPreferences(FILE *f) 1.975 +{ 1.976 + char buffer[2048]; 1.977 + 1.978 + while(1) { 1.979 + char *s = fgets(buffer, 2048, f); 1.980 + 1.981 + if(s == NULL) 1.982 + break; 1.983 + 1.984 + char *p = strchr(s, '#'); 1.985 + 1.986 + if(p) 1.987 + *p = 0; 1.988 + 1.989 + char *token = strtok(s, " \t\n\r="); 1.990 + 1.991 + if(!token) 1.992 + continue; 1.993 + 1.994 + if(strlen(token) == 0) 1.995 + continue; 1.996 + 1.997 + char *key = token; 1.998 + char *value = strtok(NULL, "\t\n\r"); 1.999 + 1.1000 + if(value == NULL) { 1.1001 + fprintf(stderr, "Empty value for key %s\n", key); 1.1002 + continue; 1.1003 + } 1.1004 + 1.1005 + if(!strcmp(key,"Joy0_Left")) { 1.1006 + joypad[0][KEY_LEFT] = sdlFromHex(value); 1.1007 + } else if(!strcmp(key, "Joy0_Right")) { 1.1008 + joypad[0][KEY_RIGHT] = sdlFromHex(value); 1.1009 + } else if(!strcmp(key, "Joy0_Up")) { 1.1010 + joypad[0][KEY_UP] = sdlFromHex(value); 1.1011 + } else if(!strcmp(key, "Joy0_Down")) { 1.1012 + joypad[0][KEY_DOWN] = sdlFromHex(value); 1.1013 + } else if(!strcmp(key, "Joy0_A")) { 1.1014 + joypad[0][KEY_BUTTON_A] = sdlFromHex(value); 1.1015 + } else if(!strcmp(key, "Joy0_B")) { 1.1016 + joypad[0][KEY_BUTTON_B] = sdlFromHex(value); 1.1017 + } else if(!strcmp(key, "Joy0_L")) { 1.1018 + joypad[0][KEY_BUTTON_L] = sdlFromHex(value); 1.1019 + } else if(!strcmp(key, "Joy0_R")) { 1.1020 + joypad[0][KEY_BUTTON_R] = sdlFromHex(value); 1.1021 + } else if(!strcmp(key, "Joy0_Start")) { 1.1022 + joypad[0][KEY_BUTTON_START] = sdlFromHex(value); 1.1023 + } else if(!strcmp(key, "Joy0_Select")) { 1.1024 + joypad[0][KEY_BUTTON_SELECT] = sdlFromHex(value); 1.1025 + } else if(!strcmp(key, "Joy0_Speed")) { 1.1026 + joypad[0][KEY_BUTTON_SPEED] = sdlFromHex(value); 1.1027 + } else if(!strcmp(key, "Joy0_Capture")) { 1.1028 + joypad[0][KEY_BUTTON_CAPTURE] = sdlFromHex(value); 1.1029 + } else if(!strcmp(key,"Joy1_Left")) { 1.1030 + joypad[1][KEY_LEFT] = sdlFromHex(value); 1.1031 + } else if(!strcmp(key, "Joy1_Right")) { 1.1032 + joypad[1][KEY_RIGHT] = sdlFromHex(value); 1.1033 + } else if(!strcmp(key, "Joy1_Up")) { 1.1034 + joypad[1][KEY_UP] = sdlFromHex(value); 1.1035 + } else if(!strcmp(key, "Joy1_Down")) { 1.1036 + joypad[1][KEY_DOWN] = sdlFromHex(value); 1.1037 + } else if(!strcmp(key, "Joy1_A")) { 1.1038 + joypad[1][KEY_BUTTON_A] = sdlFromHex(value); 1.1039 + } else if(!strcmp(key, "Joy1_B")) { 1.1040 + joypad[1][KEY_BUTTON_B] = sdlFromHex(value); 1.1041 + } else if(!strcmp(key, "Joy1_L")) { 1.1042 + joypad[1][KEY_BUTTON_L] = sdlFromHex(value); 1.1043 + } else if(!strcmp(key, "Joy1_R")) { 1.1044 + joypad[1][KEY_BUTTON_R] = sdlFromHex(value); 1.1045 + } else if(!strcmp(key, "Joy1_Start")) { 1.1046 + joypad[1][KEY_BUTTON_START] = sdlFromHex(value); 1.1047 + } else if(!strcmp(key, "Joy1_Select")) { 1.1048 + joypad[1][KEY_BUTTON_SELECT] = sdlFromHex(value); 1.1049 + } else if(!strcmp(key, "Joy1_Speed")) { 1.1050 + joypad[1][KEY_BUTTON_SPEED] = sdlFromHex(value); 1.1051 + } else if(!strcmp(key, "Joy1_Capture")) { 1.1052 + joypad[1][KEY_BUTTON_CAPTURE] = sdlFromHex(value); 1.1053 + } else if(!strcmp(key,"Joy2_Left")) { 1.1054 + joypad[2][KEY_LEFT] = sdlFromHex(value); 1.1055 + } else if(!strcmp(key, "Joy2_Right")) { 1.1056 + joypad[2][KEY_RIGHT] = sdlFromHex(value); 1.1057 + } else if(!strcmp(key, "Joy2_Up")) { 1.1058 + joypad[2][KEY_UP] = sdlFromHex(value); 1.1059 + } else if(!strcmp(key, "Joy2_Down")) { 1.1060 + joypad[2][KEY_DOWN] = sdlFromHex(value); 1.1061 + } else if(!strcmp(key, "Joy2_A")) { 1.1062 + joypad[2][KEY_BUTTON_A] = sdlFromHex(value); 1.1063 + } else if(!strcmp(key, "Joy2_B")) { 1.1064 + joypad[2][KEY_BUTTON_B] = sdlFromHex(value); 1.1065 + } else if(!strcmp(key, "Joy2_L")) { 1.1066 + joypad[2][KEY_BUTTON_L] = sdlFromHex(value); 1.1067 + } else if(!strcmp(key, "Joy2_R")) { 1.1068 + joypad[2][KEY_BUTTON_R] = sdlFromHex(value); 1.1069 + } else if(!strcmp(key, "Joy2_Start")) { 1.1070 + joypad[2][KEY_BUTTON_START] = sdlFromHex(value); 1.1071 + } else if(!strcmp(key, "Joy2_Select")) { 1.1072 + joypad[2][KEY_BUTTON_SELECT] = sdlFromHex(value); 1.1073 + } else if(!strcmp(key, "Joy2_Speed")) { 1.1074 + joypad[2][KEY_BUTTON_SPEED] = sdlFromHex(value); 1.1075 + } else if(!strcmp(key, "Joy2_Capture")) { 1.1076 + joypad[2][KEY_BUTTON_CAPTURE] = sdlFromHex(value); 1.1077 + } else if(!strcmp(key,"Joy4_Left")) { 1.1078 + joypad[4][KEY_LEFT] = sdlFromHex(value); 1.1079 + } else if(!strcmp(key, "Joy4_Right")) { 1.1080 + joypad[4][KEY_RIGHT] = sdlFromHex(value); 1.1081 + } else if(!strcmp(key, "Joy4_Up")) { 1.1082 + joypad[4][KEY_UP] = sdlFromHex(value); 1.1083 + } else if(!strcmp(key, "Joy4_Down")) { 1.1084 + joypad[4][KEY_DOWN] = sdlFromHex(value); 1.1085 + } else if(!strcmp(key, "Joy4_A")) { 1.1086 + joypad[4][KEY_BUTTON_A] = sdlFromHex(value); 1.1087 + } else if(!strcmp(key, "Joy4_B")) { 1.1088 + joypad[4][KEY_BUTTON_B] = sdlFromHex(value); 1.1089 + } else if(!strcmp(key, "Joy4_L")) { 1.1090 + joypad[4][KEY_BUTTON_L] = sdlFromHex(value); 1.1091 + } else if(!strcmp(key, "Joy4_R")) { 1.1092 + joypad[4][KEY_BUTTON_R] = sdlFromHex(value); 1.1093 + } else if(!strcmp(key, "Joy4_Start")) { 1.1094 + joypad[4][KEY_BUTTON_START] = sdlFromHex(value); 1.1095 + } else if(!strcmp(key, "Joy4_Select")) { 1.1096 + joypad[4][KEY_BUTTON_SELECT] = sdlFromHex(value); 1.1097 + } else if(!strcmp(key, "Joy4_Speed")) { 1.1098 + joypad[4][KEY_BUTTON_SPEED] = sdlFromHex(value); 1.1099 + } else if(!strcmp(key, "Joy4_Capture")) { 1.1100 + joypad[4][KEY_BUTTON_CAPTURE] = sdlFromHex(value); 1.1101 + } else if(!strcmp(key, "Motion_Left")) { 1.1102 + motion[KEY_LEFT] = sdlFromHex(value); 1.1103 + } else if(!strcmp(key, "Motion_Right")) { 1.1104 + motion[KEY_RIGHT] = sdlFromHex(value); 1.1105 + } else if(!strcmp(key, "Motion_Up")) { 1.1106 + motion[KEY_UP] = sdlFromHex(value); 1.1107 + } else if(!strcmp(key, "Motion_Down")) { 1.1108 + motion[KEY_DOWN] = sdlFromHex(value); 1.1109 + } else if(!strcmp(key, "frameSkip")) { 1.1110 + frameSkip = sdlFromHex(value); 1.1111 + if(frameSkip < 0 || frameSkip > 9) 1.1112 + frameSkip = 2; 1.1113 + } else if(!strcmp(key, "gbFrameSkip")) { 1.1114 + gbFrameSkip = sdlFromHex(value); 1.1115 + if(gbFrameSkip < 0 || gbFrameSkip > 9) 1.1116 + gbFrameSkip = 0; 1.1117 + } else if(!strcmp(key, "video")) { 1.1118 + sizeOption = sdlFromHex(value); 1.1119 + if(sizeOption < 0 || sizeOption > 3) 1.1120 + sizeOption = 1; 1.1121 + } else if(!strcmp(key, "fullScreen")) { 1.1122 + fullscreen = sdlFromHex(value) ? 1 : 0; 1.1123 + } else if(!strcmp(key, "useBios")) { 1.1124 + useBios = sdlFromHex(value) ? true : false; 1.1125 + } else if(!strcmp(key, "skipBios")) { 1.1126 + skipBios = sdlFromHex(value) ? true : false; 1.1127 + } else if(!strcmp(key, "biosFile")) { 1.1128 + strcpy(biosFileName, value); 1.1129 + } else if(!strcmp(key, "filter")) { 1.1130 + filter = sdlFromHex(value); 1.1131 + if(filter < 0 || filter > 13) 1.1132 + filter = 0; 1.1133 + } else if(!strcmp(key, "disableStatus")) { 1.1134 + disableStatusMessages = sdlFromHex(value) ? true : false; 1.1135 + } else if(!strcmp(key, "borderOn")) { 1.1136 + gbBorderOn = sdlFromHex(value) ? true : false; 1.1137 + } else if(!strcmp(key, "borderAutomatic")) { 1.1138 + gbBorderAutomatic = sdlFromHex(value) ? true : false; 1.1139 + } else if(!strcmp(key, "emulatorType")) { 1.1140 + gbEmulatorType = sdlFromHex(value); 1.1141 + if(gbEmulatorType < 0 || gbEmulatorType > 5) 1.1142 + gbEmulatorType = 1; 1.1143 + } else if(!strcmp(key, "colorOption")) { 1.1144 + gbColorOption = sdlFromHex(value) ? true : false; 1.1145 + } else if(!strcmp(key, "captureDir")) { 1.1146 + sdlCheckDirectory(value); 1.1147 + strcpy(captureDir, value); 1.1148 + } else if(!strcmp(key, "saveDir")) { 1.1149 + sdlCheckDirectory(value); 1.1150 + strcpy(saveDir, value); 1.1151 + } else if(!strcmp(key, "batteryDir")) { 1.1152 + sdlCheckDirectory(value); 1.1153 + strcpy(batteryDir, value); 1.1154 + } else if(!strcmp(key, "captureFormat")) { 1.1155 + captureFormat = sdlFromHex(value); 1.1156 + } else if(!strcmp(key, "soundQuality")) { 1.1157 + soundQuality = sdlFromHex(value); 1.1158 + switch(soundQuality) { 1.1159 + case 1: break; 1.1160 + default: 1.1161 + fprintf(stderr, "The rerecording version will run only sound at highest quality. Defaulting to 44.1 KHz\n"); 1.1162 + soundQuality = 1; 1.1163 + break; 1.1164 + } 1.1165 + } else if(!strcmp(key, "soundOff")) { 1.1166 + soundOffFlag = sdlFromHex(value) ? true : false; 1.1167 + } else if(!strcmp(key, "soundEnable")) { 1.1168 + int res = sdlFromHex(value) & 0x30f; 1.1169 + soundEnableChannels(res); 1.1170 + soundDisableChannels(~res); 1.1171 + } else if(!strcmp(key, "soundEcho")) { 1.1172 + soundEcho = sdlFromHex(value) ? true : false; 1.1173 + } else if(!strcmp(key, "soundLowPass")) { 1.1174 + soundLowPass = sdlFromHex(value) ? true : false; 1.1175 + } else if(!strcmp(key, "soundReverse")) { 1.1176 + soundReverse = sdlFromHex(value) ? true : false; 1.1177 + } else if(!strcmp(key, "soundVolume")) { 1.1178 + soundVolume = sdlFromHex(value); 1.1179 + if(soundVolume < 0 || soundVolume > 3) 1.1180 + soundVolume = 0; 1.1181 + } else if(!strcmp(key, "removeIntros")) { 1.1182 + removeIntros = sdlFromHex(value) ? true : false; 1.1183 + } else if(!strcmp(key, "saveType")) { 1.1184 + cpuSaveType = sdlFromHex(value); 1.1185 + if(cpuSaveType < 0 || cpuSaveType > 5) 1.1186 + cpuSaveType = 0; 1.1187 + } else if(!strcmp(key, "flashSize")) { 1.1188 + sdlFlashSize = sdlFromHex(value); 1.1189 + if(sdlFlashSize != 0 && sdlFlashSize != 1) 1.1190 + sdlFlashSize = 0; 1.1191 + } else if(!strcmp(key, "ifbType")) { 1.1192 + ifbType = sdlFromHex(value); 1.1193 + if(ifbType < 0 || ifbType > 2) 1.1194 + ifbType = 0; 1.1195 + } else if(!strcmp(key, "showSpeed")) { 1.1196 + showSpeed = sdlFromHex(value); 1.1197 + if(showSpeed < 0 || showSpeed > 2) 1.1198 + showSpeed = 1; 1.1199 + } else if(!strcmp(key, "showSpeedTransparent")) { 1.1200 + showSpeedTransparent = sdlFromHex(value); 1.1201 + } else if(!strcmp(key, "autoFrameSkip")) { 1.1202 + autoFrameSkip = sdlFromHex(value); 1.1203 + } else if(!strcmp(key, "throttle")) { 1.1204 + throttle = sdlFromHex(value); 1.1205 + if(throttle != 0 && (throttle < 5 || throttle > 1000)) 1.1206 + throttle = 0; 1.1207 + } else if(!strcmp(key, "disableMMX")) { 1.1208 +#ifdef MMX 1.1209 + cpu_mmx = sdlFromHex(value) ? false : true; 1.1210 +#endif 1.1211 + } else if(!strcmp(key, "pauseWhenInactive")) { 1.1212 + pauseWhenInactive = sdlFromHex(value) ? true : false; 1.1213 + } else if(!strcmp(key, "agbPrint")) { 1.1214 + sdlAgbPrint = sdlFromHex(value); 1.1215 + } else if(!strcmp(key, "rtcEnabled")) { 1.1216 + sdlRtcEnable = sdlFromHex(value); 1.1217 + } else if(!strcmp(key, "rewindTimer")) { 1.1218 + rewindTimer = sdlFromHex(value); 1.1219 + if(rewindTimer < 0 || rewindTimer > 600) 1.1220 + rewindTimer = 0; 1.1221 + rewindTimer *= 6; // convert value to 10 frames multiple 1.1222 + } else if(!strcmp(key, "enhancedDetection")) { 1.1223 + cpuEnhancedDetection = sdlFromHex(value) ? true : false; 1.1224 + } else { 1.1225 + fprintf(stderr, "Unknown configuration key %s\n", key); 1.1226 + } 1.1227 + } 1.1228 +} 1.1229 + 1.1230 +void sdlReadPreferences() 1.1231 +{ 1.1232 + FILE *f = sdlFindFile("VisualBoyAdvance.cfg"); 1.1233 + 1.1234 + if(f == NULL) { 1.1235 + fprintf(stderr, "Configuration file NOT FOUND (using defaults)\n"); 1.1236 + return; 1.1237 + } else 1.1238 + fprintf(stderr, "Reading configuration file.\n"); 1.1239 + 1.1240 + sdlReadPreferences(f); 1.1241 + 1.1242 + fclose(f); 1.1243 +} 1.1244 + 1.1245 +static void sdlApplyPerImagePreferences() 1.1246 +{ 1.1247 + FILE *f = sdlFindFile("vba-over.ini"); 1.1248 + if(!f) { 1.1249 + fprintf(stderr, "vba-over.ini NOT FOUND (using emulator settings)\n"); 1.1250 + return; 1.1251 + } else 1.1252 + fprintf(stderr, "Reading vba-over.ini\n"); 1.1253 + 1.1254 + char buffer[7]; 1.1255 + buffer[0] = '['; 1.1256 + buffer[1] = rom[0xac]; 1.1257 + buffer[2] = rom[0xad]; 1.1258 + buffer[3] = rom[0xae]; 1.1259 + buffer[4] = rom[0xaf]; 1.1260 + buffer[5] = ']'; 1.1261 + buffer[6] = 0; 1.1262 + 1.1263 + char readBuffer[2048]; 1.1264 + 1.1265 + bool found = false; 1.1266 + 1.1267 + while(1) { 1.1268 + char *s = fgets(readBuffer, 2048, f); 1.1269 + 1.1270 + if(s == NULL) 1.1271 + break; 1.1272 + 1.1273 + char *p = strchr(s, ';'); 1.1274 + 1.1275 + if(p) 1.1276 + *p = 0; 1.1277 + 1.1278 + char *token = strtok(s, " \t\n\r="); 1.1279 + 1.1280 + if(!token) 1.1281 + continue; 1.1282 + if(strlen(token) == 0) 1.1283 + continue; 1.1284 + 1.1285 + if(!strcmp(token, buffer)) { 1.1286 + found = true; 1.1287 + break; 1.1288 + } 1.1289 + } 1.1290 + 1.1291 + if(found) { 1.1292 + while(1) { 1.1293 + char *s = fgets(readBuffer, 2048, f); 1.1294 + 1.1295 + if(s == NULL) 1.1296 + break; 1.1297 + 1.1298 + char *p = strchr(s, ';'); 1.1299 + if(p) 1.1300 + *p = 0; 1.1301 + 1.1302 + char *token = strtok(s, " \t\n\r="); 1.1303 + if(!token) 1.1304 + continue; 1.1305 + if(strlen(token) == 0) 1.1306 + continue; 1.1307 + 1.1308 + if(token[0] == '[') // starting another image settings 1.1309 + break; 1.1310 + char *value = strtok(NULL, "\t\n\r="); 1.1311 + if(value == NULL) 1.1312 + continue; 1.1313 + 1.1314 + if(!strcmp(token, "rtcEnabled")) 1.1315 + rtcEnable(atoi(value) == 0 ? false : true); 1.1316 + else if(!strcmp(token, "flashSize")) { 1.1317 + int size = atoi(value); 1.1318 + if(size == 0x10000 || size == 0x20000) 1.1319 + flashSetSize(size); 1.1320 + } else if(!strcmp(token, "saveType")) { 1.1321 + int save = atoi(value); 1.1322 + if(save >= 0 && save <= 5) 1.1323 + cpuSaveType = save; 1.1324 + } 1.1325 + } 1.1326 + } 1.1327 + fclose(f); 1.1328 +} 1.1329 + 1.1330 +static int sdlCalculateShift(u32 mask) 1.1331 +{ 1.1332 + int m = 0; 1.1333 + 1.1334 + while(mask) { 1.1335 + m++; 1.1336 + mask >>= 1; 1.1337 + } 1.1338 + 1.1339 + return m-5; 1.1340 +} 1.1341 + 1.1342 +static int sdlCalculateMaskWidth(u32 mask) 1.1343 +{ 1.1344 + int m = 0; 1.1345 + int mask2 = mask; 1.1346 + 1.1347 + while(mask2) { 1.1348 + m++; 1.1349 + mask2 >>= 1; 1.1350 + } 1.1351 + 1.1352 + int m2 = 0; 1.1353 + mask2 = mask; 1.1354 + while(!(mask2 & 1)) { 1.1355 + m2++; 1.1356 + mask2 >>= 1; 1.1357 + } 1.1358 + 1.1359 + return m - m2; 1.1360 +} 1.1361 + 1.1362 +void sdlWriteState(int num) 1.1363 +{ 1.1364 + char stateName[2048]; 1.1365 + 1.1366 + if(saveDir[0]) 1.1367 + sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename), 1.1368 + num+1); 1.1369 + else 1.1370 + sprintf(stateName,"%s%d.sgm", filename, num+1); 1.1371 + if(theEmulator.emuWriteState) 1.1372 + theEmulator.emuWriteState(stateName); 1.1373 + sprintf(stateName, "Wrote state %d", num+1); 1.1374 + systemScreenMessage(stateName); 1.1375 +} 1.1376 + 1.1377 +void sdlReadState(int num) 1.1378 +{ 1.1379 + char stateName[2048]; 1.1380 + 1.1381 + if(saveDir[0]) 1.1382 + sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename), 1.1383 + num+1); 1.1384 + else 1.1385 + sprintf(stateName,"%s%d.sgm", filename, num+1); 1.1386 + 1.1387 + if(theEmulator.emuReadState) 1.1388 + theEmulator.emuReadState(stateName); 1.1389 + 1.1390 + sprintf(stateName, "Loaded state %d", num+1); 1.1391 + systemScreenMessage(stateName); 1.1392 +} 1.1393 + 1.1394 +void sdlWriteBattery() 1.1395 +{ 1.1396 + char buffer[1048]; 1.1397 + 1.1398 + if(batteryDir[0]) 1.1399 + sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename)); 1.1400 + else 1.1401 + sprintf(buffer, "%s.sav", filename); 1.1402 + 1.1403 + theEmulator.emuWriteBattery(buffer); 1.1404 + 1.1405 + systemScreenMessage("Wrote battery"); 1.1406 +} 1.1407 + 1.1408 +void sdlReadBattery() 1.1409 +{ 1.1410 + char buffer[1048]; 1.1411 + 1.1412 + if(batteryDir[0]) 1.1413 + sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename)); 1.1414 + else 1.1415 + sprintf(buffer, "%s.sav", filename); 1.1416 + 1.1417 + bool res = false; 1.1418 + 1.1419 + res = theEmulator.emuReadBattery(buffer); 1.1420 + 1.1421 + if(res) 1.1422 + systemScreenMessage("Loaded battery"); 1.1423 +} 1.1424 + 1.1425 +#define MOD_KEYS (KMOD_CTRL|KMOD_SHIFT|KMOD_ALT|KMOD_META) 1.1426 +#define MOD_NOCTRL (KMOD_SHIFT|KMOD_ALT|KMOD_META) 1.1427 +#define MOD_NOALT (KMOD_CTRL|KMOD_SHIFT|KMOD_META) 1.1428 +#define MOD_NOSHIFT (KMOD_CTRL|KMOD_ALT|KMOD_META) 1.1429 + 1.1430 +void sdlUpdateKey(int key, bool down) 1.1431 +{ 1.1432 + int i; 1.1433 + for(int j = 0; j < 4; j++) { 1.1434 + for(i = 0 ; i < 12; i++) { 1.1435 + if((joypad[j][i] & 0xf000) == 0) { 1.1436 + if(key == joypad[j][i]) 1.1437 + if (down) currentButtons[j] |= 1<<i; 1.1438 + else currentButtons[j] ^= 1<<i; 1.1439 + } 1.1440 + } 1.1441 + } 1.1442 + for(i = 0 ; i < 4; i++) { 1.1443 + if((motion[i] & 0xf000) == 0) { 1.1444 + if(key == motion[i]) 1.1445 + sdlMotionButtons[i] = down; 1.1446 + } 1.1447 + } 1.1448 +} 1.1449 + 1.1450 +void sdlUpdateJoyButton(int which, 1.1451 + int button, 1.1452 + bool pressed) 1.1453 +{ 1.1454 + int i; 1.1455 + for(int j = 0; j < 4; j++) { 1.1456 + for(i = 0; i < 12; i++) { 1.1457 + int dev = (joypad[j][i] >> 12); 1.1458 + int b = joypad[j][i] & 0xfff; 1.1459 + if(dev) { 1.1460 + dev--; 1.1461 + 1.1462 + if((dev == which) && (b >= 128) && (b == (button+128))) { 1.1463 + if (pressed) currentButtons[j] |= 1<<i; 1.1464 + else currentButtons[j] ^= 1<<i; 1.1465 + } 1.1466 + } 1.1467 + } 1.1468 + } 1.1469 + for(i = 0; i < 4; i++) { 1.1470 + int dev = (motion[i] >> 12); 1.1471 + int b = motion[i] & 0xfff; 1.1472 + if(dev) { 1.1473 + dev--; 1.1474 + 1.1475 + if((dev == which) && (b >= 128) && (b == (button+128))) { 1.1476 + sdlMotionButtons[i] = pressed; 1.1477 + } 1.1478 + } 1.1479 + } 1.1480 +} 1.1481 + 1.1482 +void sdlUpdateJoyHat(int which, 1.1483 + int hat, 1.1484 + int value) 1.1485 +{ 1.1486 + int i; 1.1487 + for(int j = 0; j < 4; j++) { 1.1488 + for(i = 0; i < 12; i++) { 1.1489 + int dev = (joypad[j][i] >> 12); 1.1490 + int a = joypad[j][i] & 0xfff; 1.1491 + if(dev) { 1.1492 + dev--; 1.1493 + 1.1494 + if((dev == which) && (a>=32) && (a < 48) && (((a&15)>>2) == hat)) { 1.1495 + int dir = a & 3; 1.1496 + int v = 0; 1.1497 + switch(dir) { 1.1498 + case 0: 1.1499 + v = value & SDL_HAT_UP; 1.1500 + break; 1.1501 + case 1: 1.1502 + v = value & SDL_HAT_DOWN; 1.1503 + break; 1.1504 + case 2: 1.1505 + v = value & SDL_HAT_RIGHT; 1.1506 + break; 1.1507 + case 3: 1.1508 + v = value & SDL_HAT_LEFT; 1.1509 + break; 1.1510 + } 1.1511 + if (v) currentButtons[j] |= 1<<i; 1.1512 + else currentButtons[j] ^= 1<<i; 1.1513 + } 1.1514 + } 1.1515 + } 1.1516 + } 1.1517 + for(i = 0; i < 4; i++) { 1.1518 + int dev = (motion[i] >> 12); 1.1519 + int a = motion[i] & 0xfff; 1.1520 + if(dev) { 1.1521 + dev--; 1.1522 + 1.1523 + if((dev == which) && (a>=32) && (a < 48) && (((a&15)>>2) == hat)) { 1.1524 + int dir = a & 3; 1.1525 + int v = 0; 1.1526 + switch(dir) { 1.1527 + case 0: 1.1528 + v = value & SDL_HAT_UP; 1.1529 + break; 1.1530 + case 1: 1.1531 + v = value & SDL_HAT_DOWN; 1.1532 + break; 1.1533 + case 2: 1.1534 + v = value & SDL_HAT_RIGHT; 1.1535 + break; 1.1536 + case 3: 1.1537 + v = value & SDL_HAT_LEFT; 1.1538 + break; 1.1539 + } 1.1540 + sdlMotionButtons[i] = (v ? true : false); 1.1541 + } 1.1542 + } 1.1543 + } 1.1544 +} 1.1545 + 1.1546 +void sdlUpdateJoyAxis(int which, 1.1547 + int axis, 1.1548 + int value) 1.1549 +{ 1.1550 + int i; 1.1551 + for(int j = 0; j < 4; j++) { 1.1552 + for(i = 0; i < 12; i++) { 1.1553 + int dev = (joypad[j][i] >> 12); 1.1554 + int a = joypad[j][i] & 0xfff; 1.1555 + if(dev) { 1.1556 + dev--; 1.1557 + 1.1558 + if((dev == which) && (a < 32) && ((a>>1) == axis)) { 1.1559 + //I have no idea what this does, is this reimplementation correct? --Felipe 1.1560 + if (value>16384) { 1.1561 + if (a&1) currentButtons[j] |= 1<<i; 1.1562 + else currentButtons[j] ^= 1<<i; 1.1563 + } 1.1564 + else if (value<16384){ 1.1565 + if (a&1) currentButtons[j] ^= 1<<i; 1.1566 + else currentButtons[j] |= 1<<i; 1.1567 + } 1.1568 + } 1.1569 + } 1.1570 + } 1.1571 + } 1.1572 + for(i = 0; i < 4; i++) { 1.1573 + int dev = (motion[i] >> 12); 1.1574 + int a = motion[i] & 0xfff; 1.1575 + if(dev) { 1.1576 + dev--; 1.1577 + 1.1578 + if((dev == which) && (a < 32) && ((a>>1) == axis)) { 1.1579 + sdlMotionButtons[i] = (a & 1) ? (value > 16384) : (value < -16384); 1.1580 + } 1.1581 + } 1.1582 + } 1.1583 +} 1.1584 + 1.1585 +bool sdlCheckJoyKey(int key) 1.1586 +{ 1.1587 + int dev = (key >> 12) - 1; 1.1588 + int what = key & 0xfff; 1.1589 + 1.1590 + if(what >= 128) { 1.1591 + // joystick button 1.1592 + int button = what - 128; 1.1593 + 1.1594 + if(button >= SDL_JoystickNumButtons(sdlDevices[dev])) 1.1595 + return false; 1.1596 + } else if (what < 0x20) { 1.1597 + // joystick axis 1.1598 + what >>= 1; 1.1599 + if(what >= SDL_JoystickNumAxes(sdlDevices[dev])) 1.1600 + return false; 1.1601 + } else if (what < 0x30) { 1.1602 + // joystick hat 1.1603 + what = (what & 15); 1.1604 + what >>= 2; 1.1605 + if(what >= SDL_JoystickNumHats(sdlDevices[dev])) 1.1606 + return false; 1.1607 + } 1.1608 + 1.1609 + // no problem found 1.1610 + return true; 1.1611 +} 1.1612 + 1.1613 +void sdlCheckKeys() 1.1614 +{ 1.1615 + sdlNumDevices = SDL_NumJoysticks(); 1.1616 + 1.1617 + if(sdlNumDevices) 1.1618 + sdlDevices = (SDL_Joystick **)calloc(1,sdlNumDevices * 1.1619 + sizeof(SDL_Joystick **)); 1.1620 + int i; 1.1621 + 1.1622 + bool usesJoy = false; 1.1623 + 1.1624 + for(int j = 0; j < 4; j++) { 1.1625 + for(i = 0; i < 12; i++) { 1.1626 + int dev = joypad[j][i] >> 12; 1.1627 + if(dev) { 1.1628 + dev--; 1.1629 + bool ok = false; 1.1630 + 1.1631 + if(sdlDevices) { 1.1632 + if(dev < sdlNumDevices) { 1.1633 + if(sdlDevices[dev] == NULL) { 1.1634 + sdlDevices[dev] = SDL_JoystickOpen(dev); 1.1635 + } 1.1636 + 1.1637 + ok = sdlCheckJoyKey(joypad[j][i]); 1.1638 + } else 1.1639 + ok = false; 1.1640 + } 1.1641 + 1.1642 + if(!ok) 1.1643 + joypad[j][i] = defaultJoypad[i]; 1.1644 + else 1.1645 + usesJoy = true; 1.1646 + } 1.1647 + } 1.1648 + } 1.1649 + 1.1650 + for(i = 0; i < 4; i++) { 1.1651 + int dev = motion[i] >> 12; 1.1652 + if(dev) { 1.1653 + dev--; 1.1654 + bool ok = false; 1.1655 + 1.1656 + if(sdlDevices) { 1.1657 + if(dev < sdlNumDevices) { 1.1658 + if(sdlDevices[dev] == NULL) { 1.1659 + sdlDevices[dev] = SDL_JoystickOpen(dev); 1.1660 + } 1.1661 + 1.1662 + ok = sdlCheckJoyKey(motion[i]); 1.1663 + } else 1.1664 + ok = false; 1.1665 + } 1.1666 + 1.1667 + if(!ok) 1.1668 + motion[i] = defaultMotion[i]; 1.1669 + else 1.1670 + usesJoy = true; 1.1671 + } 1.1672 + } 1.1673 + 1.1674 + if(usesJoy) 1.1675 + SDL_JoystickEventState(SDL_ENABLE); 1.1676 +} 1.1677 + 1.1678 +void sdlPollEvents() 1.1679 +{ 1.1680 + SDL_Event event; 1.1681 + while(SDL_PollEvent(&event)) { 1.1682 + switch(event.type) { 1.1683 + case SDL_QUIT: 1.1684 + emulating = 0; 1.1685 + break; 1.1686 + case SDL_ACTIVEEVENT: 1.1687 + if(pauseWhenInactive && (event.active.state & SDL_APPINPUTFOCUS)) { 1.1688 + active = event.active.gain; 1.1689 + if(active) { 1.1690 + if(!paused) { 1.1691 + if(emulating) 1.1692 + soundResume(); 1.1693 + } 1.1694 + } else { 1.1695 + wasPaused = true; 1.1696 + if(pauseWhenInactive) { 1.1697 + if(emulating) 1.1698 + soundPause(); 1.1699 + } 1.1700 + 1.1701 + memset(delta,255,sizeof(delta)); 1.1702 + } 1.1703 + } 1.1704 + break; 1.1705 + case SDL_MOUSEMOTION: 1.1706 + case SDL_MOUSEBUTTONUP: 1.1707 + case SDL_MOUSEBUTTONDOWN: 1.1708 + if(fullscreen) { 1.1709 + SDL_ShowCursor(SDL_ENABLE); 1.1710 + mouseCounter = 120; 1.1711 + } 1.1712 + break; 1.1713 + case SDL_JOYHATMOTION: 1.1714 + sdlUpdateJoyHat(event.jhat.which, 1.1715 + event.jhat.hat, 1.1716 + event.jhat.value); 1.1717 + break; 1.1718 + case SDL_JOYBUTTONDOWN: 1.1719 + case SDL_JOYBUTTONUP: 1.1720 + sdlUpdateJoyButton(event.jbutton.which, 1.1721 + event.jbutton.button, 1.1722 + event.jbutton.state == SDL_PRESSED); 1.1723 + break; 1.1724 + case SDL_JOYAXISMOTION: 1.1725 + sdlUpdateJoyAxis(event.jaxis.which, 1.1726 + event.jaxis.axis, 1.1727 + event.jaxis.value); 1.1728 + break; 1.1729 + case SDL_KEYDOWN: 1.1730 + sdlUpdateKey(event.key.keysym.sym, true); 1.1731 + break; 1.1732 + case SDL_KEYUP: 1.1733 + switch(event.key.keysym.sym) { 1.1734 + case SDLK_r: 1.1735 + if(!(event.key.keysym.mod & MOD_NOCTRL) && 1.1736 + (event.key.keysym.mod & KMOD_CTRL)) { 1.1737 + if(emulating) { 1.1738 + theEmulator.emuReset(true); 1.1739 + 1.1740 + systemScreenMessage("Reset"); 1.1741 + } 1.1742 + } 1.1743 + break; 1.1744 + case SDLK_b: 1.1745 + if(!(event.key.keysym.mod & MOD_NOCTRL) && 1.1746 + (event.key.keysym.mod & KMOD_CTRL)) { 1.1747 + if(emulating && theEmulator.emuReadMemState && rewindMemory 1.1748 + && rewindCount) { 1.1749 + rewindPos = --rewindPos & 7; 1.1750 + theEmulator.emuReadMemState(&rewindMemory[REWIND_SIZE*rewindPos], 1.1751 + REWIND_SIZE); 1.1752 + rewindCount--; 1.1753 + rewindCounter = 0; 1.1754 + systemScreenMessage("Rewind"); 1.1755 + } 1.1756 + } 1.1757 + break; 1.1758 + case SDLK_p: 1.1759 + if(!(event.key.keysym.mod & MOD_NOCTRL) && 1.1760 + (event.key.keysym.mod & KMOD_CTRL)) { 1.1761 + paused = !paused; 1.1762 + SDL_PauseAudio(paused); 1.1763 + if(paused) 1.1764 + wasPaused = true; 1.1765 + } 1.1766 + break; 1.1767 + case SDLK_ESCAPE: 1.1768 + emulating = 0; 1.1769 + break; 1.1770 + case SDLK_f: 1.1771 + if(!(event.key.keysym.mod & MOD_NOCTRL) && 1.1772 + (event.key.keysym.mod & KMOD_CTRL)) { 1.1773 + int flags = 0; 1.1774 + fullscreen = !fullscreen; 1.1775 + if(fullscreen) 1.1776 + flags |= SDL_FULLSCREEN; 1.1777 + SDL_SetVideoMode(destWidth, destHeight, systemColorDepth, flags); 1.1778 + // if(SDL_WM_ToggleFullScreen(surface)) 1.1779 + // fullscreen = !fullscreen; 1.1780 + } 1.1781 + break; 1.1782 + case SDLK_F11: 1.1783 + if(dbgMain != debuggerMain) { 1.1784 + if(armState) { 1.1785 + armNextPC -= 4; 1.1786 + reg[15].I -= 4; 1.1787 + } else { 1.1788 + armNextPC -= 2; 1.1789 + reg[15].I -= 2; 1.1790 + } 1.1791 + } 1.1792 + debugger = true; 1.1793 + break; 1.1794 + case SDLK_F1: 1.1795 + case SDLK_F2: 1.1796 + case SDLK_F3: 1.1797 + case SDLK_F4: 1.1798 + case SDLK_F5: 1.1799 + case SDLK_F6: 1.1800 + case SDLK_F7: 1.1801 + case SDLK_F8: 1.1802 + case SDLK_F9: 1.1803 + case SDLK_F10: 1.1804 + if(!(event.key.keysym.mod & MOD_NOSHIFT) && 1.1805 + (event.key.keysym.mod & KMOD_SHIFT)) { 1.1806 + sdlWriteState(event.key.keysym.sym-SDLK_F1); 1.1807 + } else if(!(event.key.keysym.mod & MOD_KEYS)) { 1.1808 + sdlReadState(event.key.keysym.sym-SDLK_F1); 1.1809 + } 1.1810 + break; 1.1811 + case SDLK_1: 1.1812 + case SDLK_2: 1.1813 + case SDLK_3: 1.1814 + case SDLK_4: 1.1815 + if(!(event.key.keysym.mod & MOD_NOALT) && 1.1816 + (event.key.keysym.mod & KMOD_ALT)) { 1.1817 + char *disableMessages[4] = 1.1818 + { "autofire A disabled", 1.1819 + "autofire B disabled", 1.1820 + "autofire R disabled", 1.1821 + "autofire L disabled"}; 1.1822 + char *enableMessages[4] = 1.1823 + { "autofire A", 1.1824 + "autofire B", 1.1825 + "autofire R", 1.1826 + "autofire L"}; 1.1827 + int mask = 1 << (event.key.keysym.sym - SDLK_1); 1.1828 + if(event.key.keysym.sym > SDLK_2) 1.1829 + mask <<= 6; 1.1830 + if(autoFire & mask) { 1.1831 + autoFire &= ~mask; 1.1832 + systemScreenMessage(disableMessages[event.key.keysym.sym - SDLK_1]); 1.1833 + } else { 1.1834 + autoFire |= mask; 1.1835 + systemScreenMessage(enableMessages[event.key.keysym.sym - SDLK_1]); 1.1836 + } 1.1837 + } if(!(event.key.keysym.mod & MOD_NOCTRL) && 1.1838 + (event.key.keysym.mod & KMOD_CTRL)) { 1.1839 + int mask = 0x0100 << (event.key.keysym.sym - SDLK_1); 1.1840 + layerSettings ^= mask; 1.1841 + layerEnable = DISPCNT & layerSettings; 1.1842 + CPUUpdateRenderBuffers(false); 1.1843 + } 1.1844 + break; 1.1845 + case SDLK_5: 1.1846 + case SDLK_6: 1.1847 + case SDLK_7: 1.1848 + case SDLK_8: 1.1849 + if(!(event.key.keysym.mod & MOD_NOCTRL) && 1.1850 + (event.key.keysym.mod & KMOD_CTRL)) { 1.1851 + int mask = 0x0100 << (event.key.keysym.sym - SDLK_1); 1.1852 + layerSettings ^= mask; 1.1853 + layerEnable = DISPCNT & layerSettings; 1.1854 + } 1.1855 + break; 1.1856 + case SDLK_n: 1.1857 + if(!(event.key.keysym.mod & MOD_NOCTRL) && 1.1858 + (event.key.keysym.mod & KMOD_CTRL)) { 1.1859 + if(paused) 1.1860 + paused = false; 1.1861 + pauseNextFrame = true; 1.1862 + } 1.1863 + break; 1.1864 + default: 1.1865 + break; 1.1866 + } 1.1867 + sdlUpdateKey(event.key.keysym.sym, false); 1.1868 + break; 1.1869 + } 1.1870 + } 1.1871 +} 1.1872 + 1.1873 +void usage(char *cmd) 1.1874 +{ 1.1875 + printf("%s [option ...] file\n", cmd); 1.1876 + printf("\ 1.1877 +\n\ 1.1878 +Options:\n\ 1.1879 + -1, --video-1x 1x\n\ 1.1880 + -2, --video-2x 2x\n\ 1.1881 + -3, --video-3x 3x\n\ 1.1882 + -4, --video-4x 4x\n\ 1.1883 + -F, --fullscreen Full screen\n\ 1.1884 + -G, --gdb=PROTOCOL GNU Remote Stub mode:\n\ 1.1885 + tcp - use TCP at port 55555\n\ 1.1886 + tcp:PORT - use TCP at port PORT\n\ 1.1887 + pipe - use pipe transport\n\ 1.1888 + -N, --no-debug Don't parse debug information\n\ 1.1889 + -S, --flash-size=SIZE Set the Flash size\n\ 1.1890 + --flash-64k 0 - 64K Flash\n\ 1.1891 + --flash-128k 1 - 128K Flash\n\ 1.1892 + -T, --throttle=THROTTLE Set the desired throttle (5...1000)\n\ 1.1893 + -Y, --yuv=TYPE Use YUV overlay for drawing:\n\ 1.1894 + 0 - YV12\n\ 1.1895 + 1 - UYVY\n\ 1.1896 + 2 - YVYU\n\ 1.1897 + 3 - YUY2\n\ 1.1898 + 4 - IYUV\n\ 1.1899 + -b, --bios=BIOS Use given bios file\n\ 1.1900 + -c, --config=FILE Read the given configuration file\n\ 1.1901 + -d, --debug Enter debugger\n\ 1.1902 + -f, --filter=FILTER Select filter:\n\ 1.1903 + --filter-normal 0 - normal mode\n\ 1.1904 + --filter-tv-mode 1 - TV Mode\n\ 1.1905 + --filter-2xsai 2 - 2xSaI\n\ 1.1906 + --filter-super-2xsai 3 - Super 2xSaI\n\ 1.1907 + --filter-super-eagle 4 - Super Eagle\n\ 1.1908 + --filter-pixelate 5 - Pixelate\n\ 1.1909 + --filter-motion-blur 6 - Motion Blur\n\ 1.1910 + --filter-advmame 7 - AdvanceMAME Scale2x\n\ 1.1911 + --filter-simple2x 8 - Simple2x\n\ 1.1912 + --filter-bilinear 9 - Bilinear\n\ 1.1913 + --filter-bilinear+ 10 - Bilinear Plus\n\ 1.1914 + --filter-scanlines 11 - Scanlines\n\ 1.1915 + --filter-hq2x 12 - hq2x\n\ 1.1916 + --filter-lq2x 13 - lq2x\n\ 1.1917 + -h, --help Print this help\n\ 1.1918 + -i, --ips=PATCH Apply given IPS patch\n\ 1.1919 + -P, --profile=[HERTZ] Enable profiling\n\ 1.1920 + -s, --frameskip=FRAMESKIP Set frame skip (0...9)\n\ 1.1921 +"); 1.1922 + printf("\ 1.1923 + -t, --save-type=TYPE Set the available save type\n\ 1.1924 + --save-auto 0 - Automatic (EEPROM, SRAM, FLASH)\n\ 1.1925 + --save-eeprom 1 - EEPROM\n\ 1.1926 + --save-sram 2 - SRAM\n\ 1.1927 + --save-flash 3 - FLASH\n\ 1.1928 + --save-sensor 4 - EEPROM+Sensor\n\ 1.1929 + --save-none 5 - NONE\n\ 1.1930 + -v, --verbose=VERBOSE Set verbose logging (trace.log)\n\ 1.1931 + 1 - SWI\n\ 1.1932 + 2 - Unaligned memory access\n\ 1.1933 + 4 - Illegal memory write\n\ 1.1934 + 8 - Illegal memory read\n\ 1.1935 + 16 - DMA 0\n\ 1.1936 + 32 - DMA 1\n\ 1.1937 + 64 - DMA 2\n\ 1.1938 + 128 - DMA 3\n\ 1.1939 + 256 - Undefined instruction\n\ 1.1940 + 512 - AGBPrint messages\n\ 1.1941 +\n\ 1.1942 +Long options only:\n\ 1.1943 + --agb-print Enable AGBPrint support\n\ 1.1944 + --auto-frameskip Enable auto frameskipping\n\ 1.1945 + --ifb-none No interframe blending\n\ 1.1946 + --ifb-motion-blur Interframe motion blur\n\ 1.1947 + --ifb-smart Smart interframe blending\n\ 1.1948 + --no-agb-print Disable AGBPrint support\n\ 1.1949 + --no-auto-frameskip Disable auto frameskipping\n\ 1.1950 + --no-ips Do not apply IPS patch\n\ 1.1951 + --no-mmx Disable MMX support\n\ 1.1952 + --no-pause-when-inactive Don't pause when inactive\n\ 1.1953 + --no-rtc Disable RTC support\n\ 1.1954 + --no-show-speed Don't show emulation speed\n\ 1.1955 + --no-throttle Disable thrrotle\n\ 1.1956 + --pause-when-inactive Pause when inactive\n\ 1.1957 + --rtc Enable RTC support\n\ 1.1958 + --show-speed-normal Show emulation speed\n\ 1.1959 + --show-speed-detailed Show detailed speed data\n\ 1.1960 +"); 1.1961 + printf("\ 1.1962 + -r, --recordmovie=filename Start recording input movie\n\ 1.1963 + -p, --playmovie=filename Play input movie non-read-only\n\ 1.1964 + -w, --watchmovie=filename Play input movie in read-only mode\n\ 1.1965 +"); 1.1966 +} 1.1967 + 1.1968 +static char *szFile; 1.1969 + 1.1970 +void file_run() 1.1971 +{ 1.1972 + utilGetBaseName(szFile, filename); 1.1973 + char *p = strrchr(filename, '.'); 1.1974 + 1.1975 + if(p) 1.1976 + *p = 0; 1.1977 + 1.1978 + if(ipsname[0] == 0) 1.1979 + sprintf(ipsname, "%s.ips", filename); 1.1980 + 1.1981 + bool failed = false; 1.1982 + 1.1983 + IMAGE_TYPE type = utilFindType(szFile); 1.1984 + 1.1985 + if(type == IMAGE_UNKNOWN) { 1.1986 + systemMessage(0, "Unknown file type %s", szFile); 1.1987 + exit(-1); 1.1988 + } 1.1989 + systemCartridgeType = (int)type; 1.1990 + 1.1991 + if(type == IMAGE_GB) { 1.1992 + failed = !gbLoadRom(szFile); 1.1993 + if(!failed) { 1.1994 + systemCartridgeType = 1; 1.1995 + theEmulator = GBSystem; 1.1996 + if(sdlAutoIPS) { 1.1997 + int size = gbRomSize; 1.1998 + utilApplyIPS(ipsname, &gbRom, &size); 1.1999 + if(size != gbRomSize) { 1.2000 + extern bool gbUpdateSizes(); 1.2001 + gbUpdateSizes(); 1.2002 + gbReset(); 1.2003 + } 1.2004 + } 1.2005 + } 1.2006 + } else if(type == IMAGE_GBA) { 1.2007 + int size = CPULoadRom(szFile); 1.2008 + failed = (size == 0); 1.2009 + if(!failed) { 1.2010 + // if(cpuEnhancedDetection && cpuSaveType == 0) { 1.2011 + // utilGBAFindSave(rom, size); 1.2012 + // } 1.2013 + 1.2014 + sdlApplyPerImagePreferences(); 1.2015 + 1.2016 + systemCartridgeType = 0; 1.2017 + theEmulator = GBASystem; 1.2018 + 1.2019 + /* disabled due to problems 1.2020 + if(removeIntros && rom != NULL) { 1.2021 + WRITE32LE(&rom[0], 0xea00002e); 1.2022 + } 1.2023 + */ 1.2024 + 1.2025 + //CPUInit(biosFileName, useBios); 1.2026 + CPUInit(); 1.2027 + CPUReset(); 1.2028 + if(sdlAutoIPS) { 1.2029 + int size = 0x2000000; 1.2030 + utilApplyIPS(ipsname, &rom, &size); 1.2031 + if(size != 0x2000000) { 1.2032 + CPUReset(); 1.2033 + } 1.2034 + } 1.2035 + } 1.2036 + } 1.2037 + 1.2038 + if(failed) { 1.2039 + systemMessage(0, "Failed to load file %s", szFile); 1.2040 + exit(-1); 1.2041 + } 1.2042 + 1.2043 + emulating = 1; 1.2044 + renderedFrames = 0; 1.2045 + } 1.2046 + 1.2047 +int main(int argc, char **argv) 1.2048 +{ 1.2049 + fprintf(stderr, "VisualBoyAdvance version %s [SDL]\n", VERSION); 1.2050 + 1.2051 + arg0 = argv[0]; 1.2052 + 1.2053 + captureDir[0] = 0; 1.2054 + saveDir[0] = 0; 1.2055 + batteryDir[0] = 0; 1.2056 + ipsname[0] = 0; 1.2057 + 1.2058 + int op = -1; 1.2059 + 1.2060 + frameSkip = 2; 1.2061 + gbBorderOn = 0; 1.2062 + 1.2063 + parseDebug = true; 1.2064 + 1.2065 + sdlReadPreferences(); 1.2066 + 1.2067 + sdlPrintUsage = 0; 1.2068 + 1.2069 + while((op = getopt_long(argc, 1.2070 + argv, 1.2071 + "FNT:Y:G:D:b:c:df:hi:p::s:t:v:1234", 1.2072 + sdlOptions, 1.2073 + NULL)) != -1) { 1.2074 + switch(op) { 1.2075 + case 0: 1.2076 + // long option already processed by getopt_long 1.2077 + break; 1.2078 + case 'b': 1.2079 + useBios = true; 1.2080 + if(optarg == NULL) { 1.2081 + fprintf(stderr, "Missing BIOS file name\n"); 1.2082 + exit(-1); 1.2083 + } 1.2084 + strcpy(biosFileName, optarg); 1.2085 + break; 1.2086 + case 'c': 1.2087 + { 1.2088 + if(optarg == NULL) { 1.2089 + fprintf(stderr, "Missing config file name\n"); 1.2090 + exit(-1); 1.2091 + } 1.2092 + FILE *f = fopen(optarg, "r"); 1.2093 + if(f == NULL) { 1.2094 + fprintf(stderr, "File not found %s\n", optarg); 1.2095 + exit(-1); 1.2096 + } 1.2097 + sdlReadPreferences(f); 1.2098 + fclose(f); 1.2099 + } 1.2100 + break; 1.2101 + case 'd': 1.2102 + debugger = true; 1.2103 + break; 1.2104 + case 'h': 1.2105 + sdlPrintUsage = 1; 1.2106 + break; 1.2107 + case 'i': 1.2108 + if(optarg == NULL) { 1.2109 + fprintf(stderr, "Missing IPS name\n"); 1.2110 + exit(-1); 1.2111 + strcpy(ipsname, optarg); 1.2112 + } 1.2113 + break; 1.2114 + case 'Y': 1.2115 + yuv = true; 1.2116 + if(optarg) { 1.2117 + yuvType = atoi(optarg); 1.2118 + switch(yuvType) { 1.2119 + case 0: 1.2120 + yuvType = SDL_YV12_OVERLAY; 1.2121 + break; 1.2122 + case 1: 1.2123 + yuvType = SDL_UYVY_OVERLAY; 1.2124 + break; 1.2125 + case 2: 1.2126 + yuvType = SDL_YVYU_OVERLAY; 1.2127 + break; 1.2128 + case 3: 1.2129 + yuvType = SDL_YUY2_OVERLAY; 1.2130 + break; 1.2131 + case 4: 1.2132 + yuvType = SDL_IYUV_OVERLAY; 1.2133 + break; 1.2134 + default: 1.2135 + yuvType = SDL_YV12_OVERLAY; 1.2136 + } 1.2137 + } else 1.2138 + yuvType = SDL_YV12_OVERLAY; 1.2139 + break; 1.2140 + case 'G': 1.2141 + dbgMain = remoteStubMain; 1.2142 + dbgSignal = remoteStubSignal; 1.2143 + dbgOutput = remoteOutput; 1.2144 + debugger = true; 1.2145 + debuggerStub = true; 1.2146 + if(optarg) { 1.2147 + char *s = optarg; 1.2148 + if(strncmp(s,"tcp:", 4) == 0) { 1.2149 + s+=4; 1.2150 + int port = atoi(s); 1.2151 + remoteSetProtocol(0); 1.2152 + remoteSetPort(port); 1.2153 + } else if(strcmp(s,"tcp") == 0) { 1.2154 + remoteSetProtocol(0); 1.2155 + } else if(strcmp(s, "pipe") == 0) { 1.2156 + remoteSetProtocol(1); 1.2157 + } else { 1.2158 + fprintf(stderr, "Unknown protocol %s\n", s); 1.2159 + exit(-1); 1.2160 + } 1.2161 + } else { 1.2162 + remoteSetProtocol(0); 1.2163 + } 1.2164 + break; 1.2165 + case 'N': 1.2166 + parseDebug = false; 1.2167 + break; 1.2168 + case 'D': 1.2169 + if(optarg) { 1.2170 + systemDebug = atoi(optarg); 1.2171 + } else { 1.2172 + systemDebug = 1; 1.2173 + } 1.2174 + break; 1.2175 + case 'F': 1.2176 + fullscreen = 1; 1.2177 + mouseCounter = 120; 1.2178 + break; 1.2179 + case 'f': 1.2180 + if(optarg) { 1.2181 + filter = atoi(optarg); 1.2182 + } else { 1.2183 + filter = 0; 1.2184 + } 1.2185 + break; 1.2186 + 1.2187 + case 'r': 1.2188 + if(optarg == NULL) { 1.2189 + fprintf(stderr, "ERROR: --recordMovie ('r') needs movie filename as option\n"); 1.2190 + exit(-1); 1.2191 + } 1.2192 + strcpy(movieFileName, optarg); 1.2193 + useMovie = 1; 1.2194 + break; 1.2195 + case 'p': // play without read-only (editable) 1.2196 + fprintf (stderr, "-p got called!\n"); 1.2197 + if(optarg == NULL) { 1.2198 + fprintf(stderr, "ERROR: --playMovie ('p') needs movie filename as option\n"); 1.2199 + exit(-1); 1.2200 + } 1.2201 + strcpy(movieFileName, optarg); 1.2202 + useMovie = 2; 1.2203 + break; 1.2204 + case 'w': // play with read-only 1.2205 + fprintf (stderr, "-w got called!\n"); 1.2206 + if(optarg == NULL) { 1.2207 + fprintf(stderr, "ERROR: --watchMovie ('w') needs movie filename as option\n"); 1.2208 + exit(-1); 1.2209 + } 1.2210 + strcpy(movieFileName, optarg); 1.2211 + useMovie = 3; 1.2212 + break; 1.2213 + 1.2214 + case 'P': 1.2215 +#ifdef PROFILING 1.2216 + if(optarg) { 1.2217 + cpuEnableProfiling(atoi(optarg)); 1.2218 + } else 1.2219 + cpuEnableProfiling(100); 1.2220 +#endif 1.2221 + break; 1.2222 + case 'S': 1.2223 + sdlFlashSize = atoi(optarg); 1.2224 + if(sdlFlashSize < 0 || sdlFlashSize > 1) 1.2225 + sdlFlashSize = 0; 1.2226 + break; 1.2227 + case 's': 1.2228 + if(optarg) { 1.2229 + int a = atoi(optarg); 1.2230 + if(a >= 0 && a <= 9) { 1.2231 + gbFrameSkip = a; 1.2232 + frameSkip = a; 1.2233 + } 1.2234 + } else { 1.2235 + frameSkip = 2; 1.2236 + gbFrameSkip = 0; 1.2237 + } 1.2238 + break; 1.2239 + case 't': 1.2240 + if(optarg) { 1.2241 + int a = atoi(optarg); 1.2242 + if(a < 0 || a > 5) 1.2243 + a = 0; 1.2244 + cpuSaveType = a; 1.2245 + } 1.2246 + break; 1.2247 + case 'T': 1.2248 + if(optarg) { 1.2249 + int t = atoi(optarg); 1.2250 + throttle = t; 1.2251 + } 1.2252 + break; 1.2253 + case 'v': 1.2254 + if(optarg) { 1.2255 + systemVerbose = atoi(optarg); 1.2256 + } else 1.2257 + systemVerbose = 0; 1.2258 + break; 1.2259 + case '1': 1.2260 + sizeOption = 0; 1.2261 + break; 1.2262 + case '2': 1.2263 + sizeOption = 1; 1.2264 + break; 1.2265 + case '3': 1.2266 + sizeOption = 2; 1.2267 + break; 1.2268 + case '4': 1.2269 + sizeOption = 3; 1.2270 + break; 1.2271 + case '?': 1.2272 + sdlPrintUsage = 1; 1.2273 + break; 1.2274 + } 1.2275 + } 1.2276 + 1.2277 + if(sdlPrintUsage) { 1.2278 + usage(argv[0]); 1.2279 + exit(-1); 1.2280 + } 1.2281 + 1.2282 +#ifdef MMX 1.2283 + if(disableMMX) 1.2284 + cpu_mmx = 0; 1.2285 +#endif 1.2286 + 1.2287 + if(rewindTimer) 1.2288 + rewindMemory = (char *)malloc(8*REWIND_SIZE); 1.2289 + 1.2290 + if(sdlFlashSize == 0) 1.2291 + flashSetSize(0x10000); 1.2292 + else 1.2293 + flashSetSize(0x20000); 1.2294 + 1.2295 + rtcEnable(sdlRtcEnable ? true : false); 1.2296 + agbPrintEnable(sdlAgbPrint ? true : false); 1.2297 + 1.2298 + if(!debuggerStub) { 1.2299 + if(optind >= argc) { 1.2300 + systemMessage(0,"Missing image name"); 1.2301 + usage(argv[0]); 1.2302 + exit(-1); 1.2303 + } 1.2304 + } 1.2305 + 1.2306 + if(filter) { 1.2307 + sizeOption = 1; 1.2308 + } 1.2309 + 1.2310 + for(int i = 0; i < 24;) { 1.2311 + systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10); 1.2312 + systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10); 1.2313 + systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10); 1.2314 + systemGbPalette[i++] = 0; 1.2315 + } 1.2316 + 1.2317 + systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; 1.2318 + 1.2319 + if(optind < argc) 1.2320 + { 1.2321 + szFile = argv[optind]; 1.2322 + file_run(); 1.2323 + } 1.2324 + else 1.2325 + { 1.2326 + systemCartridgeType = 0; 1.2327 + strcpy(filename, "gnu_stub"); 1.2328 + rom = (u8 *)malloc(0x2000000); 1.2329 + workRAM = (u8 *)calloc(1, 0x40000); 1.2330 + bios = (u8 *)calloc(1,0x4000); 1.2331 + internalRAM = (u8 *)calloc(1,0x8000); 1.2332 + paletteRAM = (u8 *)calloc(1,0x400); 1.2333 + vram = (u8 *)calloc(1, 0x20000); 1.2334 + oam = (u8 *)calloc(1, 0x400); 1.2335 + pix = (u8 *)calloc(1, 4 * 240 * 160); 1.2336 + ioMem = (u8 *)calloc(1, 0x400); 1.2337 + 1.2338 + theEmulator = GBASystem; 1.2339 + 1.2340 + //CPUInit(biosFileName, useBios); 1.2341 + CPUInit(); 1.2342 + CPUReset(); 1.2343 + } 1.2344 + 1.2345 + if(debuggerStub) 1.2346 + remoteInit(); 1.2347 + 1.2348 + int flags = SDL_INIT_VIDEO|SDL_INIT_AUDIO| 1.2349 + SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE; 1.2350 + 1.2351 + if(soundOffFlag) 1.2352 + flags ^= SDL_INIT_AUDIO; 1.2353 + 1.2354 + if(SDL_Init(flags)) { 1.2355 + systemMessage(0, "Failed to init SDL: %s", SDL_GetError()); 1.2356 + exit(-1); 1.2357 + } 1.2358 + 1.2359 + if(SDL_InitSubSystem(SDL_INIT_JOYSTICK)) { 1.2360 + systemMessage(0, "Failed to init joystick support: %s", SDL_GetError()); 1.2361 + } 1.2362 + 1.2363 + sdlCheckKeys(); 1.2364 + 1.2365 + if(systemCartridgeType == 0) { 1.2366 + srcWidth = 240; 1.2367 + srcHeight = 160; 1.2368 + systemFrameSkip = frameSkip; 1.2369 + } else if (systemCartridgeType == 1) { 1.2370 + if(gbBorderOn) { 1.2371 + srcWidth = 256; 1.2372 + srcHeight = 224; 1.2373 + gbBorderLineSkip = 256; 1.2374 + gbBorderColumnSkip = 48; 1.2375 + gbBorderRowSkip = 40; 1.2376 + } else { 1.2377 + srcWidth = 160; 1.2378 + srcHeight = 144; 1.2379 + gbBorderLineSkip = 160; 1.2380 + gbBorderColumnSkip = 0; 1.2381 + gbBorderRowSkip = 0; 1.2382 + } 1.2383 + systemFrameSkip = gbFrameSkip; 1.2384 + } else { 1.2385 + srcWidth = 320; 1.2386 + srcHeight = 240; 1.2387 + } 1.2388 + 1.2389 + destWidth = (sizeOption+1)*srcWidth; 1.2390 + destHeight = (sizeOption+1)*srcHeight; 1.2391 + 1.2392 + surface = SDL_SetVideoMode(destWidth, destHeight, 16, 1.2393 + SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF| 1.2394 + (fullscreen ? SDL_FULLSCREEN : 0)); 1.2395 + 1.2396 + if(surface == NULL) { 1.2397 + systemMessage(0, "Failed to set video mode"); 1.2398 + SDL_Quit(); 1.2399 + exit(-1); 1.2400 + } 1.2401 + 1.2402 + systemRedShift = sdlCalculateShift(surface->format->Rmask); 1.2403 + systemGreenShift = sdlCalculateShift(surface->format->Gmask); 1.2404 + systemBlueShift = sdlCalculateShift(surface->format->Bmask); 1.2405 + 1.2406 + systemColorDepth = surface->format->BitsPerPixel; 1.2407 + if(systemColorDepth == 15) 1.2408 + systemColorDepth = 16; 1.2409 + 1.2410 + if(yuv) { 1.2411 + Init_Overlay(surface, yuvType); 1.2412 + systemColorDepth = 32; 1.2413 + systemRedShift = 3; 1.2414 + systemGreenShift = 11; 1.2415 + systemBlueShift = 19; 1.2416 + } 1.2417 + 1.2418 + if(systemColorDepth != 16 && systemColorDepth != 24 && 1.2419 + systemColorDepth != 32) { 1.2420 + fprintf(stderr,"Unsupported color depth '%d'.\nOnly 16, 24 and 32 bit color depths are supported\n", systemColorDepth); 1.2421 + exit(-1); 1.2422 + } 1.2423 + 1.2424 +#ifndef C_CORE 1.2425 + sdlMakeStretcher(srcWidth); 1.2426 +#else 1.2427 + switch(systemColorDepth) { 1.2428 + case 16: 1.2429 + sdlStretcher = sdlStretcher16[sizeOption]; 1.2430 + break; 1.2431 + case 24: 1.2432 + sdlStretcher = sdlStretcher24[sizeOption]; 1.2433 + break; 1.2434 + case 32: 1.2435 + sdlStretcher = sdlStretcher32[sizeOption]; 1.2436 + break; 1.2437 + default: 1.2438 + fprintf(stderr, "Unsupported resolution: %d\n", systemColorDepth); 1.2439 + exit(-1); 1.2440 + } 1.2441 +#endif 1.2442 + 1.2443 + fprintf(stderr,"Color depth: %d\n", systemColorDepth); 1.2444 + 1.2445 + if(systemColorDepth == 16) { 1.2446 + if(sdlCalculateMaskWidth(surface->format->Gmask) == 6) { 1.2447 + Init_2xSaI(565); 1.2448 + RGB_LOW_BITS_MASK = 0x821; 1.2449 + } else { 1.2450 + Init_2xSaI(555); 1.2451 + RGB_LOW_BITS_MASK = 0x421; 1.2452 + } 1.2453 + if(systemCartridgeType == 2) { 1.2454 + for(int i = 0; i < 0x10000; i++) { 1.2455 + systemColorMap16[i] = (((i >> 1) & 0x1f) << systemBlueShift) | 1.2456 + (((i & 0x7c0) >> 6) << systemGreenShift) | 1.2457 + (((i & 0xf800) >> 11) << systemRedShift); 1.2458 + } 1.2459 + } else { 1.2460 + for(int i = 0; i < 0x10000; i++) { 1.2461 + systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | 1.2462 + (((i & 0x3e0) >> 5) << systemGreenShift) | 1.2463 + (((i & 0x7c00) >> 10) << systemBlueShift); 1.2464 + } 1.2465 + } 1.2466 + srcPitch = srcWidth * 2+4; 1.2467 + } else { 1.2468 + if(systemColorDepth != 32) 1.2469 + filterFunction = NULL; 1.2470 + RGB_LOW_BITS_MASK = 0x010101; 1.2471 + if(systemColorDepth == 32) { 1.2472 + Init_2xSaI(32); 1.2473 + } 1.2474 + for(int i = 0; i < 0x10000; i++) { 1.2475 + systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | 1.2476 + (((i & 0x3e0) >> 5) << systemGreenShift) | 1.2477 + (((i & 0x7c00) >> 10) << systemBlueShift); 1.2478 + } 1.2479 + if(systemColorDepth == 32) 1.2480 + srcPitch = srcWidth*4 + 4; 1.2481 + else 1.2482 + srcPitch = srcWidth*3; 1.2483 + } 1.2484 + 1.2485 + if(systemColorDepth != 32) { 1.2486 + switch(filter) { 1.2487 + case 0: 1.2488 + filterFunction = NULL; 1.2489 + break; 1.2490 + case 1: 1.2491 + filterFunction = ScanlinesTV; 1.2492 + break; 1.2493 + case 2: 1.2494 + filterFunction = _2xSaI; 1.2495 + break; 1.2496 + case 3: 1.2497 + filterFunction = Super2xSaI; 1.2498 + break; 1.2499 + case 4: 1.2500 + filterFunction = SuperEagle; 1.2501 + break; 1.2502 + case 5: 1.2503 + filterFunction = Pixelate2x16; 1.2504 + break; 1.2505 + case 6: 1.2506 + filterFunction = MotionBlur; 1.2507 + break; 1.2508 + case 7: 1.2509 + filterFunction = AdMame2x; 1.2510 + break; 1.2511 + case 8: 1.2512 + filterFunction = Simple2x16; 1.2513 + break; 1.2514 + case 9: 1.2515 + filterFunction = Bilinear; 1.2516 + break; 1.2517 + case 10: 1.2518 + filterFunction = BilinearPlus; 1.2519 + break; 1.2520 + case 11: 1.2521 + filterFunction = Scanlines; 1.2522 + break; 1.2523 + case 12: 1.2524 + filterFunction = hq2x; 1.2525 + break; 1.2526 + case 13: 1.2527 + filterFunction = lq2x; 1.2528 + break; 1.2529 + default: 1.2530 + filterFunction = NULL; 1.2531 + break; 1.2532 + } 1.2533 + } else { 1.2534 + switch(filter) { 1.2535 + case 0: 1.2536 + filterFunction = NULL; 1.2537 + break; 1.2538 + case 1: 1.2539 + filterFunction = ScanlinesTV32; 1.2540 + break; 1.2541 + case 2: 1.2542 + filterFunction = _2xSaI32; 1.2543 + break; 1.2544 + case 3: 1.2545 + filterFunction = Super2xSaI32; 1.2546 + break; 1.2547 + case 4: 1.2548 + filterFunction = SuperEagle32; 1.2549 + break; 1.2550 + case 5: 1.2551 + filterFunction = Pixelate2x32; 1.2552 + break; 1.2553 + case 6: 1.2554 + filterFunction = MotionBlur32; 1.2555 + break; 1.2556 + case 7: 1.2557 + filterFunction = AdMame2x32; 1.2558 + break; 1.2559 + case 8: 1.2560 + filterFunction = Simple2x32; 1.2561 + break; 1.2562 + case 9: 1.2563 + filterFunction = Bilinear32; 1.2564 + break; 1.2565 + case 10: 1.2566 + filterFunction = BilinearPlus32; 1.2567 + break; 1.2568 + case 11: 1.2569 + filterFunction = Scanlines32; 1.2570 + break; 1.2571 + case 12: 1.2572 + filterFunction = hq2x32; 1.2573 + break; 1.2574 + case 13: 1.2575 + filterFunction = lq2x32; 1.2576 + break; 1.2577 + default: 1.2578 + filterFunction = NULL; 1.2579 + break; 1.2580 + } 1.2581 + } 1.2582 + 1.2583 + if(systemColorDepth == 16) { 1.2584 + switch(ifbType) { 1.2585 + case 0: 1.2586 + default: 1.2587 + ifbFunction = NULL; 1.2588 + break; 1.2589 + case 1: 1.2590 + ifbFunction = MotionBlurIB; 1.2591 + break; 1.2592 + case 2: 1.2593 + ifbFunction = SmartIB; 1.2594 + break; 1.2595 + } 1.2596 + } else if(systemColorDepth == 32) { 1.2597 + switch(ifbType) { 1.2598 + case 0: 1.2599 + default: 1.2600 + ifbFunction = NULL; 1.2601 + break; 1.2602 + case 1: 1.2603 + ifbFunction = MotionBlurIB32; 1.2604 + break; 1.2605 + case 2: 1.2606 + ifbFunction = SmartIB32; 1.2607 + break; 1.2608 + } 1.2609 + } else 1.2610 + ifbFunction = NULL; 1.2611 + 1.2612 + if(delta == NULL) { 1.2613 + delta = (u8*)malloc(322*242*4); 1.2614 + memset(delta, 255, 322*242*4); 1.2615 + } 1.2616 + 1.2617 + if(!soundOffFlag) 1.2618 + soundInit(); 1.2619 + 1.2620 + autoFrameSkipLastTime = throttleLastTime = systemGetClock(); 1.2621 + 1.2622 + switch(useMovie) 1.2623 + { 1.2624 + case 1: // --recordMovie 1.2625 + VBAMovieCreate(movieFileName, 1.2626 + /*authorInfo*/"", 1.2627 + /*startFlags*/0, 1.2628 + /*controllerFlags*/MOVIE_CONTROLLER(0), 1.2629 + /*typeFlags*/(systemCartridgeType==IMAGE_GBA)?(MOVIE_TYPE_GBA):(GBC_CAPABLE?MOVIE_TYPE_GBC:MOVIE_TYPE_SGB)); 1.2630 + break; 1.2631 + case 2: // --playMovie 1.2632 + VBAMovieOpen(movieFileName, false); 1.2633 + break; 1.2634 + case 3: // --watchMovie 1.2635 + VBAMovieOpen(movieFileName, true); 1.2636 + break; 1.2637 + default: 1.2638 + sdlReadBattery(); 1.2639 + break; 1.2640 + } 1.2641 + SDL_WM_SetCaption("VisualBoyAdvance", NULL); 1.2642 + 1.2643 + char *moviefile = getenv("AUTODEMO"); 1.2644 +// fprintf (stderr, "Checking for AUTODEMO...\n"); 1.2645 + if (moviefile) 1.2646 + { 1.2647 +// fprintf (stderr, "I got a filename OMG!\nCalling VBAMovieOpen...\n"); 1.2648 + VBAMovieOpen(moviefile, true); 1.2649 + } 1.2650 + 1.2651 + while(emulating) { 1.2652 + if(!paused && active) { 1.2653 + if(debugger && theEmulator.emuHasDebugger) 1.2654 + dbgMain(); 1.2655 + else { 1.2656 + theEmulator.emuMain(theEmulator.emuCount); 1.2657 + if(rewindSaveNeeded && rewindMemory && theEmulator.emuWriteMemState) { 1.2658 + rewindCount++; 1.2659 + if(rewindCount > 8) 1.2660 + rewindCount = 8; 1.2661 + if(theEmulator.emuWriteMemState && 1.2662 + theEmulator.emuWriteMemState(&rewindMemory[rewindPos*REWIND_SIZE], 1.2663 + REWIND_SIZE)) { 1.2664 + rewindPos = ++rewindPos & 7; 1.2665 + if(rewindCount == 8) 1.2666 + rewindTopPos = ++rewindTopPos & 7; 1.2667 + } 1.2668 + } 1.2669 + 1.2670 + rewindSaveNeeded = false; 1.2671 + } 1.2672 + } else { 1.2673 + SDL_Delay(500); 1.2674 + } 1.2675 + sdlPollEvents(); 1.2676 + if(mouseCounter) { 1.2677 + mouseCounter--; 1.2678 + if(mouseCounter == 0) 1.2679 + SDL_ShowCursor(SDL_DISABLE); 1.2680 + } 1.2681 + } 1.2682 + 1.2683 + emulating = 0; 1.2684 + fprintf(stderr,"Shutting down\n"); 1.2685 + remoteCleanUp(); 1.2686 + soundShutdown(); 1.2687 + 1.2688 + if(gbRom != NULL || rom != NULL) { 1.2689 + sdlWriteBattery(); 1.2690 + theEmulator.emuCleanUp(); 1.2691 + } 1.2692 + 1.2693 + if(delta) { 1.2694 + free(delta); 1.2695 + delta = NULL; 1.2696 + } 1.2697 + 1.2698 + SDL_Quit(); 1.2699 + return 0; 1.2700 +} 1.2701 + 1.2702 +void systemMessage(int num, const char *msg, ...) 1.2703 +{ 1.2704 + char buffer[2048]; 1.2705 + va_list valist; 1.2706 + 1.2707 + va_start(valist, msg); 1.2708 + vsprintf(buffer, msg, valist); 1.2709 + 1.2710 + fprintf(stderr, "%s\n", buffer); 1.2711 + va_end(valist); 1.2712 +} 1.2713 + 1.2714 +//On WIN32, this function messages requesting 1.2715 +//the window to be redrawn. Can this be ignored here? 1.2716 +void systemRefreshScreen(){} 1.2717 + 1.2718 +void systemRenderFrame() 1.2719 +{ 1.2720 + renderedFrames++; 1.2721 + VBAUpdateFrameCountDisplay(); 1.2722 + VBAUpdateButtonPressDisplay(); 1.2723 + 1.2724 + if(yuv) { 1.2725 + Draw_Overlay(surface, sizeOption+1); 1.2726 + return; 1.2727 + } 1.2728 + 1.2729 + SDL_LockSurface(surface); 1.2730 + 1.2731 + for(int slot = 0 ; slot < 8 ; slot++) 1.2732 + { 1.2733 + if(screenMessage[slot]) { 1.2734 + if(systemCartridgeType == 1 && gbBorderOn) { 1.2735 + gbSgbRenderBorder(); 1.2736 + } 1.2737 + if(((systemGetClock() - screenMessageTime[slot]) < screenMessageDuration[slot]) && 1.2738 + !disableStatusMessages) { 1.2739 + drawText(pix, srcPitch, 10, srcHeight - 20*(slot+1), 1.2740 + screenMessageBuffer[slot]); 1.2741 + } else { 1.2742 + screenMessage[slot] = false; 1.2743 + } 1.2744 + } 1.2745 + } 1.2746 + 1.2747 + if(ifbFunction) { 1.2748 + if(systemColorDepth == 16) 1.2749 + ifbFunction(pix+destWidth+4, destWidth+4, srcWidth, srcHeight); 1.2750 + else 1.2751 + ifbFunction(pix+destWidth*2+4, destWidth*2+4, srcWidth, srcHeight); 1.2752 + } 1.2753 + 1.2754 + if(filterFunction) { 1.2755 + if(systemColorDepth == 16) 1.2756 + filterFunction(pix+destWidth+4,destWidth+4, delta, 1.2757 + (u8*)surface->pixels,surface->pitch, 1.2758 + srcWidth, 1.2759 + srcHeight); 1.2760 + else 1.2761 + filterFunction(pix+destWidth*2+4, 1.2762 + destWidth*2+4, 1.2763 + delta, 1.2764 + (u8*)surface->pixels, 1.2765 + surface->pitch, 1.2766 + srcWidth, 1.2767 + srcHeight); 1.2768 + } else { 1.2769 + int destPitch = surface->pitch; 1.2770 + u8 *src = pix; 1.2771 + u8 *dest = (u8*)surface->pixels; 1.2772 + int i; 1.2773 + u32 *stretcher = (u32 *)sdlStretcher; 1.2774 + if(systemColorDepth == 16) 1.2775 + src += srcPitch; 1.2776 + int option = sizeOption; 1.2777 + if(yuv) 1.2778 + option = 0; 1.2779 + switch(sizeOption) { 1.2780 + case 0: 1.2781 + for(i = 0; i < srcHeight; i++) { 1.2782 + SDL_CALL_STRETCHER; 1.2783 + src += srcPitch; 1.2784 + dest += destPitch; 1.2785 + } 1.2786 + break; 1.2787 + case 1: 1.2788 + for(i = 0; i < srcHeight; i++) { 1.2789 + SDL_CALL_STRETCHER; 1.2790 + dest += destPitch; 1.2791 + SDL_CALL_STRETCHER; 1.2792 + src += srcPitch; 1.2793 + dest += destPitch; 1.2794 + } 1.2795 + break; 1.2796 + case 2: 1.2797 + for(i = 0; i < srcHeight; i++) { 1.2798 + SDL_CALL_STRETCHER; 1.2799 + dest += destPitch; 1.2800 + SDL_CALL_STRETCHER; 1.2801 + dest += destPitch; 1.2802 + SDL_CALL_STRETCHER; 1.2803 + src += srcPitch; 1.2804 + dest += destPitch; 1.2805 + } 1.2806 + break; 1.2807 + case 3: 1.2808 + for(i = 0; i < srcHeight; i++) { 1.2809 + SDL_CALL_STRETCHER; 1.2810 + dest += destPitch; 1.2811 + SDL_CALL_STRETCHER; 1.2812 + dest += destPitch; 1.2813 + SDL_CALL_STRETCHER; 1.2814 + dest += destPitch; 1.2815 + SDL_CALL_STRETCHER; 1.2816 + src += srcPitch; 1.2817 + dest += destPitch; 1.2818 + } 1.2819 + break; 1.2820 + } 1.2821 + } 1.2822 + 1.2823 + if(showSpeed && fullscreen) { 1.2824 + char buffer[50]; 1.2825 + if(showSpeed == 1) 1.2826 + sprintf(buffer, "%d%%", systemSpeed); 1.2827 + else 1.2828 + sprintf(buffer, "%3d%%(%d, %d fps)", systemSpeed, 1.2829 + systemFrameSkip, 1.2830 + showRenderedFrames); 1.2831 + if(showSpeedTransparent) 1.2832 + drawTextTransp((u8*)surface->pixels, 1.2833 + surface->pitch, 1.2834 + 10, 1.2835 + surface->h-20, 1.2836 + buffer); 1.2837 + else 1.2838 + drawText((u8*)surface->pixels, 1.2839 + surface->pitch, 1.2840 + 10, 1.2841 + surface->h-20, 1.2842 + buffer); 1.2843 + } 1.2844 + 1.2845 + SDL_UnlockSurface(surface); 1.2846 + // SDL_UpdateRect(surface, 0, 0, destWidth, destHeight); 1.2847 + SDL_Flip(surface); 1.2848 +} 1.2849 + 1.2850 +bool systemReadJoypads() 1.2851 +{ 1.2852 + return true; 1.2853 +} 1.2854 + 1.2855 +// Kludge to make Lua call the right function. 1.2856 +u32 systemGetOriginalJoypad(int which, bool sensor){ 1.2857 + return systemGetJoypad(which,sensor); 1.2858 +} 1.2859 + 1.2860 +u32 systemGetJoypad(int which, bool sensor) 1.2861 +{ 1.2862 + sensorOn = sensor; 1.2863 + if(which < 0 || which > 3) 1.2864 + which = sdlDefaultJoypad; 1.2865 + 1.2866 + //VBAMovieUpdate(which); 1.2867 + //VBAMovieUpdateState(); 1.2868 + u32 res = 0; 1.2869 + 1.2870 + //----------------------------// 1.2871 + if (VBAMoviePlaying()){ 1.2872 + // VBAMovieRead() overwrites currentButtons[i] 1.2873 + VBAMovieRead(which, sensor); 1.2874 + res = currentButtons[which]; 1.2875 + return res; 1.2876 + } 1.2877 + //---------------------------// 1.2878 + //Temporary implementation, not sure if it's correct --Felipe 1.2879 + 1.2880 + /* 1.2881 + if(sdlButtons[which][KEY_BUTTON_A]) 1.2882 + res |= BUTTON_MASK_A; 1.2883 + if(sdlButtons[which][KEY_BUTTON_B]) 1.2884 + res |= BUTTON_MASK_B; 1.2885 + if(sdlButtons[which][KEY_BUTTON_SELECT]) 1.2886 + res |= BUTTON_MASK_SELECT; 1.2887 + if(sdlButtons[which][KEY_BUTTON_START]) 1.2888 + res |= BUTTON_MASK_START; 1.2889 + if(sdlButtons[which][KEY_RIGHT]) 1.2890 + res |= BUTTON_MASK_RIGHT; 1.2891 + if(sdlButtons[which][KEY_LEFT]) 1.2892 + res |= BUTTON_MASK_LEFT; 1.2893 + if(sdlButtons[which][KEY_UP]) 1.2894 + res |= BUTTON_MASK_UP; 1.2895 + if(sdlButtons[which][KEY_DOWN]) 1.2896 + res |= BUTTON_MASK_DOWN; 1.2897 + if(sdlButtons[which][KEY_BUTTON_R]) 1.2898 + res |= BUTTON_MASK_R; 1.2899 + if(sdlButtons[which][KEY_BUTTON_L]) 1.2900 + res |= BUTTON_MASK_L; 1.2901 + */ 1.2902 +/* 1.2903 + // disallow L+R or U+D of being pressed at the same time 1.2904 + if((res & 48) == 48) 1.2905 + res &= ~16; 1.2906 + if((res & 192) == 192) 1.2907 + res &= ~128; 1.2908 +*/ 1.2909 +/* 1.2910 + if(sdlbuttons[which][KEY_BUTTON_SPEED]) 1.2911 + res |= 1024; 1.2912 + if(sdlButtons[which][KEY_BUTTON_CAPTURE]) 1.2913 + res |= 2048; 1.2914 +*/ 1.2915 + res = currentButtons[which]; 1.2916 + 1.2917 + if(autoFire) { 1.2918 + res &= (~autoFire); 1.2919 + if(autoFireToggle) 1.2920 + res |= autoFire; 1.2921 + autoFireToggle = !autoFireToggle; 1.2922 + } 1.2923 + 1.2924 + //if (res) fprintf(stdout,"%x\n",res); 1.2925 + 1.2926 + return res; 1.2927 +} 1.2928 + 1.2929 +void systemSetJoypad(int which, u32 buttons) 1.2930 +{ 1.2931 + if(which < 0 || which > 3) 1.2932 + which = sdlDefaultJoypad; 1.2933 +/* 1.2934 + sdlButtons[which][KEY_BUTTON_A] = (buttons & 1) != 0; 1.2935 + sdlButtons[which][KEY_BUTTON_B] = (buttons & 2) != 0; 1.2936 + sdlButtons[which][KEY_BUTTON_SELECT] = (buttons & 4) != 0; 1.2937 + sdlButtons[which][KEY_BUTTON_START] = (buttons & 8) != 0; 1.2938 + sdlButtons[which][KEY_RIGHT] = (buttons & 16) != 0; 1.2939 + sdlButtons[which][KEY_LEFT] = (buttons & 32) != 0; 1.2940 + sdlButtons[which][KEY_UP] = (buttons & 64) != 0; 1.2941 + sdlButtons[which][KEY_DOWN] = (buttons & 128) != 0; 1.2942 + sdlButtons[which][KEY_BUTTON_R] = (buttons & 256) != 0; 1.2943 + sdlButtons[which][KEY_BUTTON_L] = (buttons & 512) != 0; 1.2944 +*/ 1.2945 + currentButtons[which]= buttons & 0x3ff; 1.2946 +} 1.2947 + 1.2948 +void systemClearJoypads() 1.2949 +{ 1.2950 + for (int i = 0; i < 4; ++i) 1.2951 + currentButtons[i] = 0; 1.2952 + 1.2953 + //lastKeys = 0; 1.2954 +} 1.2955 + 1.2956 +void systemSetTitle(const char *title) 1.2957 +{ 1.2958 + SDL_WM_SetCaption(title, NULL); 1.2959 +} 1.2960 + 1.2961 +void systemShowSpeed(int speed) 1.2962 +{ 1.2963 + systemSpeed = speed; 1.2964 + 1.2965 + showRenderedFrames = renderedFrames; 1.2966 + renderedFrames = 0; 1.2967 + 1.2968 + if(!fullscreen && showSpeed) { 1.2969 + char buffer[80]; 1.2970 + if(showSpeed == 1) 1.2971 + sprintf(buffer, "VisualBoyAdvance-%3d%%", systemSpeed); 1.2972 + else 1.2973 + sprintf(buffer, "VisualBoyAdvance-%3d%%(%d, %d fps)", systemSpeed, 1.2974 + systemFrameSkip, 1.2975 + showRenderedFrames); 1.2976 + 1.2977 + systemSetTitle(buffer); 1.2978 + } 1.2979 +} 1.2980 + 1.2981 +// FIXME: the timing 1.2982 +void systemFrame(/*int rate*/) //Looking at System.cpp, it looks like rate should be 600 1.2983 +{ 1.2984 + u32 time = systemGetClock(); 1.2985 + if(!wasPaused && autoFrameSkip && !throttle) { 1.2986 + u32 diff = time - autoFrameSkipLastTime; 1.2987 + int speed = 100; 1.2988 + 1.2989 + if(diff) 1.2990 + speed = (1000000/600)/diff; 1.2991 + 1.2992 + if(speed >= 98) { 1.2993 + frameskipadjust++; 1.2994 + 1.2995 + if(frameskipadjust >= 3) { 1.2996 + frameskipadjust=0; 1.2997 + if(systemFrameSkip > 0) 1.2998 + systemFrameSkip--; 1.2999 + } 1.3000 + } else { 1.3001 + if(speed < 80) 1.3002 + frameskipadjust -= (90 - speed)/5; 1.3003 + else if(systemFrameSkip < 9) 1.3004 + frameskipadjust--; 1.3005 + 1.3006 + if(frameskipadjust <= -2) { 1.3007 + frameskipadjust += 2; 1.3008 + if(systemFrameSkip < 9) 1.3009 + systemFrameSkip++; 1.3010 + } 1.3011 + } 1.3012 + } 1.3013 + if(!wasPaused && throttle) { 1.3014 + /*if(!speedup) { 1.3015 + u32 diff = time - throttleLastTime; 1.3016 + 1.3017 + int target = (1000000.0/(600*throttle)); 1.3018 + int d = (target - diff); 1.3019 + 1.3020 + if(d > 0) { 1.3021 + SDL_Delay(d); 1.3022 + } 1.3023 + } 1.3024 + throttleLastTime = systemGetClock(); 1.3025 + */ 1.3026 + } 1.3027 + if(rewindMemory) { 1.3028 + if(++rewindCounter >= rewindTimer) { 1.3029 + rewindSaveNeeded = true; 1.3030 + rewindCounter = 0; 1.3031 + } 1.3032 + } 1.3033 + 1.3034 + if(systemSaveUpdateCounter) { 1.3035 + if(--systemSaveUpdateCounter <= SYSTEM_SAVE_NOT_UPDATED) { 1.3036 + sdlWriteBattery(); 1.3037 + systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; 1.3038 + } 1.3039 + } 1.3040 + 1.3041 + wasPaused = false; 1.3042 + autoFrameSkipLastTime = time; 1.3043 +} 1.3044 + 1.3045 +int systemFramesToSkip(){ 1.3046 + return systemFrameSkip; 1.3047 +} 1.3048 + 1.3049 +int systemScreenCapture(int a) 1.3050 +{ 1.3051 + char buffer[2048]; 1.3052 + 1.3053 + if(captureFormat) { 1.3054 + if(captureDir[0]) 1.3055 + sprintf(buffer, "%s/%s%02d.bmp", captureDir, sdlGetFilename(filename), a); 1.3056 + else 1.3057 + sprintf(buffer, "%s%02d.bmp", filename, a); 1.3058 + 1.3059 + theEmulator.emuWriteBMP(buffer); 1.3060 + } else { 1.3061 + if(captureDir[0]) 1.3062 + sprintf(buffer, "%s/%s%02d.png", captureDir, sdlGetFilename(filename), a); 1.3063 + else 1.3064 + sprintf(buffer, "%s%02d.png", filename, a); 1.3065 + theEmulator.emuWritePNG(buffer); 1.3066 + } 1.3067 + 1.3068 + systemScreenMessage("Screen capture"); 1.3069 + return a; 1.3070 +} 1.3071 + 1.3072 +void soundCallback(void *,u8 *stream,int len){} 1.3073 + 1.3074 +void systemSoundWriteToBuffer(){ 1.3075 + soundDriver->write(soundFinalWave, soundBufferLen); 1.3076 +} 1.3077 + 1.3078 +void systemSoundClearBuffer() 1.3079 +{ 1.3080 + SDL_mutexP(mutex); 1.3081 + memset(sdlBuffer,0,soundBufferTotalLen); 1.3082 + sdlSoundLen=0; 1.3083 + printf("Hi\n"); 1.3084 + SDL_mutexV(mutex); 1.3085 +} 1.3086 + 1.3087 +bool systemSoundInit(){ 1.3088 + systemSoundShutdown(); 1.3089 + soundDriver = new SoundSDL(); 1.3090 + if ( !soundDriver ) 1.3091 + return false; 1.3092 + 1.3093 + if (!soundDriver->init()) //<-- sound sample rate 1.3094 + return false; 1.3095 + 1.3096 + if (!(soundDriver->setThrottle(throttle))){ 1.3097 + fprintf(stderr,"Failed to set desired throttle, defaulting to 100 %%.\n"); 1.3098 + if (!soundDriver->setThrottle(100)) return false; 1.3099 + } 1.3100 + soundPaused = true; 1.3101 + systemSoundOn = true; 1.3102 + return true; 1.3103 +} 1.3104 + 1.3105 +void systemSoundShutdown(){ 1.3106 + if (soundDriver) 1.3107 + { 1.3108 + delete soundDriver; 1.3109 + soundDriver = 0; 1.3110 + } 1.3111 +} 1.3112 + 1.3113 +void systemSoundPause() 1.3114 +{ 1.3115 + SDL_PauseAudio(1); 1.3116 +} 1.3117 + 1.3118 +void systemSoundResume() 1.3119 +{ 1.3120 + SDL_PauseAudio(0); 1.3121 +} 1.3122 + 1.3123 +void systemSoundReset() 1.3124 +{ 1.3125 +} 1.3126 + 1.3127 +u32 systemGetClock() 1.3128 +{ 1.3129 + return SDL_GetTicks(); 1.3130 +} 1.3131 + 1.3132 +void systemUpdateMotionSensor() 1.3133 +{ 1.3134 + if(sdlMotionButtons[KEY_LEFT]) { 1.3135 + sensorX += 3; 1.3136 + if(sensorX > 2197) 1.3137 + sensorX = 2197; 1.3138 + if(sensorX < 2047) 1.3139 + sensorX = 2057; 1.3140 + } else if(sdlMotionButtons[KEY_RIGHT]) { 1.3141 + sensorX -= 3; 1.3142 + if(sensorX < 1897) 1.3143 + sensorX = 1897; 1.3144 + if(sensorX > 2047) 1.3145 + sensorX = 2037; 1.3146 + } else if(sensorX > 2047) { 1.3147 + sensorX -= 2; 1.3148 + if(sensorX < 2047) 1.3149 + sensorX = 2047; 1.3150 + } else { 1.3151 + sensorX += 2; 1.3152 + if(sensorX > 2047) 1.3153 + sensorX = 2047; 1.3154 + } 1.3155 + 1.3156 + if(sdlMotionButtons[KEY_UP]) { 1.3157 + sensorY += 3; 1.3158 + if(sensorY > 2197) 1.3159 + sensorY = 2197; 1.3160 + if(sensorY < 2047) 1.3161 + sensorY = 2057; 1.3162 + } else if(sdlMotionButtons[KEY_DOWN]) { 1.3163 + sensorY -= 3; 1.3164 + if(sensorY < 1897) 1.3165 + sensorY = 1897; 1.3166 + if(sensorY > 2047) 1.3167 + sensorY = 2037; 1.3168 + } else if(sensorY > 2047) { 1.3169 + sensorY -= 2; 1.3170 + if(sensorY < 2047) 1.3171 + sensorY = 2047; 1.3172 + } else { 1.3173 + sensorY += 2; 1.3174 + if(sensorY > 2047) 1.3175 + sensorY = 2047; 1.3176 + } 1.3177 +} 1.3178 + 1.3179 +void systemResetSensor() 1.3180 +{ 1.3181 + sensorX = sensorY = INITIAL_SENSOR_VALUE; 1.3182 +} 1.3183 + 1.3184 +int systemGetSensorX() 1.3185 +{ 1.3186 + return sensorX; 1.3187 +} 1.3188 + 1.3189 +int systemGetSensorY() 1.3190 +{ 1.3191 + return sensorY; 1.3192 +} 1.3193 + 1.3194 +void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast) 1.3195 +{ 1.3196 +} 1.3197 + 1.3198 +void systemScreenMessage(const char *msg, int slot, int duration, const char *colorList) 1.3199 +{ 1.3200 + screenMessage[slot] = true; 1.3201 + screenMessageTime[slot] = systemGetClock(); 1.3202 + screenMessageDuration[slot] = duration; 1.3203 + if(strlen(msg) > 20) { 1.3204 + strncpy(screenMessageBuffer[slot], msg, 20); 1.3205 + screenMessageBuffer[slot][20] = 0; 1.3206 + } else 1.3207 + strcpy(screenMessageBuffer[slot], msg); 1.3208 +} 1.3209 + 1.3210 +bool systemSoundCanChangeQuality() 1.3211 +{ 1.3212 + return false; 1.3213 +} 1.3214 + 1.3215 +bool systemSoundSetQuality(int quality) 1.3216 +{ 1.3217 + if (systemCartridgeType == 0) 1.3218 + soundSetQuality(quality); 1.3219 + else 1.3220 + gbSoundSetQuality(quality); 1.3221 + 1.3222 + return true; 1.3223 +} 1.3224 + 1.3225 +bool systemPauseOnFrame() 1.3226 +{ 1.3227 + if(pauseNextFrame) { 1.3228 + paused = true; 1.3229 + pauseNextFrame = false; 1.3230 + return true; 1.3231 + } 1.3232 + return false; 1.3233 +} 1.3234 + 1.3235 +// Code donated by Niels Wagenaar (BoycottAdvance) 1.3236 + 1.3237 +// GBA screensize. 1.3238 +#define GBA_WIDTH 240 1.3239 +#define GBA_HEIGHT 160 1.3240 + 1.3241 +void Init_Overlay(SDL_Surface *gbascreen, int overlaytype) 1.3242 +{ 1.3243 + 1.3244 + overlay = SDL_CreateYUVOverlay( GBA_WIDTH, 1.3245 + GBA_HEIGHT, 1.3246 + overlaytype, gbascreen); 1.3247 + fprintf(stderr, "Created %dx%dx%d %s %s overlay\n", 1.3248 + overlay->w,overlay->h,overlay->planes, 1.3249 + overlay->hw_overlay?"hardware":"software", 1.3250 + overlay->format==SDL_YV12_OVERLAY?"YV12": 1.3251 + overlay->format==SDL_IYUV_OVERLAY?"IYUV": 1.3252 + overlay->format==SDL_YUY2_OVERLAY?"YUY2": 1.3253 + overlay->format==SDL_UYVY_OVERLAY?"UYVY": 1.3254 + overlay->format==SDL_YVYU_OVERLAY?"YVYU": 1.3255 + "Unknown"); 1.3256 +} 1.3257 + 1.3258 +void Quit_Overlay(void) 1.3259 +{ 1.3260 + 1.3261 + SDL_FreeYUVOverlay(overlay); 1.3262 +} 1.3263 + 1.3264 +/* NOTE: These RGB conversion functions are not intended for speed, 1.3265 + only as examples. 1.3266 +*/ 1.3267 +inline void RGBtoYUV(Uint8 *rgb, int *yuv) 1.3268 +{ 1.3269 + yuv[0] = (int)((0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16); 1.3270 + yuv[1] = (int)(128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2])); 1.3271 + yuv[2] = (int)(128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2])); 1.3272 +} 1.3273 + 1.3274 +inline void ConvertRGBtoYV12(SDL_Overlay *o) 1.3275 +{ 1.3276 + int x,y; 1.3277 + int yuv[3]; 1.3278 + Uint8 *p,*op[3]; 1.3279 + 1.3280 + SDL_LockYUVOverlay(o); 1.3281 + 1.3282 + /* Black initialization */ 1.3283 + /* 1.3284 + memset(o->pixels[0],0,o->pitches[0]*o->h); 1.3285 + memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2)); 1.3286 + memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2)); 1.3287 + */ 1.3288 + 1.3289 + /* Convert */ 1.3290 + for(y=0; y<160 && y<o->h; y++) { 1.3291 + p=(Uint8 *)pix+srcPitch*y; 1.3292 + op[0]=o->pixels[0]+o->pitches[0]*y; 1.3293 + op[1]=o->pixels[1]+o->pitches[1]*(y/2); 1.3294 + op[2]=o->pixels[2]+o->pitches[2]*(y/2); 1.3295 + for(x=0; x<240 && x<o->w; x++) { 1.3296 + RGBtoYUV(p,yuv); 1.3297 + *(op[0]++)=yuv[0]; 1.3298 + if(x%2==0 && y%2==0) { 1.3299 + *(op[1]++)=yuv[2]; 1.3300 + *(op[2]++)=yuv[1]; 1.3301 + } 1.3302 + p+=4;//s->format->BytesPerPixel; 1.3303 + } 1.3304 + } 1.3305 + 1.3306 + SDL_UnlockYUVOverlay(o); 1.3307 +} 1.3308 + 1.3309 +inline void ConvertRGBtoIYUV(SDL_Overlay *o) 1.3310 +{ 1.3311 + int x,y; 1.3312 + int yuv[3]; 1.3313 + Uint8 *p,*op[3]; 1.3314 + 1.3315 + SDL_LockYUVOverlay(o); 1.3316 + 1.3317 + /* Black initialization */ 1.3318 + /* 1.3319 + memset(o->pixels[0],0,o->pitches[0]*o->h); 1.3320 + memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2)); 1.3321 + memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2)); 1.3322 + */ 1.3323 + 1.3324 + /* Convert */ 1.3325 + for(y=0; y<160 && y<o->h; y++) { 1.3326 + p=(Uint8 *)pix+srcPitch*y; 1.3327 + op[0]=o->pixels[0]+o->pitches[0]*y; 1.3328 + op[1]=o->pixels[1]+o->pitches[1]*(y/2); 1.3329 + op[2]=o->pixels[2]+o->pitches[2]*(y/2); 1.3330 + for(x=0; x<240 && x<o->w; x++) { 1.3331 + RGBtoYUV(p,yuv); 1.3332 + *(op[0]++)=yuv[0]; 1.3333 + if(x%2==0 && y%2==0) { 1.3334 + *(op[1]++)=yuv[1]; 1.3335 + *(op[2]++)=yuv[2]; 1.3336 + } 1.3337 + p+=4; //s->format->BytesPerPixel; 1.3338 + } 1.3339 + } 1.3340 + 1.3341 + SDL_UnlockYUVOverlay(o); 1.3342 +} 1.3343 + 1.3344 +inline void ConvertRGBtoUYVY(SDL_Overlay *o) 1.3345 +{ 1.3346 + int x,y; 1.3347 + int yuv[3]; 1.3348 + Uint8 *p,*op; 1.3349 + 1.3350 + SDL_LockYUVOverlay(o); 1.3351 + 1.3352 + for(y=0; y<160 && y<o->h; y++) { 1.3353 + p=(Uint8 *)pix+srcPitch*y; 1.3354 + op=o->pixels[0]+o->pitches[0]*y; 1.3355 + for(x=0; x<240 && x<o->w; x++) { 1.3356 + RGBtoYUV(p,yuv); 1.3357 + if(x%2==0) { 1.3358 + *(op++)=yuv[1]; 1.3359 + *(op++)=yuv[0]; 1.3360 + *(op++)=yuv[2]; 1.3361 + } else 1.3362 + *(op++)=yuv[0]; 1.3363 + 1.3364 + p+=4; //s->format->BytesPerPixel; 1.3365 + } 1.3366 + } 1.3367 + 1.3368 + SDL_UnlockYUVOverlay(o); 1.3369 +} 1.3370 + 1.3371 +inline void ConvertRGBtoYVYU(SDL_Overlay *o) 1.3372 +{ 1.3373 + int x,y; 1.3374 + int yuv[3]; 1.3375 + Uint8 *p,*op; 1.3376 + 1.3377 + SDL_LockYUVOverlay(o); 1.3378 + 1.3379 + for(y=0; y<160 && y<o->h; y++) { 1.3380 + p=(Uint8 *)pix+srcPitch*y; 1.3381 + op=o->pixels[0]+o->pitches[0]*y; 1.3382 + for(x=0; x<240 && x<o->w; x++) { 1.3383 + RGBtoYUV(p,yuv); 1.3384 + if(x%2==0) { 1.3385 + *(op++)=yuv[0]; 1.3386 + *(op++)=yuv[2]; 1.3387 + op[1]=yuv[1]; 1.3388 + } else { 1.3389 + *op=yuv[0]; 1.3390 + op+=2; 1.3391 + } 1.3392 + 1.3393 + p+=4; //s->format->BytesPerPixel; 1.3394 + } 1.3395 + } 1.3396 + 1.3397 + SDL_UnlockYUVOverlay(o); 1.3398 +} 1.3399 + 1.3400 +inline void ConvertRGBtoYUY2(SDL_Overlay *o) 1.3401 +{ 1.3402 + int x,y; 1.3403 + int yuv[3]; 1.3404 + Uint8 *p,*op; 1.3405 + 1.3406 + SDL_LockYUVOverlay(o); 1.3407 + 1.3408 + for(y=0; y<160 && y<o->h; y++) { 1.3409 + p=(Uint8 *)pix+srcPitch*y; 1.3410 + op=o->pixels[0]+o->pitches[0]*y; 1.3411 + for(x=0; x<240 && x<o->w; x++) { 1.3412 + RGBtoYUV(p,yuv); 1.3413 + if(x%2==0) { 1.3414 + *(op++)=yuv[0]; 1.3415 + *(op++)=yuv[1]; 1.3416 + op[1]=yuv[2]; 1.3417 + } else { 1.3418 + *op=yuv[0]; 1.3419 + op+=2; 1.3420 + } 1.3421 + 1.3422 + p+=4; //s->format->BytesPerPixel; 1.3423 + } 1.3424 + } 1.3425 + 1.3426 + SDL_UnlockYUVOverlay(o); 1.3427 +} 1.3428 + 1.3429 +inline void Convert32bit(SDL_Surface *display) 1.3430 +{ 1.3431 + switch(overlay->format) { 1.3432 + case SDL_YV12_OVERLAY: 1.3433 + ConvertRGBtoYV12(overlay); 1.3434 + break; 1.3435 + case SDL_UYVY_OVERLAY: 1.3436 + ConvertRGBtoUYVY(overlay); 1.3437 + break; 1.3438 + case SDL_YVYU_OVERLAY: 1.3439 + ConvertRGBtoYVYU(overlay); 1.3440 + break; 1.3441 + case SDL_YUY2_OVERLAY: 1.3442 + ConvertRGBtoYUY2(overlay); 1.3443 + break; 1.3444 + case SDL_IYUV_OVERLAY: 1.3445 + ConvertRGBtoIYUV(overlay); 1.3446 + break; 1.3447 + default: 1.3448 + fprintf(stderr, "cannot convert RGB picture to obtained YUV format!\n"); 1.3449 + exit(1); 1.3450 + break; 1.3451 + } 1.3452 + 1.3453 +} 1.3454 + 1.3455 + 1.3456 +inline void Draw_Overlay(SDL_Surface *display, int size) 1.3457 +{ 1.3458 + SDL_LockYUVOverlay(overlay); 1.3459 + 1.3460 + Convert32bit(display); 1.3461 + 1.3462 + overlay_rect.x = 0; 1.3463 + overlay_rect.y = 0; 1.3464 + overlay_rect.w = GBA_WIDTH * size; 1.3465 + overlay_rect.h = GBA_HEIGHT * size; 1.3466 + 1.3467 + SDL_DisplayYUVOverlay(overlay, &overlay_rect); 1.3468 + SDL_UnlockYUVOverlay(overlay); 1.3469 +} 1.3470 + 1.3471 +bool systemIsEmulating() 1.3472 +{ 1.3473 + return emulating != 0; 1.3474 +} 1.3475 + 1.3476 +void systemGbBorderOn() 1.3477 +{ 1.3478 + srcWidth = 256; 1.3479 + srcHeight = 224; 1.3480 + gbBorderLineSkip = 256; 1.3481 + gbBorderColumnSkip = 48; 1.3482 + gbBorderRowSkip = 40; 1.3483 + 1.3484 + destWidth = (sizeOption+1)*srcWidth; 1.3485 + destHeight = (sizeOption+1)*srcHeight; 1.3486 + 1.3487 + surface = SDL_SetVideoMode(destWidth, destHeight, 16, 1.3488 + SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF| 1.3489 + (fullscreen ? SDL_FULLSCREEN : 0)); 1.3490 +#ifndef C_CORE 1.3491 + sdlMakeStretcher(srcWidth); 1.3492 +#else 1.3493 + switch(systemColorDepth) { 1.3494 + case 16: 1.3495 + sdlStretcher = sdlStretcher16[sizeOption]; 1.3496 + break; 1.3497 + case 24: 1.3498 + sdlStretcher = sdlStretcher24[sizeOption]; 1.3499 + break; 1.3500 + case 32: 1.3501 + sdlStretcher = sdlStretcher32[sizeOption]; 1.3502 + break; 1.3503 + default: 1.3504 + fprintf(stderr, "Unsupported resolution: %d\n", systemColorDepth); 1.3505 + exit(-1); 1.3506 + } 1.3507 +#endif 1.3508 + 1.3509 + if(systemColorDepth == 16) { 1.3510 + if(sdlCalculateMaskWidth(surface->format->Gmask) == 6) { 1.3511 + Init_2xSaI(565); 1.3512 + RGB_LOW_BITS_MASK = 0x821; 1.3513 + } else { 1.3514 + Init_2xSaI(555); 1.3515 + RGB_LOW_BITS_MASK = 0x421; 1.3516 + } 1.3517 + if(systemCartridgeType == 2) { 1.3518 + for(int i = 0; i < 0x10000; i++) { 1.3519 + systemColorMap16[i] = (((i >> 1) & 0x1f) << systemBlueShift) | 1.3520 + (((i & 0x7c0) >> 6) << systemGreenShift) | 1.3521 + (((i & 0xf800) >> 11) << systemRedShift); 1.3522 + } 1.3523 + } else { 1.3524 + for(int i = 0; i < 0x10000; i++) { 1.3525 + systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | 1.3526 + (((i & 0x3e0) >> 5) << systemGreenShift) | 1.3527 + (((i & 0x7c00) >> 10) << systemBlueShift); 1.3528 + } 1.3529 + } 1.3530 + srcPitch = srcWidth * 2+4; 1.3531 + } else { 1.3532 + if(systemColorDepth != 32) 1.3533 + filterFunction = NULL; 1.3534 + RGB_LOW_BITS_MASK = 0x010101; 1.3535 + if(systemColorDepth == 32) { 1.3536 + Init_2xSaI(32); 1.3537 + } 1.3538 + for(int i = 0; i < 0x10000; i++) { 1.3539 + systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | 1.3540 + (((i & 0x3e0) >> 5) << systemGreenShift) | 1.3541 + (((i & 0x7c00) >> 10) << systemBlueShift); 1.3542 + } 1.3543 + if(systemColorDepth == 32) 1.3544 + srcPitch = srcWidth*4 + 4; 1.3545 + else 1.3546 + srcPitch = srcWidth*3; 1.3547 + } 1.3548 +} 1.3549 + 1.3550 +bool systemIsRunningGBA() 1.3551 +{ 1.3552 + return (rom != NULL); 1.3553 +} 1.3554 + 1.3555 +int systemGetDefaultJoypad() 1.3556 +{ 1.3557 + return sdlDefaultJoypad; 1.3558 +} 1.3559 + 1.3560 +bool systemIsPaused() 1.3561 +{ 1.3562 + return paused; 1.3563 +} 1.3564 + 1.3565 +void systemSetPause(bool pause) 1.3566 +{ 1.3567 + paused = pause; 1.3568 + if (pause) 1.3569 + systemSoundPause(); 1.3570 + else 1.3571 + systemSoundResume(); 1.3572 +} 1.3573 + 1.3574 +u16 checksumBIOS() 1.3575 +{ 1.3576 + bool hasBIOS = false; 1.3577 + u8 * tempBIOS; 1.3578 + if(useBios) 1.3579 + { 1.3580 + tempBIOS = (u8 *)malloc(0x4000); 1.3581 + int size = 0x4000; 1.3582 + if(utilLoad(biosFileName, 1.3583 + utilIsGBABios, 1.3584 + tempBIOS, 1.3585 + size)) { 1.3586 + if(size == 0x4000) 1.3587 + hasBIOS = true; 1.3588 + } 1.3589 + } 1.3590 + 1.3591 + u16 biosCheck = 0; 1.3592 + if(hasBIOS) { 1.3593 + for(int i = 0; i < 0x4000; i += 4) 1.3594 + biosCheck += *((u32 *)&tempBIOS[i]); 1.3595 + free(tempBIOS); 1.3596 + } 1.3597 + 1.3598 + return biosCheck; 1.3599 +} 1.3600 + 1.3601 +EmulatedSystemCounters systemCounters = { 1.3602 + 0, //framecount 1.3603 + 0, //lagcount 1.3604 + 0, //extracount 1.3605 + true, //lagged 1.3606 + true //laggedLast 1.3607 +}; 1.3608 + 1.3609 +void VBAOnEnteringFrameBoundary() 1.3610 +{ 1.3611 + CallRegisteredLuaFunctions(LUACALL_AFTEREMULATION); 1.3612 + 1.3613 + if (VBALuaRunning()) 1.3614 + { 1.3615 + VBALuaFrameBoundary(); 1.3616 + } 1.3617 + 1.3618 + VBAMovieUpdateState(); 1.3619 +} 1.3620 + 1.3621 +void VBAOnExitingFrameBoundary() 1.3622 +{ 1.3623 + ; 1.3624 +} 1.3625 + 1.3626 +