rlm@1: // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. rlm@1: // Copyright (C) 1999-2003 Forgotten rlm@1: // Copyright (C) 2004 Forgotten and the VBA development team rlm@1: rlm@1: // This program is free software; you can redistribute it and/or modify rlm@1: // it under the terms of the GNU General Public License as published by rlm@1: // the Free Software Foundation; either version 2, or(at your option) rlm@1: // any later version. rlm@1: // rlm@1: // This program is distributed in the hope that it will be useful, rlm@1: // but WITHOUT ANY WARRANTY; without even the implied warranty of rlm@1: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the rlm@1: // GNU General Public License for more details. rlm@1: // rlm@1: // You should have received a copy of the GNU General Public License rlm@1: // along with this program; if not, write to the Free Software Foundation, rlm@1: // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. rlm@1: rlm@1: #include rlm@1: #include rlm@1: #include rlm@1: #include rlm@1: #include rlm@1: #include rlm@30: #include rlm@1: #include "AutoBuild.h" rlm@1: rlm@1: #include "Port.h" rlm@1: #include "SDL.h" rlm@1: #include "debugger.h" rlm@1: #include "gba/GBA.h" rlm@1: #include "gba/GBAGlobals.h" rlm@1: #include "gba/agbprint.h" rlm@1: #include "gba/Flash.h" rlm@1: #include "gba/RTC.h" rlm@1: #include "gba/GBASound.h" rlm@1: #include "gb/GB.h" rlm@1: #include "gb/gbGlobals.h" rlm@1: #include "common/Text.h" rlm@1: #include "common/unzip.h" rlm@1: #include "common/Util.h" rlm@1: #include "common/movie.h" rlm@1: #include "common/System.h" rlm@1: #include "common/inputGlobal.h" rlm@1: #include "../common/vbalua.h" rlm@1: #include "SoundSDL.h" rlm@49: #include "Drive.h" rlm@1: rlm@1: #define GBC_CAPABLE ((gbRom[0x143] & 0x80) != 0) rlm@1: #define SGB_CAPABLE (gbRom[0x146] == 0x03) rlm@1: rlm@1: #ifndef WIN32 rlm@1: # include rlm@1: # define GETCWD getcwd rlm@1: #else // WIN32 rlm@1: # include rlm@1: # define GETCWD _getcwd rlm@1: #endif // WIN32 rlm@1: rlm@1: #ifndef __GNUC__ rlm@1: # define HAVE_DECL_GETOPT 0 rlm@1: # define __STDC__ 1 rlm@1: # include "getopt.h" rlm@1: #else // ! __GNUC__ rlm@1: # define HAVE_DECL_GETOPT 1 rlm@1: # include "getopt.h" rlm@1: #endif // ! __GNUC__ rlm@1: rlm@1: #ifdef MMX rlm@1: extern "C" bool cpu_mmx; rlm@1: #endif rlm@1: extern bool8 soundEcho; rlm@1: extern bool8 soundLowPass; rlm@1: extern bool8 soundReverse; rlm@1: extern int Init_2xSaI(u32); rlm@1: extern void _2xSaI(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void _2xSaI32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void Super2xSaI(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void Super2xSaI32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void SuperEagle(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void SuperEagle32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void Pixelate2x16(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void Pixelate2x32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void MotionBlur(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void MotionBlur32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void AdMame2x(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void AdMame2x32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void Simple2x16(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void Simple2x32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void Bilinear(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void Bilinear32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void BilinearPlus(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void BilinearPlus32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void Scanlines(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void Scanlines32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void ScanlinesTV(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void ScanlinesTV32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void hq2x(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void hq2x32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void lq2x(u8*,u32,u8*,u8*,u32,int,int); rlm@1: extern void lq2x32(u8*,u32,u8*,u8*,u32,int,int); rlm@1: rlm@1: extern void SmartIB(u8*,u32,int,int); rlm@1: extern void SmartIB32(u8*,u32,int,int); rlm@1: extern void MotionBlurIB(u8*,u32,int,int); rlm@1: extern void MotionBlurIB32(u8*,u32,int,int); rlm@1: rlm@1: void Init_Overlay(SDL_Surface *surface, int overlaytype); rlm@1: void Quit_Overlay(void); rlm@1: void Draw_Overlay(SDL_Surface *surface, int size); rlm@1: rlm@1: extern void remoteInit(); rlm@1: extern void remoteCleanUp(); rlm@1: extern void remoteStubMain(); rlm@1: extern void remoteStubSignal(int,int); rlm@1: extern void remoteOutput(char *, u32); rlm@1: extern void remoteSetProtocol(int); rlm@1: extern void remoteSetPort(int); rlm@1: extern void debuggerOutput(char *, u32); rlm@1: rlm@1: extern void CPUUpdateRenderBuffers(bool); rlm@1: rlm@1: struct EmulatedSystem theEmulator = { rlm@1: NULL, rlm@1: NULL, rlm@1: NULL, rlm@1: NULL, rlm@1: NULL, rlm@1: NULL, rlm@1: NULL, rlm@1: NULL, rlm@1: NULL, rlm@1: NULL, rlm@1: NULL, rlm@1: NULL, rlm@1: false, rlm@1: 0 rlm@1: }; rlm@1: rlm@1: SDL_Surface *surface = NULL; rlm@1: SDL_Overlay *overlay = NULL; rlm@1: SDL_Rect overlay_rect; rlm@1: rlm@1: int systemSpeed = 0; rlm@1: int systemRedShift = 0; rlm@1: int systemBlueShift = 0; rlm@1: int systemGreenShift = 0; rlm@1: int systemColorDepth = 0; rlm@1: int systemDebug = 0; rlm@1: int systemVerbose = 0; rlm@1: int systemFrameSkip = 0; rlm@1: int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; rlm@1: rlm@1: int srcPitch = 0; rlm@1: int srcWidth = 0; rlm@1: int srcHeight = 0; rlm@1: int destWidth = 0; rlm@1: int destHeight = 0; rlm@1: rlm@1: int sensorX = 2047; rlm@1: int sensorY = 2047; rlm@1: bool sensorOn = false; rlm@1: rlm@1: int filter = 0; rlm@1: u8 *delta = NULL; rlm@1: rlm@1: int sdlPrintUsage = 0; rlm@1: int disableMMX = 0; rlm@1: rlm@1: int systemCartridgeType = 3; rlm@1: int sizeOption = 0; rlm@1: int captureFormat = 0; rlm@1: int useMovie = 0; rlm@1: rlm@1: int pauseWhenInactive = 0; rlm@1: int active = 1; rlm@1: int emulating = 0; rlm@1: int RGB_LOW_BITS_MASK=0x821; rlm@1: u32 systemColorMap32[0x10000]; rlm@1: u16 systemColorMap16[0x10000]; rlm@1: u16 systemGbPalette[24]; rlm@1: void (*filterFunction)(u8*,u32,u8*,u8*,u32,int,int) = NULL; rlm@1: void (*ifbFunction)(u8*,u32,int,int) = NULL; rlm@1: int ifbType = 0; rlm@1: char filename[2048]; rlm@1: char ipsname[2048]; rlm@1: char biosFileName[2048]; rlm@1: char movieFileName[2048]; rlm@1: char captureDir[2048]; rlm@1: char saveDir[2048]; rlm@1: char batteryDir[2048]; rlm@1: rlm@1: static char *rewindMemory = NULL; rlm@1: static int rewindPos = 0; rlm@1: static int rewindTopPos = 0; rlm@1: static int rewindCounter = 0; rlm@1: static int rewindCount = 0; rlm@1: static bool rewindSaveNeeded = false; rlm@1: static int rewindTimer = 0; rlm@1: rlm@1: #define REWIND_SIZE 400000 rlm@1: rlm@1: #define _stricmp strcasecmp rlm@1: rlm@1: /*bool sdlButtons[4][12] = { rlm@1: { false, false, false, false, false, false, rlm@1: false, false, false, false, false, false }, rlm@1: { false, false, false, false, false, false, rlm@1: false, false, false, false, false, false }, rlm@1: { false, false, false, false, false, false, rlm@1: false, false, false, false, false, false }, rlm@1: { false, false, false, false, false, false, rlm@1: false, false, false, false, false, false } rlm@1: };*/ rlm@1: /* rlm@1: I'm changing the way the SDL GUI handles the button rlm@1: input to match the one in win32, this is needed in rlm@1: order to be compatible with the format required by rlm@1: common/movie.cpp rlm@1: --Felipe rlm@1: */ rlm@1: rlm@1: u16 currentButtons[4] = {0, 0, 0, 0}; rlm@1: rlm@1: bool sdlMotionButtons[4] = { false, false, false, false }; rlm@1: const int32 INITIAL_SENSOR_VALUE = 2047; rlm@1: rlm@1: int sdlNumDevices = 0; rlm@1: SDL_Joystick **sdlDevices = NULL; rlm@1: rlm@1: bool wasPaused = false; rlm@1: int autoFrameSkip = 0; rlm@1: int frameskipadjust = 0; rlm@1: int showRenderedFrames = 0; rlm@1: int renderedFrames = 0; rlm@1: rlm@1: int throttle = 0; rlm@1: u32 throttleLastTime = 0; rlm@1: u32 autoFrameSkipLastTime = 0; rlm@1: rlm@1: int showSpeed = 1; rlm@1: int showSpeedTransparent = 1; rlm@1: bool disableStatusMessages = false; rlm@1: bool paused = false; rlm@1: bool pauseNextFrame = false; rlm@1: bool debugger = false; rlm@1: bool debuggerStub = false; rlm@1: int fullscreen = 0; rlm@1: bool systemSoundOn = false; rlm@1: bool yuv = false; rlm@1: int yuvType = 0; rlm@1: bool removeIntros = false; rlm@1: int sdlFlashSize = 0; rlm@1: int sdlAutoIPS = 1; rlm@1: int sdlRtcEnable = 0; rlm@1: int sdlAgbPrint = 0; rlm@1: rlm@1: int sdlDefaultJoypad = 0; rlm@1: rlm@1: extern void debuggerSignal(int,int); rlm@1: rlm@1: void (*dbgMain)() = debuggerMain; rlm@1: void (*dbgSignal)(int,int) = debuggerSignal; rlm@1: void (*dbgOutput)(char *, u32) = debuggerOutput; rlm@1: rlm@1: int mouseCounter = 0; rlm@1: int autoFire = 0; rlm@1: bool autoFireToggle = false; rlm@1: rlm@1: bool screenMessage[8] = {false,false,false,false,false,false,false,false}; rlm@1: char screenMessageBuffer[8][21]; rlm@1: u32 screenMessageTime[8] = {0,0,0,0,0,0,0,0}; rlm@1: u32 screenMessageDuration[8] = {0,0,0,0,0,0,0,0}; rlm@1: rlm@1: SDL_cond *cond = NULL; rlm@1: SDL_mutex *mutex = NULL; rlm@1: u8* sdlBuffer; rlm@1: int sdlSoundLen = 0; rlm@1: SoundSDL* soundDriver = NULL; rlm@1: rlm@1: char *arg0; rlm@1: rlm@1: #ifndef C_CORE rlm@1: u8 sdlStretcher[16384]; rlm@1: int sdlStretcherPos; rlm@1: #else rlm@1: void (*sdlStretcher)(u8 *, u8*) = NULL; rlm@1: #endif rlm@1: rlm@1: u16 joypad[4][12] = { rlm@1: { SDLK_LEFT, SDLK_RIGHT, rlm@1: SDLK_UP, SDLK_DOWN, rlm@1: SDLK_z, SDLK_x, rlm@1: SDLK_RETURN,SDLK_BACKSPACE, rlm@1: SDLK_a, SDLK_s, rlm@1: SDLK_SPACE, SDLK_F12 rlm@1: }, rlm@1: { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, rlm@1: { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, rlm@1: { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } rlm@1: }; rlm@1: rlm@1: u16 defaultJoypad[12] = { rlm@1: SDLK_LEFT, SDLK_RIGHT, rlm@1: SDLK_UP, SDLK_DOWN, rlm@1: SDLK_z, SDLK_x, rlm@1: SDLK_RETURN,SDLK_BACKSPACE, rlm@1: SDLK_a, SDLK_s, rlm@1: SDLK_SPACE, SDLK_F12 rlm@1: }; rlm@1: rlm@1: u16 motion[4] = { rlm@1: SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2 rlm@1: }; rlm@1: rlm@1: u16 defaultMotion[4] = { rlm@1: SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2 rlm@1: }; rlm@1: rlm@1: struct option sdlOptions[] = { rlm@1: { "agb-print", no_argument, &sdlAgbPrint, 1 }, rlm@1: { "auto-frameskip", no_argument, &autoFrameSkip, 1 }, rlm@1: { "bios", required_argument, 0, 'b' }, rlm@1: { "config", required_argument, 0, 'c' }, rlm@1: { "debug", no_argument, 0, 'd' }, rlm@1: { "filter", required_argument, 0, 'f' }, rlm@1: { "filter-normal", no_argument, &filter, 0 }, rlm@1: { "filter-tv-mode", no_argument, &filter, 1 }, rlm@1: { "filter-2xsai", no_argument, &filter, 2 }, rlm@1: { "filter-super-2xsai", no_argument, &filter, 3 }, rlm@1: { "filter-super-eagle", no_argument, &filter, 4 }, rlm@1: { "filter-pixelate", no_argument, &filter, 5 }, rlm@1: { "filter-motion-blur", no_argument, &filter, 6 }, rlm@1: { "filter-advmame", no_argument, &filter, 7 }, rlm@1: { "filter-simple2x", no_argument, &filter, 8 }, rlm@1: { "filter-bilinear", no_argument, &filter, 9 }, rlm@1: { "filter-bilinear+", no_argument, &filter, 10 }, rlm@1: { "filter-scanlines", no_argument, &filter, 11 }, rlm@1: { "filter-hq2x", no_argument, &filter, 12 }, rlm@1: { "filter-lq2x", no_argument, &filter, 13 }, rlm@1: { "flash-size", required_argument, 0, 'S' }, rlm@1: { "flash-64k", no_argument, &sdlFlashSize, 0 }, rlm@1: { "flash-128k", no_argument, &sdlFlashSize, 1 }, rlm@1: { "frameskip", required_argument, 0, 's' }, rlm@1: { "fullscreen", no_argument, &fullscreen, 1 }, rlm@1: { "gdb", required_argument, 0, 'G' }, rlm@1: { "help", no_argument, &sdlPrintUsage, 1 }, rlm@1: { "ifb-none", no_argument, &ifbType, 0 }, rlm@1: { "ifb-motion-blur", no_argument, &ifbType, 1 }, rlm@1: { "ifb-smart", no_argument, &ifbType, 2 }, rlm@1: { "ips", required_argument, 0, 'i' }, rlm@1: { "no-agb-print", no_argument, &sdlAgbPrint, 0 }, rlm@1: { "no-auto-frameskip", no_argument, &autoFrameSkip, 0 }, rlm@1: { "no-debug", no_argument, 0, 'N' }, rlm@1: { "no-ips", no_argument, &sdlAutoIPS, 0 }, rlm@1: { "no-mmx", no_argument, &disableMMX, 1 }, rlm@1: { "no-pause-when-inactive", no_argument, &pauseWhenInactive, 0 }, rlm@1: { "no-rtc", no_argument, &sdlRtcEnable, 0 }, rlm@1: { "no-show-speed", no_argument, &showSpeed, 0 }, rlm@1: { "no-throttle", no_argument, &throttle, 0 }, rlm@1: { "pause-when-inactive", no_argument, &pauseWhenInactive, 1 }, rlm@1: { "profile", optional_argument, 0, 'P' }, rlm@1: { "rtc", no_argument, &sdlRtcEnable, 1 }, rlm@1: { "save-type", required_argument, 0, 't' }, rlm@1: { "save-auto", no_argument, &cpuSaveType, 0 }, rlm@1: { "save-eeprom", no_argument, &cpuSaveType, 1 }, rlm@1: { "save-sram", no_argument, &cpuSaveType, 2 }, rlm@1: { "save-flash", no_argument, &cpuSaveType, 3 }, rlm@1: { "save-sensor", no_argument, &cpuSaveType, 4 }, rlm@1: { "save-none", no_argument, &cpuSaveType, 5 }, rlm@1: { "show-speed-normal", no_argument, &showSpeed, 1 }, rlm@1: { "show-speed-detailed", no_argument, &showSpeed, 2 }, rlm@1: { "throttle", required_argument, 0, 'T' }, rlm@1: { "verbose", required_argument, 0, 'v' }, rlm@1: { "video-1x", no_argument, &sizeOption, 0 }, rlm@1: { "video-2x", no_argument, &sizeOption, 1 }, rlm@1: { "video-3x", no_argument, &sizeOption, 2 }, rlm@1: { "video-4x", no_argument, &sizeOption, 3 }, rlm@1: { "yuv", required_argument, 0, 'Y' }, rlm@1: { "recordmovie", required_argument, 0, 'r' }, rlm@1: { "playmovie", required_argument, 0, 'p' }, rlm@1: { "watchmovie", required_argument, 0, 'w' }, rlm@1: { NULL, no_argument, NULL, 0 } rlm@1: }; rlm@1: rlm@1: #ifndef C_CORE rlm@1: #define SDL_LONG(val) \ rlm@1: *((u32 *)&sdlStretcher[sdlStretcherPos]) = val;\ rlm@1: sdlStretcherPos+=4; rlm@1: rlm@1: #define SDL_AND_EAX(val) \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x25;\ rlm@1: SDL_LONG(val); rlm@1: rlm@1: #define SDL_AND_EBX(val) \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x81;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xe3;\ rlm@1: SDL_LONG(val); rlm@1: rlm@1: #define SDL_OR_EAX_EBX \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x09;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xd8; rlm@1: rlm@1: #define SDL_LOADL_EBX \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x8b;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x1f; rlm@1: rlm@1: #define SDL_LOADW \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x66;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x8b;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x06;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x83;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xc6;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x02; rlm@1: rlm@1: #define SDL_LOADL \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x8b;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x06;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x83;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xc6;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x04; rlm@1: rlm@1: #define SDL_LOADL2 \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x8b;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x06;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x83;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xc6;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x03; rlm@1: rlm@1: #define SDL_STOREW \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x66;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x89;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x07;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x83;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xc7;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x02; rlm@1: rlm@1: #define SDL_STOREL \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x89;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x07;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x83;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xc7;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x04; rlm@1: rlm@1: #define SDL_STOREL2 \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x89;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x07;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x83;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xc7;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x03; rlm@1: rlm@1: #define SDL_RET \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xc3; rlm@1: rlm@1: #define SDL_PUSH_EAX \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x50; rlm@1: rlm@1: #define SDL_PUSH_ECX \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x51; rlm@1: rlm@1: #define SDL_PUSH_EBX \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x53; rlm@1: rlm@1: #define SDL_PUSH_ESI \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x56; rlm@1: rlm@1: #define SDL_PUSH_EDI \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x57; rlm@1: rlm@1: #define SDL_POP_EAX \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x58; rlm@1: rlm@1: #define SDL_POP_ECX \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x59; rlm@1: rlm@1: #define SDL_POP_EBX \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x5b; rlm@1: rlm@1: #define SDL_POP_ESI \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x5e; rlm@1: rlm@1: #define SDL_POP_EDI \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x5f; rlm@1: rlm@1: #define SDL_MOV_ECX(val) \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xb9;\ rlm@1: SDL_LONG(val); rlm@1: rlm@1: #define SDL_REP_MOVSB \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xf3;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xa4; rlm@1: rlm@1: #define SDL_REP_MOVSW \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xf3;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0x66;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xa5; rlm@1: rlm@1: #define SDL_REP_MOVSL \ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xf3;\ rlm@1: sdlStretcher[sdlStretcherPos++] = 0xa5; rlm@1: rlm@1: void sdlMakeStretcher(int width) rlm@1: { rlm@1: sdlStretcherPos = 0; rlm@1: switch(systemColorDepth) { rlm@1: case 16: rlm@1: if(sizeOption) { rlm@1: SDL_PUSH_EAX; rlm@1: SDL_PUSH_ESI; rlm@1: SDL_PUSH_EDI; rlm@1: for(int i = 0; i < width; i++) { rlm@1: SDL_LOADW; rlm@1: SDL_STOREW; rlm@1: SDL_STOREW; rlm@1: if(sizeOption > 1) { rlm@1: SDL_STOREW; rlm@1: } rlm@1: if(sizeOption > 2) { rlm@1: SDL_STOREW; rlm@1: } rlm@1: } rlm@1: SDL_POP_EDI; rlm@1: SDL_POP_ESI; rlm@1: SDL_POP_EAX; rlm@1: SDL_RET; rlm@1: } else { rlm@1: SDL_PUSH_ESI; rlm@1: SDL_PUSH_EDI; rlm@1: SDL_PUSH_ECX; rlm@1: SDL_MOV_ECX(width); rlm@1: SDL_REP_MOVSW; rlm@1: SDL_POP_ECX; rlm@1: SDL_POP_EDI; rlm@1: SDL_POP_ESI; rlm@1: SDL_RET; rlm@1: } rlm@1: break; rlm@1: case 24: rlm@1: if(sizeOption) { rlm@1: SDL_PUSH_EAX; rlm@1: SDL_PUSH_ESI; rlm@1: SDL_PUSH_EDI; rlm@1: int w = width - 1; rlm@1: for(int i = 0; i < w; i++) { rlm@1: SDL_LOADL2; rlm@1: SDL_STOREL2; rlm@1: SDL_STOREL2; rlm@1: if(sizeOption > 1) { rlm@1: SDL_STOREL2; rlm@1: } rlm@1: if(sizeOption > 2) { rlm@1: SDL_STOREL2; rlm@1: } rlm@1: } rlm@1: // need to write the last one rlm@1: SDL_LOADL2; rlm@1: SDL_STOREL2; rlm@1: if(sizeOption > 1) { rlm@1: SDL_STOREL2; rlm@1: } rlm@1: if(sizeOption > 2) { rlm@1: SDL_STOREL2; rlm@1: } rlm@1: SDL_AND_EAX(0x00ffffff); rlm@1: SDL_PUSH_EBX; rlm@1: SDL_LOADL_EBX; rlm@1: SDL_AND_EBX(0xff000000); rlm@1: SDL_OR_EAX_EBX; rlm@1: SDL_POP_EBX; rlm@1: SDL_STOREL2; rlm@1: SDL_POP_EDI; rlm@1: SDL_POP_ESI; rlm@1: SDL_POP_EAX; rlm@1: SDL_RET; rlm@1: } else { rlm@1: SDL_PUSH_ESI; rlm@1: SDL_PUSH_EDI; rlm@1: SDL_PUSH_ECX; rlm@1: SDL_MOV_ECX(3*width); rlm@1: SDL_REP_MOVSB; rlm@1: SDL_POP_ECX; rlm@1: SDL_POP_EDI; rlm@1: SDL_POP_ESI; rlm@1: SDL_RET; rlm@1: } rlm@1: break; rlm@1: case 32: rlm@1: if(sizeOption) { rlm@1: SDL_PUSH_EAX; rlm@1: SDL_PUSH_ESI; rlm@1: SDL_PUSH_EDI; rlm@1: for(int i = 0; i < width; i++) { rlm@1: SDL_LOADL; rlm@1: SDL_STOREL; rlm@1: SDL_STOREL; rlm@1: if(sizeOption > 1) { rlm@1: SDL_STOREL; rlm@1: } rlm@1: if(sizeOption > 2) { rlm@1: SDL_STOREL; rlm@1: } rlm@1: } rlm@1: SDL_POP_EDI; rlm@1: SDL_POP_ESI; rlm@1: SDL_POP_EAX; rlm@1: SDL_RET; rlm@1: } else { rlm@1: SDL_PUSH_ESI; rlm@1: SDL_PUSH_EDI; rlm@1: SDL_PUSH_ECX; rlm@1: SDL_MOV_ECX(width); rlm@1: SDL_REP_MOVSL; rlm@1: SDL_POP_ECX; rlm@1: SDL_POP_EDI; rlm@1: SDL_POP_ESI; rlm@1: SDL_RET; rlm@1: } rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: #ifdef _MSC_VER rlm@1: #define SDL_CALL_STRETCHER \ rlm@1: {\ rlm@1: __asm mov eax, stretcher\ rlm@1: __asm mov edi, dest\ rlm@1: __asm mov esi, src\ rlm@1: __asm call eax\ rlm@1: } rlm@1: #else rlm@1: #define SDL_CALL_STRETCHER \ rlm@1: asm volatile("call *%%eax"::"a" (stretcher),"S" (src),"D" (dest)) rlm@1: #endif rlm@1: #else rlm@1: #define SDL_CALL_STRETCHER \ rlm@1: sdlStretcher(src, dest) rlm@1: rlm@1: void sdlStretch16x1(u8 *src, u8 *dest) rlm@1: { rlm@1: u16 *s = (u16 *)src; rlm@1: u16 *d = (u16 *)dest; rlm@1: for(int i = 0; i < srcWidth; i++) rlm@1: *d++ = *s++; rlm@1: } rlm@1: rlm@1: void sdlStretch16x2(u8 *src, u8 *dest) rlm@1: { rlm@1: u16 *s = (u16 *)src; rlm@1: u16 *d = (u16 *)dest; rlm@1: for(int i = 0; i < srcWidth; i++) { rlm@1: *d++ = *s; rlm@1: *d++ = *s++; rlm@1: } rlm@1: } rlm@1: rlm@1: void sdlStretch16x3(u8 *src, u8 *dest) rlm@1: { rlm@1: u16 *s = (u16 *)src; rlm@1: u16 *d = (u16 *)dest; rlm@1: for(int i = 0; i < srcWidth; i++) { rlm@1: *d++ = *s; rlm@1: *d++ = *s; rlm@1: *d++ = *s++; rlm@1: } rlm@1: } rlm@1: rlm@1: void sdlStretch16x4(u8 *src, u8 *dest) rlm@1: { rlm@1: u16 *s = (u16 *)src; rlm@1: u16 *d = (u16 *)dest; rlm@1: for(int i = 0; i < srcWidth; i++) { rlm@1: *d++ = *s; rlm@1: *d++ = *s; rlm@1: *d++ = *s; rlm@1: *d++ = *s++; rlm@1: } rlm@1: } rlm@1: rlm@1: void (*sdlStretcher16[4])(u8 *, u8 *) = { rlm@1: sdlStretch16x1, rlm@1: sdlStretch16x2, rlm@1: sdlStretch16x3, rlm@1: sdlStretch16x4 rlm@1: }; rlm@1: rlm@1: void sdlStretch32x1(u8 *src, u8 *dest) rlm@1: { rlm@1: u32 *s = (u32 *)src; rlm@1: u32 *d = (u32 *)dest; rlm@1: for(int i = 0; i < srcWidth; i++) rlm@1: *d++ = *s++; rlm@1: } rlm@1: rlm@1: void sdlStretch32x2(u8 *src, u8 *dest) rlm@1: { rlm@1: u32 *s = (u32 *)src; rlm@1: u32 *d = (u32 *)dest; rlm@1: for(int i = 0; i < srcWidth; i++) { rlm@1: *d++ = *s; rlm@1: *d++ = *s++; rlm@1: } rlm@1: } rlm@1: rlm@1: void sdlStretch32x3(u8 *src, u8 *dest) rlm@1: { rlm@1: u32 *s = (u32 *)src; rlm@1: u32 *d = (u32 *)dest; rlm@1: for(int i = 0; i < srcWidth; i++) { rlm@1: *d++ = *s; rlm@1: *d++ = *s; rlm@1: *d++ = *s++; rlm@1: } rlm@1: } rlm@1: rlm@1: void sdlStretch32x4(u8 *src, u8 *dest) rlm@1: { rlm@1: u32 *s = (u32 *)src; rlm@1: u32 *d = (u32 *)dest; rlm@1: for(int i = 0; i < srcWidth; i++) { rlm@1: *d++ = *s; rlm@1: *d++ = *s; rlm@1: *d++ = *s; rlm@1: *d++ = *s++; rlm@1: } rlm@1: } rlm@1: rlm@1: void (*sdlStretcher32[4])(u8 *, u8 *) = { rlm@1: sdlStretch32x1, rlm@1: sdlStretch32x2, rlm@1: sdlStretch32x3, rlm@1: sdlStretch32x4 rlm@1: }; rlm@1: rlm@1: void sdlStretch24x1(u8 *src, u8 *dest) rlm@1: { rlm@1: u8 *s = src; rlm@1: u8 *d = dest; rlm@1: for(int i = 0; i < srcWidth; i++) { rlm@1: *d++ = *s++; rlm@1: *d++ = *s++; rlm@1: *d++ = *s++; rlm@1: } rlm@1: } rlm@1: rlm@1: void sdlStretch24x2(u8 *src, u8 *dest) rlm@1: { rlm@1: u8 *s = (u8 *)src; rlm@1: u8 *d = (u8 *)dest; rlm@1: for(int i = 0; i < srcWidth; i++) { rlm@1: *d++ = *s; rlm@1: *d++ = *(s+1); rlm@1: *d++ = *(s+2); rlm@1: s += 3; rlm@1: *d++ = *s; rlm@1: *d++ = *(s+1); rlm@1: *d++ = *(s+2); rlm@1: s += 3; rlm@1: } rlm@1: } rlm@1: rlm@1: void sdlStretch24x3(u8 *src, u8 *dest) rlm@1: { rlm@1: u8 *s = (u8 *)src; rlm@1: u8 *d = (u8 *)dest; rlm@1: for(int i = 0; i < srcWidth; i++) { rlm@1: *d++ = *s; rlm@1: *d++ = *(s+1); rlm@1: *d++ = *(s+2); rlm@1: s += 3; rlm@1: *d++ = *s; rlm@1: *d++ = *(s+1); rlm@1: *d++ = *(s+2); rlm@1: s += 3; rlm@1: *d++ = *s; rlm@1: *d++ = *(s+1); rlm@1: *d++ = *(s+2); rlm@1: s += 3; rlm@1: } rlm@1: } rlm@1: rlm@1: void sdlStretch24x4(u8 *src, u8 *dest) rlm@1: { rlm@1: u8 *s = (u8 *)src; rlm@1: u8 *d = (u8 *)dest; rlm@1: for(int i = 0; i < srcWidth; i++) { rlm@1: *d++ = *s; rlm@1: *d++ = *(s+1); rlm@1: *d++ = *(s+2); rlm@1: s += 3; rlm@1: *d++ = *s; rlm@1: *d++ = *(s+1); rlm@1: *d++ = *(s+2); rlm@1: s += 3; rlm@1: *d++ = *s; rlm@1: *d++ = *(s+1); rlm@1: *d++ = *(s+2); rlm@1: s += 3; rlm@1: *d++ = *s; rlm@1: *d++ = *(s+1); rlm@1: *d++ = *(s+2); rlm@1: s += 3; rlm@1: } rlm@1: } rlm@1: rlm@1: void (*sdlStretcher24[4])(u8 *, u8 *) = { rlm@1: sdlStretch24x1, rlm@1: sdlStretch24x2, rlm@1: sdlStretch24x3, rlm@1: sdlStretch24x4 rlm@1: }; rlm@1: rlm@1: #endif rlm@1: rlm@1: u32 sdlFromHex(char *s) rlm@1: { rlm@1: u32 value; rlm@1: sscanf(s, "%x", &value); rlm@1: return value; rlm@1: } rlm@1: rlm@1: #ifdef __MSC__ rlm@1: #define stat _stat rlm@1: #define S_IFDIR _S_IFDIR rlm@1: #endif rlm@1: rlm@1: void sdlCheckDirectory(char *dir) rlm@1: { rlm@1: struct stat buf; rlm@1: rlm@1: int len = strlen(dir); rlm@1: rlm@1: char *p = dir + len - 1; rlm@1: rlm@1: if(*p == '/' || rlm@1: *p == '\\') rlm@1: *p = 0; rlm@1: rlm@1: if(stat(dir, &buf) == 0) { rlm@1: if(!(buf.st_mode & S_IFDIR)) { rlm@1: fprintf(stderr, "Error: %s is not a directory\n", dir); rlm@1: dir[0] = 0; rlm@1: } rlm@1: } else { rlm@1: fprintf(stderr, "Error: %s does not exist\n", dir); rlm@1: dir[0] = 0; rlm@1: } rlm@1: } rlm@1: rlm@1: char *sdlGetFilename(char *name) rlm@1: { rlm@1: static char filebuffer[2048]; rlm@1: rlm@1: int len = strlen(name); rlm@1: rlm@1: char *p = name + len - 1; rlm@1: rlm@1: while(true) { rlm@1: if(*p == '/' || rlm@1: *p == '\\') { rlm@1: p++; rlm@1: break; rlm@1: } rlm@1: len--; rlm@1: p--; rlm@1: if(len == 0) rlm@1: break; rlm@1: } rlm@1: rlm@1: if(len == 0) rlm@1: strcpy(filebuffer, name); rlm@1: else rlm@1: strcpy(filebuffer, p); rlm@1: return filebuffer; rlm@1: } rlm@1: rlm@1: FILE *sdlFindFile(const char *name) rlm@1: { rlm@1: char buffer[4096]; rlm@1: char path[2048]; rlm@1: rlm@1: #ifdef WIN32 rlm@1: #define PATH_SEP ";" rlm@1: #define FILE_SEP '\\' rlm@1: #define EXE_NAME "VisualBoyAdvance-SDL.exe" rlm@1: #else // ! WIN32 rlm@1: #define PATH_SEP ":" rlm@1: #define FILE_SEP '/' rlm@1: #define EXE_NAME "VisualBoyAdvance" rlm@1: #endif // ! WIN32 rlm@1: rlm@1: fprintf(stderr, "Searching for file %s\n", name); rlm@1: rlm@1: if(GETCWD(buffer, 2048)) { rlm@1: fprintf(stderr, "Searching current directory: %s\n", buffer); rlm@1: } rlm@1: rlm@1: FILE *f = fopen(name, "r"); rlm@1: if(f != NULL) { rlm@1: return f; rlm@1: } rlm@1: rlm@1: char *home = getenv("HOME"); rlm@1: rlm@1: if(home != NULL) { rlm@1: fprintf(stderr, "Searching home directory: %s\n", home); rlm@1: sprintf(path, "%s%c%s", home, FILE_SEP, name); rlm@1: f = fopen(path, "r"); rlm@1: if(f != NULL) rlm@1: return f; rlm@1: } rlm@1: rlm@1: #ifdef WIN32 rlm@1: home = getenv("USERPROFILE"); rlm@1: if(home != NULL) { rlm@1: fprintf(stderr, "Searching user profile directory: %s\n", home); rlm@1: sprintf(path, "%s%c%s", home, FILE_SEP, name); rlm@1: f = fopen(path, "r"); rlm@1: if(f != NULL) rlm@1: return f; rlm@1: } rlm@1: #else // ! WIN32 rlm@1: fprintf(stderr, "Searching system config directory: %s\n", SYSCONFDIR); rlm@1: sprintf(path, "%s%c%s", SYSCONFDIR, FILE_SEP, name); rlm@1: f = fopen(path, "r"); rlm@1: if(f != NULL) rlm@1: return f; rlm@1: #endif // ! WIN32 rlm@1: rlm@1: if(!strchr(arg0, '/') && rlm@1: !strchr(arg0, '\\')) { rlm@1: char *path = getenv("PATH"); rlm@1: rlm@1: if(path != NULL) { rlm@1: fprintf(stderr, "Searching PATH\n"); rlm@1: strncpy(buffer, path, 4096); rlm@1: buffer[4095] = 0; rlm@1: char *tok = strtok(buffer, PATH_SEP); rlm@1: rlm@1: while(tok) { rlm@1: sprintf(path, "%s%c%s", tok, FILE_SEP, EXE_NAME); rlm@1: f = fopen(path, "r"); rlm@1: if(f != NULL) { rlm@1: char path2[2048]; rlm@1: fclose(f); rlm@1: sprintf(path2, "%s%c%s", tok, FILE_SEP, name); rlm@1: f = fopen(path2, "r"); rlm@1: if(f != NULL) { rlm@1: fprintf(stderr, "Found at %s\n", path2); rlm@1: return f; rlm@1: } rlm@1: } rlm@1: tok = strtok(NULL, PATH_SEP); rlm@1: } rlm@1: } rlm@1: } else { rlm@1: // executable is relative to some directory rlm@1: fprintf(stderr, "Searching executable directory\n"); rlm@1: strcpy(buffer, arg0); rlm@1: char *p = strrchr(buffer, FILE_SEP); rlm@1: if(p) { rlm@1: *p = 0; rlm@1: sprintf(path, "%s%c%s", buffer, FILE_SEP, name); rlm@1: f = fopen(path, "r"); rlm@1: if(f != NULL) rlm@1: return f; rlm@1: } rlm@1: } rlm@1: return NULL; rlm@1: } rlm@1: rlm@1: void sdlReadPreferences(FILE *f) rlm@1: { rlm@1: char buffer[2048]; rlm@1: rlm@1: while(1) { rlm@1: char *s = fgets(buffer, 2048, f); rlm@1: rlm@1: if(s == NULL) rlm@1: break; rlm@1: rlm@1: char *p = strchr(s, '#'); rlm@1: rlm@1: if(p) rlm@1: *p = 0; rlm@1: rlm@1: char *token = strtok(s, " \t\n\r="); rlm@1: rlm@1: if(!token) rlm@1: continue; rlm@1: rlm@1: if(strlen(token) == 0) rlm@1: continue; rlm@1: rlm@1: char *key = token; rlm@1: char *value = strtok(NULL, "\t\n\r"); rlm@1: rlm@1: if(value == NULL) { rlm@1: fprintf(stderr, "Empty value for key %s\n", key); rlm@1: continue; rlm@1: } rlm@1: rlm@1: if(!strcmp(key,"Joy0_Left")) { rlm@1: joypad[0][KEY_LEFT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy0_Right")) { rlm@1: joypad[0][KEY_RIGHT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy0_Up")) { rlm@1: joypad[0][KEY_UP] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy0_Down")) { rlm@1: joypad[0][KEY_DOWN] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy0_A")) { rlm@1: joypad[0][KEY_BUTTON_A] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy0_B")) { rlm@1: joypad[0][KEY_BUTTON_B] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy0_L")) { rlm@1: joypad[0][KEY_BUTTON_L] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy0_R")) { rlm@1: joypad[0][KEY_BUTTON_R] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy0_Start")) { rlm@1: joypad[0][KEY_BUTTON_START] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy0_Select")) { rlm@1: joypad[0][KEY_BUTTON_SELECT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy0_Speed")) { rlm@1: joypad[0][KEY_BUTTON_SPEED] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy0_Capture")) { rlm@1: joypad[0][KEY_BUTTON_CAPTURE] = sdlFromHex(value); rlm@1: } else if(!strcmp(key,"Joy1_Left")) { rlm@1: joypad[1][KEY_LEFT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy1_Right")) { rlm@1: joypad[1][KEY_RIGHT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy1_Up")) { rlm@1: joypad[1][KEY_UP] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy1_Down")) { rlm@1: joypad[1][KEY_DOWN] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy1_A")) { rlm@1: joypad[1][KEY_BUTTON_A] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy1_B")) { rlm@1: joypad[1][KEY_BUTTON_B] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy1_L")) { rlm@1: joypad[1][KEY_BUTTON_L] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy1_R")) { rlm@1: joypad[1][KEY_BUTTON_R] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy1_Start")) { rlm@1: joypad[1][KEY_BUTTON_START] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy1_Select")) { rlm@1: joypad[1][KEY_BUTTON_SELECT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy1_Speed")) { rlm@1: joypad[1][KEY_BUTTON_SPEED] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy1_Capture")) { rlm@1: joypad[1][KEY_BUTTON_CAPTURE] = sdlFromHex(value); rlm@1: } else if(!strcmp(key,"Joy2_Left")) { rlm@1: joypad[2][KEY_LEFT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy2_Right")) { rlm@1: joypad[2][KEY_RIGHT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy2_Up")) { rlm@1: joypad[2][KEY_UP] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy2_Down")) { rlm@1: joypad[2][KEY_DOWN] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy2_A")) { rlm@1: joypad[2][KEY_BUTTON_A] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy2_B")) { rlm@1: joypad[2][KEY_BUTTON_B] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy2_L")) { rlm@1: joypad[2][KEY_BUTTON_L] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy2_R")) { rlm@1: joypad[2][KEY_BUTTON_R] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy2_Start")) { rlm@1: joypad[2][KEY_BUTTON_START] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy2_Select")) { rlm@1: joypad[2][KEY_BUTTON_SELECT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy2_Speed")) { rlm@1: joypad[2][KEY_BUTTON_SPEED] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy2_Capture")) { rlm@1: joypad[2][KEY_BUTTON_CAPTURE] = sdlFromHex(value); rlm@1: } else if(!strcmp(key,"Joy4_Left")) { rlm@1: joypad[4][KEY_LEFT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy4_Right")) { rlm@1: joypad[4][KEY_RIGHT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy4_Up")) { rlm@1: joypad[4][KEY_UP] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy4_Down")) { rlm@1: joypad[4][KEY_DOWN] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy4_A")) { rlm@1: joypad[4][KEY_BUTTON_A] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy4_B")) { rlm@1: joypad[4][KEY_BUTTON_B] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy4_L")) { rlm@1: joypad[4][KEY_BUTTON_L] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy4_R")) { rlm@1: joypad[4][KEY_BUTTON_R] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy4_Start")) { rlm@1: joypad[4][KEY_BUTTON_START] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy4_Select")) { rlm@1: joypad[4][KEY_BUTTON_SELECT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy4_Speed")) { rlm@1: joypad[4][KEY_BUTTON_SPEED] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Joy4_Capture")) { rlm@1: joypad[4][KEY_BUTTON_CAPTURE] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Motion_Left")) { rlm@1: motion[KEY_LEFT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Motion_Right")) { rlm@1: motion[KEY_RIGHT] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Motion_Up")) { rlm@1: motion[KEY_UP] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "Motion_Down")) { rlm@1: motion[KEY_DOWN] = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "frameSkip")) { rlm@1: frameSkip = sdlFromHex(value); rlm@1: if(frameSkip < 0 || frameSkip > 9) rlm@1: frameSkip = 2; rlm@1: } else if(!strcmp(key, "gbFrameSkip")) { rlm@1: gbFrameSkip = sdlFromHex(value); rlm@1: if(gbFrameSkip < 0 || gbFrameSkip > 9) rlm@1: gbFrameSkip = 0; rlm@1: } else if(!strcmp(key, "video")) { rlm@1: sizeOption = sdlFromHex(value); rlm@1: if(sizeOption < 0 || sizeOption > 3) rlm@1: sizeOption = 1; rlm@1: } else if(!strcmp(key, "fullScreen")) { rlm@1: fullscreen = sdlFromHex(value) ? 1 : 0; rlm@1: } else if(!strcmp(key, "useBios")) { rlm@1: useBios = sdlFromHex(value) ? true : false; rlm@1: } else if(!strcmp(key, "skipBios")) { rlm@1: skipBios = sdlFromHex(value) ? true : false; rlm@1: } else if(!strcmp(key, "biosFile")) { rlm@1: strcpy(biosFileName, value); rlm@1: } else if(!strcmp(key, "filter")) { rlm@1: filter = sdlFromHex(value); rlm@1: if(filter < 0 || filter > 13) rlm@1: filter = 0; rlm@1: } else if(!strcmp(key, "disableStatus")) { rlm@1: disableStatusMessages = sdlFromHex(value) ? true : false; rlm@1: } else if(!strcmp(key, "borderOn")) { rlm@1: gbBorderOn = sdlFromHex(value) ? true : false; rlm@1: } else if(!strcmp(key, "borderAutomatic")) { rlm@1: gbBorderAutomatic = sdlFromHex(value) ? true : false; rlm@1: } else if(!strcmp(key, "emulatorType")) { rlm@1: gbEmulatorType = sdlFromHex(value); rlm@1: if(gbEmulatorType < 0 || gbEmulatorType > 5) rlm@1: gbEmulatorType = 1; rlm@1: } else if(!strcmp(key, "colorOption")) { rlm@1: gbColorOption = sdlFromHex(value) ? true : false; rlm@1: } else if(!strcmp(key, "captureDir")) { rlm@1: sdlCheckDirectory(value); rlm@1: strcpy(captureDir, value); rlm@1: } else if(!strcmp(key, "saveDir")) { rlm@1: sdlCheckDirectory(value); rlm@1: strcpy(saveDir, value); rlm@1: } else if(!strcmp(key, "batteryDir")) { rlm@1: sdlCheckDirectory(value); rlm@1: strcpy(batteryDir, value); rlm@1: } else if(!strcmp(key, "captureFormat")) { rlm@1: captureFormat = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "soundQuality")) { rlm@1: soundQuality = sdlFromHex(value); rlm@1: switch(soundQuality) { rlm@1: case 1: break; rlm@1: default: rlm@1: fprintf(stderr, "The rerecording version will run only sound at highest quality. Defaulting to 44.1 KHz\n"); rlm@1: soundQuality = 1; rlm@1: break; rlm@1: } rlm@1: } else if(!strcmp(key, "soundOff")) { rlm@1: soundOffFlag = sdlFromHex(value) ? true : false; rlm@1: } else if(!strcmp(key, "soundEnable")) { rlm@1: int res = sdlFromHex(value) & 0x30f; rlm@1: soundEnableChannels(res); rlm@1: soundDisableChannels(~res); rlm@1: } else if(!strcmp(key, "soundEcho")) { rlm@1: soundEcho = sdlFromHex(value) ? true : false; rlm@1: } else if(!strcmp(key, "soundLowPass")) { rlm@1: soundLowPass = sdlFromHex(value) ? true : false; rlm@1: } else if(!strcmp(key, "soundReverse")) { rlm@1: soundReverse = sdlFromHex(value) ? true : false; rlm@1: } else if(!strcmp(key, "soundVolume")) { rlm@1: soundVolume = sdlFromHex(value); rlm@1: if(soundVolume < 0 || soundVolume > 3) rlm@1: soundVolume = 0; rlm@1: } else if(!strcmp(key, "removeIntros")) { rlm@1: removeIntros = sdlFromHex(value) ? true : false; rlm@1: } else if(!strcmp(key, "saveType")) { rlm@1: cpuSaveType = sdlFromHex(value); rlm@1: if(cpuSaveType < 0 || cpuSaveType > 5) rlm@1: cpuSaveType = 0; rlm@1: } else if(!strcmp(key, "flashSize")) { rlm@1: sdlFlashSize = sdlFromHex(value); rlm@1: if(sdlFlashSize != 0 && sdlFlashSize != 1) rlm@1: sdlFlashSize = 0; rlm@1: } else if(!strcmp(key, "ifbType")) { rlm@1: ifbType = sdlFromHex(value); rlm@1: if(ifbType < 0 || ifbType > 2) rlm@1: ifbType = 0; rlm@1: } else if(!strcmp(key, "showSpeed")) { rlm@1: showSpeed = sdlFromHex(value); rlm@1: if(showSpeed < 0 || showSpeed > 2) rlm@1: showSpeed = 1; rlm@1: } else if(!strcmp(key, "showSpeedTransparent")) { rlm@1: showSpeedTransparent = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "autoFrameSkip")) { rlm@1: autoFrameSkip = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "throttle")) { rlm@1: throttle = sdlFromHex(value); rlm@1: if(throttle != 0 && (throttle < 5 || throttle > 1000)) rlm@1: throttle = 0; rlm@1: } else if(!strcmp(key, "disableMMX")) { rlm@1: #ifdef MMX rlm@1: cpu_mmx = sdlFromHex(value) ? false : true; rlm@1: #endif rlm@1: } else if(!strcmp(key, "pauseWhenInactive")) { rlm@1: pauseWhenInactive = sdlFromHex(value) ? true : false; rlm@1: } else if(!strcmp(key, "agbPrint")) { rlm@1: sdlAgbPrint = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "rtcEnabled")) { rlm@1: sdlRtcEnable = sdlFromHex(value); rlm@1: } else if(!strcmp(key, "rewindTimer")) { rlm@1: rewindTimer = sdlFromHex(value); rlm@1: if(rewindTimer < 0 || rewindTimer > 600) rlm@1: rewindTimer = 0; rlm@1: rewindTimer *= 6; // convert value to 10 frames multiple rlm@1: } else if(!strcmp(key, "enhancedDetection")) { rlm@1: cpuEnhancedDetection = sdlFromHex(value) ? true : false; rlm@1: } else { rlm@1: fprintf(stderr, "Unknown configuration key %s\n", key); rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void sdlReadPreferences() rlm@1: { rlm@1: FILE *f = sdlFindFile("VisualBoyAdvance.cfg"); rlm@1: rlm@1: if(f == NULL) { rlm@1: fprintf(stderr, "Configuration file NOT FOUND (using defaults)\n"); rlm@1: return; rlm@1: } else rlm@1: fprintf(stderr, "Reading configuration file.\n"); rlm@1: rlm@1: sdlReadPreferences(f); rlm@1: rlm@1: fclose(f); rlm@1: } rlm@1: rlm@1: static void sdlApplyPerImagePreferences() rlm@1: { rlm@1: FILE *f = sdlFindFile("vba-over.ini"); rlm@1: if(!f) { rlm@1: fprintf(stderr, "vba-over.ini NOT FOUND (using emulator settings)\n"); rlm@1: return; rlm@1: } else rlm@1: fprintf(stderr, "Reading vba-over.ini\n"); rlm@1: rlm@1: char buffer[7]; rlm@1: buffer[0] = '['; rlm@1: buffer[1] = rom[0xac]; rlm@1: buffer[2] = rom[0xad]; rlm@1: buffer[3] = rom[0xae]; rlm@1: buffer[4] = rom[0xaf]; rlm@1: buffer[5] = ']'; rlm@1: buffer[6] = 0; rlm@1: rlm@1: char readBuffer[2048]; rlm@1: rlm@1: bool found = false; rlm@1: rlm@1: while(1) { rlm@1: char *s = fgets(readBuffer, 2048, f); rlm@1: rlm@1: if(s == NULL) rlm@1: break; rlm@1: rlm@1: char *p = strchr(s, ';'); rlm@1: rlm@1: if(p) rlm@1: *p = 0; rlm@1: rlm@1: char *token = strtok(s, " \t\n\r="); rlm@1: rlm@1: if(!token) rlm@1: continue; rlm@1: if(strlen(token) == 0) rlm@1: continue; rlm@1: rlm@1: if(!strcmp(token, buffer)) { rlm@1: found = true; rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: if(found) { rlm@1: while(1) { rlm@1: char *s = fgets(readBuffer, 2048, f); rlm@1: rlm@1: if(s == NULL) rlm@1: break; rlm@1: rlm@1: char *p = strchr(s, ';'); rlm@1: if(p) rlm@1: *p = 0; rlm@1: rlm@1: char *token = strtok(s, " \t\n\r="); rlm@1: if(!token) rlm@1: continue; rlm@1: if(strlen(token) == 0) rlm@1: continue; rlm@1: rlm@1: if(token[0] == '[') // starting another image settings rlm@1: break; rlm@1: char *value = strtok(NULL, "\t\n\r="); rlm@1: if(value == NULL) rlm@1: continue; rlm@1: rlm@1: if(!strcmp(token, "rtcEnabled")) rlm@1: rtcEnable(atoi(value) == 0 ? false : true); rlm@1: else if(!strcmp(token, "flashSize")) { rlm@1: int size = atoi(value); rlm@1: if(size == 0x10000 || size == 0x20000) rlm@1: flashSetSize(size); rlm@1: } else if(!strcmp(token, "saveType")) { rlm@1: int save = atoi(value); rlm@1: if(save >= 0 && save <= 5) rlm@1: cpuSaveType = save; rlm@1: } rlm@1: } rlm@1: } rlm@1: fclose(f); rlm@1: } rlm@1: rlm@1: static int sdlCalculateShift(u32 mask) rlm@1: { rlm@1: int m = 0; rlm@1: rlm@1: while(mask) { rlm@1: m++; rlm@1: mask >>= 1; rlm@1: } rlm@1: rlm@1: return m-5; rlm@1: } rlm@1: rlm@1: static int sdlCalculateMaskWidth(u32 mask) rlm@1: { rlm@1: int m = 0; rlm@1: int mask2 = mask; rlm@1: rlm@1: while(mask2) { rlm@1: m++; rlm@1: mask2 >>= 1; rlm@1: } rlm@1: rlm@1: int m2 = 0; rlm@1: mask2 = mask; rlm@1: while(!(mask2 & 1)) { rlm@1: m2++; rlm@1: mask2 >>= 1; rlm@1: } rlm@1: rlm@1: return m - m2; rlm@1: } rlm@1: rlm@1: void sdlWriteState(int num) rlm@1: { rlm@1: char stateName[2048]; rlm@1: rlm@1: if(saveDir[0]) rlm@1: sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename), rlm@1: num+1); rlm@1: else rlm@1: sprintf(stateName,"%s%d.sgm", filename, num+1); rlm@1: if(theEmulator.emuWriteState) rlm@1: theEmulator.emuWriteState(stateName); rlm@1: sprintf(stateName, "Wrote state %d", num+1); rlm@1: systemScreenMessage(stateName); rlm@1: } rlm@1: rlm@1: void sdlReadState(int num) rlm@1: { rlm@1: char stateName[2048]; rlm@1: rlm@1: if(saveDir[0]) rlm@1: sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename), rlm@1: num+1); rlm@1: else rlm@1: sprintf(stateName,"%s%d.sgm", filename, num+1); rlm@1: rlm@1: if(theEmulator.emuReadState) rlm@1: theEmulator.emuReadState(stateName); rlm@1: rlm@1: sprintf(stateName, "Loaded state %d", num+1); rlm@1: systemScreenMessage(stateName); rlm@1: } rlm@1: rlm@1: void sdlWriteBattery() rlm@1: { rlm@1: char buffer[1048]; rlm@1: rlm@1: if(batteryDir[0]) rlm@1: sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename)); rlm@1: else rlm@1: sprintf(buffer, "%s.sav", filename); rlm@1: rlm@1: theEmulator.emuWriteBattery(buffer); rlm@1: rlm@1: systemScreenMessage("Wrote battery"); rlm@1: } rlm@1: rlm@1: void sdlReadBattery() rlm@1: { rlm@1: char buffer[1048]; rlm@1: rlm@1: if(batteryDir[0]) rlm@1: sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename)); rlm@1: else rlm@1: sprintf(buffer, "%s.sav", filename); rlm@1: rlm@1: bool res = false; rlm@1: rlm@1: res = theEmulator.emuReadBattery(buffer); rlm@1: rlm@1: if(res) rlm@1: systemScreenMessage("Loaded battery"); rlm@1: } rlm@1: rlm@1: #define MOD_KEYS (KMOD_CTRL|KMOD_SHIFT|KMOD_ALT|KMOD_META) rlm@1: #define MOD_NOCTRL (KMOD_SHIFT|KMOD_ALT|KMOD_META) rlm@1: #define MOD_NOALT (KMOD_CTRL|KMOD_SHIFT|KMOD_META) rlm@1: #define MOD_NOSHIFT (KMOD_CTRL|KMOD_ALT|KMOD_META) rlm@1: rlm@1: void sdlUpdateKey(int key, bool down) rlm@1: { rlm@1: int i; rlm@1: for(int j = 0; j < 4; j++) { rlm@1: for(i = 0 ; i < 12; i++) { rlm@1: if((joypad[j][i] & 0xf000) == 0) { rlm@1: if(key == joypad[j][i]) rlm@1: if (down) currentButtons[j] |= 1<> 12); rlm@1: int b = joypad[j][i] & 0xfff; rlm@1: if(dev) { rlm@1: dev--; rlm@1: rlm@1: if((dev == which) && (b >= 128) && (b == (button+128))) { rlm@1: if (pressed) currentButtons[j] |= 1<> 12); rlm@1: int b = motion[i] & 0xfff; rlm@1: if(dev) { rlm@1: dev--; rlm@1: rlm@1: if((dev == which) && (b >= 128) && (b == (button+128))) { rlm@1: sdlMotionButtons[i] = pressed; rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void sdlUpdateJoyHat(int which, rlm@1: int hat, rlm@1: int value) rlm@1: { rlm@1: int i; rlm@1: for(int j = 0; j < 4; j++) { rlm@1: for(i = 0; i < 12; i++) { rlm@1: int dev = (joypad[j][i] >> 12); rlm@1: int a = joypad[j][i] & 0xfff; rlm@1: if(dev) { rlm@1: dev--; rlm@1: rlm@1: if((dev == which) && (a>=32) && (a < 48) && (((a&15)>>2) == hat)) { rlm@1: int dir = a & 3; rlm@1: int v = 0; rlm@1: switch(dir) { rlm@1: case 0: rlm@1: v = value & SDL_HAT_UP; rlm@1: break; rlm@1: case 1: rlm@1: v = value & SDL_HAT_DOWN; rlm@1: break; rlm@1: case 2: rlm@1: v = value & SDL_HAT_RIGHT; rlm@1: break; rlm@1: case 3: rlm@1: v = value & SDL_HAT_LEFT; rlm@1: break; rlm@1: } rlm@1: if (v) currentButtons[j] |= 1<> 12); rlm@1: int a = motion[i] & 0xfff; rlm@1: if(dev) { rlm@1: dev--; rlm@1: rlm@1: if((dev == which) && (a>=32) && (a < 48) && (((a&15)>>2) == hat)) { rlm@1: int dir = a & 3; rlm@1: int v = 0; rlm@1: switch(dir) { rlm@1: case 0: rlm@1: v = value & SDL_HAT_UP; rlm@1: break; rlm@1: case 1: rlm@1: v = value & SDL_HAT_DOWN; rlm@1: break; rlm@1: case 2: rlm@1: v = value & SDL_HAT_RIGHT; rlm@1: break; rlm@1: case 3: rlm@1: v = value & SDL_HAT_LEFT; rlm@1: break; rlm@1: } rlm@1: sdlMotionButtons[i] = (v ? true : false); rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void sdlUpdateJoyAxis(int which, rlm@1: int axis, rlm@1: int value) rlm@1: { rlm@1: int i; rlm@1: for(int j = 0; j < 4; j++) { rlm@1: for(i = 0; i < 12; i++) { rlm@1: int dev = (joypad[j][i] >> 12); rlm@1: int a = joypad[j][i] & 0xfff; rlm@1: if(dev) { rlm@1: dev--; rlm@1: rlm@1: if((dev == which) && (a < 32) && ((a>>1) == axis)) { rlm@1: //I have no idea what this does, is this reimplementation correct? --Felipe rlm@1: if (value>16384) { rlm@1: if (a&1) currentButtons[j] |= 1<> 12); rlm@1: int a = motion[i] & 0xfff; rlm@1: if(dev) { rlm@1: dev--; rlm@1: rlm@1: if((dev == which) && (a < 32) && ((a>>1) == axis)) { rlm@1: sdlMotionButtons[i] = (a & 1) ? (value > 16384) : (value < -16384); rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: bool sdlCheckJoyKey(int key) rlm@1: { rlm@1: int dev = (key >> 12) - 1; rlm@1: int what = key & 0xfff; rlm@1: rlm@1: if(what >= 128) { rlm@1: // joystick button rlm@1: int button = what - 128; rlm@1: rlm@1: if(button >= SDL_JoystickNumButtons(sdlDevices[dev])) rlm@1: return false; rlm@1: } else if (what < 0x20) { rlm@1: // joystick axis rlm@1: what >>= 1; rlm@1: if(what >= SDL_JoystickNumAxes(sdlDevices[dev])) rlm@1: return false; rlm@1: } else if (what < 0x30) { rlm@1: // joystick hat rlm@1: what = (what & 15); rlm@1: what >>= 2; rlm@1: if(what >= SDL_JoystickNumHats(sdlDevices[dev])) rlm@1: return false; rlm@1: } rlm@1: rlm@1: // no problem found rlm@1: return true; rlm@1: } rlm@1: rlm@1: void sdlCheckKeys() rlm@1: { rlm@1: sdlNumDevices = SDL_NumJoysticks(); rlm@1: rlm@1: if(sdlNumDevices) rlm@1: sdlDevices = (SDL_Joystick **)calloc(1,sdlNumDevices * rlm@1: sizeof(SDL_Joystick **)); rlm@1: int i; rlm@1: rlm@1: bool usesJoy = false; rlm@1: rlm@1: for(int j = 0; j < 4; j++) { rlm@1: for(i = 0; i < 12; i++) { rlm@1: int dev = joypad[j][i] >> 12; rlm@1: if(dev) { rlm@1: dev--; rlm@1: bool ok = false; rlm@1: rlm@1: if(sdlDevices) { rlm@1: if(dev < sdlNumDevices) { rlm@1: if(sdlDevices[dev] == NULL) { rlm@1: sdlDevices[dev] = SDL_JoystickOpen(dev); rlm@1: } rlm@1: rlm@1: ok = sdlCheckJoyKey(joypad[j][i]); rlm@1: } else rlm@1: ok = false; rlm@1: } rlm@1: rlm@1: if(!ok) rlm@1: joypad[j][i] = defaultJoypad[i]; rlm@1: else rlm@1: usesJoy = true; rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: for(i = 0; i < 4; i++) { rlm@1: int dev = motion[i] >> 12; rlm@1: if(dev) { rlm@1: dev--; rlm@1: bool ok = false; rlm@1: rlm@1: if(sdlDevices) { rlm@1: if(dev < sdlNumDevices) { rlm@1: if(sdlDevices[dev] == NULL) { rlm@1: sdlDevices[dev] = SDL_JoystickOpen(dev); rlm@1: } rlm@1: rlm@1: ok = sdlCheckJoyKey(motion[i]); rlm@1: } else rlm@1: ok = false; rlm@1: } rlm@1: rlm@1: if(!ok) rlm@1: motion[i] = defaultMotion[i]; rlm@1: else rlm@1: usesJoy = true; rlm@1: } rlm@1: } rlm@1: rlm@1: if(usesJoy) rlm@1: SDL_JoystickEventState(SDL_ENABLE); rlm@1: } rlm@1: rlm@1: void sdlPollEvents() rlm@1: { rlm@1: SDL_Event event; rlm@1: while(SDL_PollEvent(&event)) { rlm@1: switch(event.type) { rlm@1: case SDL_QUIT: rlm@1: emulating = 0; rlm@1: break; rlm@1: case SDL_ACTIVEEVENT: rlm@1: if(pauseWhenInactive && (event.active.state & SDL_APPINPUTFOCUS)) { rlm@1: active = event.active.gain; rlm@1: if(active) { rlm@1: if(!paused) { rlm@1: if(emulating) rlm@1: soundResume(); rlm@1: } rlm@1: } else { rlm@1: wasPaused = true; rlm@1: if(pauseWhenInactive) { rlm@1: if(emulating) rlm@1: soundPause(); rlm@1: } rlm@1: rlm@1: memset(delta,255,sizeof(delta)); rlm@1: } rlm@1: } rlm@1: break; rlm@1: case SDL_MOUSEMOTION: rlm@1: case SDL_MOUSEBUTTONUP: rlm@1: case SDL_MOUSEBUTTONDOWN: rlm@1: if(fullscreen) { rlm@1: SDL_ShowCursor(SDL_ENABLE); rlm@1: mouseCounter = 120; rlm@1: } rlm@1: break; rlm@1: case SDL_JOYHATMOTION: rlm@1: sdlUpdateJoyHat(event.jhat.which, rlm@1: event.jhat.hat, rlm@1: event.jhat.value); rlm@1: break; rlm@1: case SDL_JOYBUTTONDOWN: rlm@1: case SDL_JOYBUTTONUP: rlm@1: sdlUpdateJoyButton(event.jbutton.which, rlm@1: event.jbutton.button, rlm@1: event.jbutton.state == SDL_PRESSED); rlm@1: break; rlm@1: case SDL_JOYAXISMOTION: rlm@1: sdlUpdateJoyAxis(event.jaxis.which, rlm@1: event.jaxis.axis, rlm@1: event.jaxis.value); rlm@1: break; rlm@1: case SDL_KEYDOWN: rlm@1: sdlUpdateKey(event.key.keysym.sym, true); rlm@1: break; rlm@1: case SDL_KEYUP: rlm@1: switch(event.key.keysym.sym) { rlm@1: case SDLK_r: rlm@1: if(!(event.key.keysym.mod & MOD_NOCTRL) && rlm@1: (event.key.keysym.mod & KMOD_CTRL)) { rlm@1: if(emulating) { rlm@1: theEmulator.emuReset(true); rlm@1: rlm@1: systemScreenMessage("Reset"); rlm@1: } rlm@1: } rlm@1: break; rlm@1: case SDLK_b: rlm@1: if(!(event.key.keysym.mod & MOD_NOCTRL) && rlm@1: (event.key.keysym.mod & KMOD_CTRL)) { rlm@1: if(emulating && theEmulator.emuReadMemState && rewindMemory rlm@1: && rewindCount) { rlm@1: rewindPos = --rewindPos & 7; rlm@1: theEmulator.emuReadMemState(&rewindMemory[REWIND_SIZE*rewindPos], rlm@1: REWIND_SIZE); rlm@1: rewindCount--; rlm@1: rewindCounter = 0; rlm@1: systemScreenMessage("Rewind"); rlm@1: } rlm@1: } rlm@1: break; rlm@1: case SDLK_p: rlm@1: if(!(event.key.keysym.mod & MOD_NOCTRL) && rlm@1: (event.key.keysym.mod & KMOD_CTRL)) { rlm@1: paused = !paused; rlm@1: SDL_PauseAudio(paused); rlm@1: if(paused) rlm@1: wasPaused = true; rlm@1: } rlm@1: break; rlm@1: case SDLK_ESCAPE: rlm@1: emulating = 0; rlm@1: break; rlm@1: case SDLK_f: rlm@1: if(!(event.key.keysym.mod & MOD_NOCTRL) && rlm@1: (event.key.keysym.mod & KMOD_CTRL)) { rlm@1: int flags = 0; rlm@1: fullscreen = !fullscreen; rlm@1: if(fullscreen) rlm@1: flags |= SDL_FULLSCREEN; rlm@1: SDL_SetVideoMode(destWidth, destHeight, systemColorDepth, flags); rlm@1: // if(SDL_WM_ToggleFullScreen(surface)) rlm@1: // fullscreen = !fullscreen; rlm@1: } rlm@1: break; rlm@1: case SDLK_F11: rlm@1: if(dbgMain != debuggerMain) { rlm@1: if(armState) { rlm@1: armNextPC -= 4; rlm@1: reg[15].I -= 4; rlm@1: } else { rlm@1: armNextPC -= 2; rlm@1: reg[15].I -= 2; rlm@1: } rlm@1: } rlm@1: debugger = true; rlm@1: break; rlm@1: case SDLK_F1: rlm@1: case SDLK_F2: rlm@1: case SDLK_F3: rlm@1: case SDLK_F4: rlm@1: case SDLK_F5: rlm@1: case SDLK_F6: rlm@1: case SDLK_F7: rlm@1: case SDLK_F8: rlm@1: case SDLK_F9: rlm@1: case SDLK_F10: rlm@1: if(!(event.key.keysym.mod & MOD_NOSHIFT) && rlm@1: (event.key.keysym.mod & KMOD_SHIFT)) { rlm@1: sdlWriteState(event.key.keysym.sym-SDLK_F1); rlm@1: } else if(!(event.key.keysym.mod & MOD_KEYS)) { rlm@1: sdlReadState(event.key.keysym.sym-SDLK_F1); rlm@1: } rlm@1: break; rlm@1: case SDLK_1: rlm@1: case SDLK_2: rlm@1: case SDLK_3: rlm@1: case SDLK_4: rlm@1: if(!(event.key.keysym.mod & MOD_NOALT) && rlm@1: (event.key.keysym.mod & KMOD_ALT)) { rlm@1: char *disableMessages[4] = rlm@1: { "autofire A disabled", rlm@1: "autofire B disabled", rlm@1: "autofire R disabled", rlm@1: "autofire L disabled"}; rlm@1: char *enableMessages[4] = rlm@1: { "autofire A", rlm@1: "autofire B", rlm@1: "autofire R", rlm@1: "autofire L"}; rlm@1: int mask = 1 << (event.key.keysym.sym - SDLK_1); rlm@1: if(event.key.keysym.sym > SDLK_2) rlm@1: mask <<= 6; rlm@1: if(autoFire & mask) { rlm@1: autoFire &= ~mask; rlm@1: systemScreenMessage(disableMessages[event.key.keysym.sym - SDLK_1]); rlm@1: } else { rlm@1: autoFire |= mask; rlm@1: systemScreenMessage(enableMessages[event.key.keysym.sym - SDLK_1]); rlm@1: } rlm@1: } if(!(event.key.keysym.mod & MOD_NOCTRL) && rlm@1: (event.key.keysym.mod & KMOD_CTRL)) { rlm@1: int mask = 0x0100 << (event.key.keysym.sym - SDLK_1); rlm@1: layerSettings ^= mask; rlm@1: layerEnable = DISPCNT & layerSettings; rlm@1: CPUUpdateRenderBuffers(false); rlm@1: } rlm@1: break; rlm@1: case SDLK_5: rlm@1: case SDLK_6: rlm@1: case SDLK_7: rlm@1: case SDLK_8: rlm@1: if(!(event.key.keysym.mod & MOD_NOCTRL) && rlm@1: (event.key.keysym.mod & KMOD_CTRL)) { rlm@1: int mask = 0x0100 << (event.key.keysym.sym - SDLK_1); rlm@1: layerSettings ^= mask; rlm@1: layerEnable = DISPCNT & layerSettings; rlm@1: } rlm@1: break; rlm@1: case SDLK_n: rlm@1: if(!(event.key.keysym.mod & MOD_NOCTRL) && rlm@1: (event.key.keysym.mod & KMOD_CTRL)) { rlm@1: if(paused) rlm@1: paused = false; rlm@1: pauseNextFrame = true; rlm@1: } rlm@1: break; rlm@1: default: rlm@1: break; rlm@1: } rlm@1: sdlUpdateKey(event.key.keysym.sym, false); rlm@1: break; rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void usage(char *cmd) rlm@1: { rlm@1: printf("%s [option ...] file\n", cmd); rlm@1: printf("\ rlm@1: \n\ rlm@1: Options:\n\ rlm@1: -1, --video-1x 1x\n\ rlm@1: -2, --video-2x 2x\n\ rlm@1: -3, --video-3x 3x\n\ rlm@1: -4, --video-4x 4x\n\ rlm@1: -F, --fullscreen Full screen\n\ rlm@1: -G, --gdb=PROTOCOL GNU Remote Stub mode:\n\ rlm@1: tcp - use TCP at port 55555\n\ rlm@1: tcp:PORT - use TCP at port PORT\n\ rlm@1: pipe - use pipe transport\n\ rlm@1: -N, --no-debug Don't parse debug information\n\ rlm@1: -S, --flash-size=SIZE Set the Flash size\n\ rlm@1: --flash-64k 0 - 64K Flash\n\ rlm@1: --flash-128k 1 - 128K Flash\n\ rlm@1: -T, --throttle=THROTTLE Set the desired throttle (5...1000)\n\ rlm@1: -Y, --yuv=TYPE Use YUV overlay for drawing:\n\ rlm@1: 0 - YV12\n\ rlm@1: 1 - UYVY\n\ rlm@1: 2 - YVYU\n\ rlm@1: 3 - YUY2\n\ rlm@1: 4 - IYUV\n\ rlm@1: -b, --bios=BIOS Use given bios file\n\ rlm@1: -c, --config=FILE Read the given configuration file\n\ rlm@1: -d, --debug Enter debugger\n\ rlm@1: -f, --filter=FILTER Select filter:\n\ rlm@1: --filter-normal 0 - normal mode\n\ rlm@1: --filter-tv-mode 1 - TV Mode\n\ rlm@1: --filter-2xsai 2 - 2xSaI\n\ rlm@1: --filter-super-2xsai 3 - Super 2xSaI\n\ rlm@1: --filter-super-eagle 4 - Super Eagle\n\ rlm@1: --filter-pixelate 5 - Pixelate\n\ rlm@1: --filter-motion-blur 6 - Motion Blur\n\ rlm@1: --filter-advmame 7 - AdvanceMAME Scale2x\n\ rlm@1: --filter-simple2x 8 - Simple2x\n\ rlm@1: --filter-bilinear 9 - Bilinear\n\ rlm@1: --filter-bilinear+ 10 - Bilinear Plus\n\ rlm@1: --filter-scanlines 11 - Scanlines\n\ rlm@1: --filter-hq2x 12 - hq2x\n\ rlm@1: --filter-lq2x 13 - lq2x\n\ rlm@1: -h, --help Print this help\n\ rlm@1: -i, --ips=PATCH Apply given IPS patch\n\ rlm@1: -P, --profile=[HERTZ] Enable profiling\n\ rlm@1: -s, --frameskip=FRAMESKIP Set frame skip (0...9)\n\ rlm@1: "); rlm@1: printf("\ rlm@1: -t, --save-type=TYPE Set the available save type\n\ rlm@1: --save-auto 0 - Automatic (EEPROM, SRAM, FLASH)\n\ rlm@1: --save-eeprom 1 - EEPROM\n\ rlm@1: --save-sram 2 - SRAM\n\ rlm@1: --save-flash 3 - FLASH\n\ rlm@1: --save-sensor 4 - EEPROM+Sensor\n\ rlm@1: --save-none 5 - NONE\n\ rlm@1: -v, --verbose=VERBOSE Set verbose logging (trace.log)\n\ rlm@1: 1 - SWI\n\ rlm@1: 2 - Unaligned memory access\n\ rlm@1: 4 - Illegal memory write\n\ rlm@1: 8 - Illegal memory read\n\ rlm@1: 16 - DMA 0\n\ rlm@1: 32 - DMA 1\n\ rlm@1: 64 - DMA 2\n\ rlm@1: 128 - DMA 3\n\ rlm@1: 256 - Undefined instruction\n\ rlm@1: 512 - AGBPrint messages\n\ rlm@1: \n\ rlm@1: Long options only:\n\ rlm@1: --agb-print Enable AGBPrint support\n\ rlm@1: --auto-frameskip Enable auto frameskipping\n\ rlm@1: --ifb-none No interframe blending\n\ rlm@1: --ifb-motion-blur Interframe motion blur\n\ rlm@1: --ifb-smart Smart interframe blending\n\ rlm@1: --no-agb-print Disable AGBPrint support\n\ rlm@1: --no-auto-frameskip Disable auto frameskipping\n\ rlm@1: --no-ips Do not apply IPS patch\n\ rlm@1: --no-mmx Disable MMX support\n\ rlm@1: --no-pause-when-inactive Don't pause when inactive\n\ rlm@1: --no-rtc Disable RTC support\n\ rlm@1: --no-show-speed Don't show emulation speed\n\ rlm@1: --no-throttle Disable thrrotle\n\ rlm@1: --pause-when-inactive Pause when inactive\n\ rlm@1: --rtc Enable RTC support\n\ rlm@1: --show-speed-normal Show emulation speed\n\ rlm@1: --show-speed-detailed Show detailed speed data\n\ rlm@1: "); rlm@1: printf("\ rlm@1: -r, --recordmovie=filename Start recording input movie\n\ rlm@1: -p, --playmovie=filename Play input movie non-read-only\n\ rlm@1: -w, --watchmovie=filename Play input movie in read-only mode\n\ rlm@1: "); rlm@1: } rlm@1: rlm@1: static char *szFile; rlm@1: rlm@1: void file_run() rlm@1: { rlm@39: //printf("RLM: file_run\n"); rlm@39: utilGetBaseName(szFile, filename); rlm@1: char *p = strrchr(filename, '.'); rlm@1: rlm@1: if(p) rlm@1: *p = 0; rlm@1: rlm@1: if(ipsname[0] == 0) rlm@1: sprintf(ipsname, "%s.ips", filename); rlm@1: rlm@1: bool failed = false; rlm@1: rlm@1: IMAGE_TYPE type = utilFindType(szFile); rlm@1: rlm@1: if(type == IMAGE_UNKNOWN) { rlm@1: systemMessage(0, "Unknown file type %s", szFile); rlm@1: exit(-1); rlm@1: } rlm@1: systemCartridgeType = (int)type; rlm@1: rlm@1: if(type == IMAGE_GB) { rlm@1: failed = !gbLoadRom(szFile); rlm@1: if(!failed) { rlm@1: systemCartridgeType = 1; rlm@39: //printf("RLM: choosing GBSystem\n"); rlm@33: theEmulator = GBSystem; rlm@1: if(sdlAutoIPS) { rlm@1: int size = gbRomSize; rlm@1: utilApplyIPS(ipsname, &gbRom, &size); rlm@1: if(size != gbRomSize) { rlm@1: extern bool gbUpdateSizes(); rlm@1: gbUpdateSizes(); rlm@1: gbReset(); rlm@1: } rlm@1: } rlm@1: } rlm@1: } else if(type == IMAGE_GBA) { rlm@1: int size = CPULoadRom(szFile); rlm@1: failed = (size == 0); rlm@1: if(!failed) { rlm@1: // if(cpuEnhancedDetection && cpuSaveType == 0) { rlm@1: // utilGBAFindSave(rom, size); rlm@1: // } rlm@33: rlm@1: sdlApplyPerImagePreferences(); rlm@1: rlm@1: systemCartridgeType = 0; rlm@1: theEmulator = GBASystem; rlm@1: rlm@1: /* disabled due to problems rlm@1: if(removeIntros && rom != NULL) { rlm@1: WRITE32LE(&rom[0], 0xea00002e); rlm@1: } rlm@1: */ rlm@1: rlm@1: //CPUInit(biosFileName, useBios); rlm@1: CPUInit(); rlm@1: CPUReset(); rlm@1: if(sdlAutoIPS) { rlm@1: int size = 0x2000000; rlm@1: utilApplyIPS(ipsname, &rom, &size); rlm@1: if(size != 0x2000000) { rlm@1: CPUReset(); rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: if(failed) { rlm@1: systemMessage(0, "Failed to load file %s", szFile); rlm@1: exit(-1); rlm@1: } rlm@1: rlm@1: emulating = 1; rlm@1: renderedFrames = 0; rlm@1: } rlm@1: rlm@53: rlm@53: void shutdown () { rlm@53: fprintf(stderr,"Shutting down\n"); rlm@53: remoteCleanUp(); rlm@53: soundShutdown(); rlm@53: rlm@53: if(gbRom != NULL || rom != NULL) { rlm@53: sdlWriteBattery(); rlm@53: theEmulator.emuCleanUp(); rlm@53: } rlm@53: rlm@53: if(delta) { rlm@53: free(delta); rlm@53: delta = NULL; rlm@53: } rlm@53: rlm@53: SDL_Quit(); rlm@53: } rlm@53: rlm@92: int tick () { rlm@176: int ret; rlm@176: ret = theEmulator.emuMain(theEmulator.emuCount); rlm@176: // enable user input while ticking. rlm@176: if (ret) { sdlPollEvents(); } rlm@92: } rlm@53: rlm@53: void step () { rlm@53: if(!paused && active) { rlm@92: //printf("RLM: emulator main\n"); rlm@92: int frameComplete = 0; rlm@92: while (!(frameComplete)){ rlm@92: frameComplete = theEmulator.emuMain(theEmulator.emuCount); rlm@53: } rlm@92: //printf("RLM: emulator main called\n"); rlm@53: } else { rlm@53: SDL_Delay(500); rlm@53: } rlm@53: sdlPollEvents(); rlm@55: SDL_ShowCursor(SDL_DISABLE); rlm@53: } rlm@53: rlm@55: void step(int keymask){ rlm@55: currentButtons[0] = keymask; rlm@66: if (keymask == 0x0800){ rlm@66: theEmulator.emuReset(true); rlm@66: } rlm@66: else { rlm@66: step(); rlm@66: } rlm@55: currentButtons[0] = keymask; rlm@55: } rlm@55: rlm@55: rlm@55: rlm@1: int main(int argc, char **argv) rlm@1: { rlm@30: fprintf(stderr, "VisualBoyAdvance version %s [SDL]\n", PACKAGE_VERSION); rlm@1: rlm@1: arg0 = argv[0]; rlm@1: rlm@1: captureDir[0] = 0; rlm@1: saveDir[0] = 0; rlm@1: batteryDir[0] = 0; rlm@1: ipsname[0] = 0; rlm@1: rlm@1: int op = -1; rlm@1: rlm@1: frameSkip = 2; rlm@1: gbBorderOn = 0; rlm@1: rlm@1: parseDebug = true; rlm@1: rlm@1: sdlReadPreferences(); rlm@1: rlm@1: sdlPrintUsage = 0; rlm@1: rlm@1: while((op = getopt_long(argc, rlm@1: argv, rlm@1: "FNT:Y:G:D:b:c:df:hi:p::s:t:v:1234", rlm@1: sdlOptions, rlm@1: NULL)) != -1) { rlm@1: switch(op) { rlm@1: case 0: rlm@1: // long option already processed by getopt_long rlm@1: break; rlm@1: case 'b': rlm@1: useBios = true; rlm@1: if(optarg == NULL) { rlm@1: fprintf(stderr, "Missing BIOS file name\n"); rlm@1: exit(-1); rlm@1: } rlm@1: strcpy(biosFileName, optarg); rlm@1: break; rlm@1: case 'c': rlm@1: { rlm@1: if(optarg == NULL) { rlm@1: fprintf(stderr, "Missing config file name\n"); rlm@1: exit(-1); rlm@1: } rlm@1: FILE *f = fopen(optarg, "r"); rlm@1: if(f == NULL) { rlm@1: fprintf(stderr, "File not found %s\n", optarg); rlm@1: exit(-1); rlm@1: } rlm@1: sdlReadPreferences(f); rlm@1: fclose(f); rlm@1: } rlm@1: break; rlm@1: case 'd': rlm@1: debugger = true; rlm@1: break; rlm@1: case 'h': rlm@1: sdlPrintUsage = 1; rlm@1: break; rlm@1: case 'i': rlm@1: if(optarg == NULL) { rlm@1: fprintf(stderr, "Missing IPS name\n"); rlm@1: exit(-1); rlm@1: strcpy(ipsname, optarg); rlm@1: } rlm@1: break; rlm@1: case 'Y': rlm@1: yuv = true; rlm@1: if(optarg) { rlm@1: yuvType = atoi(optarg); rlm@1: switch(yuvType) { rlm@1: case 0: rlm@1: yuvType = SDL_YV12_OVERLAY; rlm@1: break; rlm@1: case 1: rlm@1: yuvType = SDL_UYVY_OVERLAY; rlm@1: break; rlm@1: case 2: rlm@1: yuvType = SDL_YVYU_OVERLAY; rlm@1: break; rlm@1: case 3: rlm@1: yuvType = SDL_YUY2_OVERLAY; rlm@1: break; rlm@1: case 4: rlm@1: yuvType = SDL_IYUV_OVERLAY; rlm@1: break; rlm@1: default: rlm@1: yuvType = SDL_YV12_OVERLAY; rlm@1: } rlm@1: } else rlm@1: yuvType = SDL_YV12_OVERLAY; rlm@1: break; rlm@1: case 'G': rlm@1: dbgMain = remoteStubMain; rlm@1: dbgSignal = remoteStubSignal; rlm@1: dbgOutput = remoteOutput; rlm@1: debugger = true; rlm@1: debuggerStub = true; rlm@1: if(optarg) { rlm@1: char *s = optarg; rlm@1: if(strncmp(s,"tcp:", 4) == 0) { rlm@1: s+=4; rlm@1: int port = atoi(s); rlm@1: remoteSetProtocol(0); rlm@1: remoteSetPort(port); rlm@1: } else if(strcmp(s,"tcp") == 0) { rlm@1: remoteSetProtocol(0); rlm@1: } else if(strcmp(s, "pipe") == 0) { rlm@1: remoteSetProtocol(1); rlm@1: } else { rlm@1: fprintf(stderr, "Unknown protocol %s\n", s); rlm@1: exit(-1); rlm@1: } rlm@1: } else { rlm@1: remoteSetProtocol(0); rlm@1: } rlm@1: break; rlm@1: case 'N': rlm@1: parseDebug = false; rlm@1: break; rlm@1: case 'D': rlm@1: if(optarg) { rlm@1: systemDebug = atoi(optarg); rlm@1: } else { rlm@1: systemDebug = 1; rlm@1: } rlm@1: break; rlm@1: case 'F': rlm@1: fullscreen = 1; rlm@1: mouseCounter = 120; rlm@1: break; rlm@1: case 'f': rlm@1: if(optarg) { rlm@1: filter = atoi(optarg); rlm@1: } else { rlm@1: filter = 0; rlm@1: } rlm@1: break; rlm@1: rlm@1: case 'r': rlm@1: if(optarg == NULL) { rlm@33: fprintf(stderr, "ERROR: --recordmovie ('r') needs movie filename as option\n"); rlm@1: exit(-1); rlm@1: } rlm@1: strcpy(movieFileName, optarg); rlm@1: useMovie = 1; rlm@1: break; rlm@1: case 'p': // play without read-only (editable) rlm@1: fprintf (stderr, "-p got called!\n"); rlm@1: if(optarg == NULL) { rlm@33: fprintf(stderr, "ERROR: --playmovie ('p') needs movie filename as option\n"); rlm@1: exit(-1); rlm@1: } rlm@1: strcpy(movieFileName, optarg); rlm@1: useMovie = 2; rlm@1: break; rlm@1: case 'w': // play with read-only rlm@1: fprintf (stderr, "-w got called!\n"); rlm@1: if(optarg == NULL) { rlm@33: fprintf(stderr, "ERROR: --watchmovie ('w') needs movie filename as option\n"); rlm@1: exit(-1); rlm@1: } rlm@1: strcpy(movieFileName, optarg); rlm@1: useMovie = 3; rlm@1: break; rlm@1: rlm@1: case 'P': rlm@1: #ifdef PROFILING rlm@1: if(optarg) { rlm@1: cpuEnableProfiling(atoi(optarg)); rlm@1: } else rlm@1: cpuEnableProfiling(100); rlm@1: #endif rlm@1: break; rlm@1: case 'S': rlm@1: sdlFlashSize = atoi(optarg); rlm@1: if(sdlFlashSize < 0 || sdlFlashSize > 1) rlm@1: sdlFlashSize = 0; rlm@1: break; rlm@1: case 's': rlm@1: if(optarg) { rlm@1: int a = atoi(optarg); rlm@1: if(a >= 0 && a <= 9) { rlm@1: gbFrameSkip = a; rlm@1: frameSkip = a; rlm@1: } rlm@1: } else { rlm@1: frameSkip = 2; rlm@1: gbFrameSkip = 0; rlm@1: } rlm@1: break; rlm@1: case 't': rlm@1: if(optarg) { rlm@1: int a = atoi(optarg); rlm@1: if(a < 0 || a > 5) rlm@1: a = 0; rlm@1: cpuSaveType = a; rlm@1: } rlm@1: break; rlm@1: case 'T': rlm@1: if(optarg) { rlm@1: int t = atoi(optarg); rlm@1: throttle = t; rlm@1: } rlm@1: break; rlm@1: case 'v': rlm@1: if(optarg) { rlm@1: systemVerbose = atoi(optarg); rlm@1: } else rlm@1: systemVerbose = 0; rlm@1: break; rlm@1: case '1': rlm@1: sizeOption = 0; rlm@1: break; rlm@1: case '2': rlm@1: sizeOption = 1; rlm@1: break; rlm@1: case '3': rlm@1: sizeOption = 2; rlm@1: break; rlm@1: case '4': rlm@1: sizeOption = 3; rlm@1: break; rlm@1: case '?': rlm@1: sdlPrintUsage = 1; rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@39: //printf("RLM: derpy loves you!\n"); rlm@39: //printf("RLM: useMovie: %d (1 is record)\n", useMovie); rlm@1: if(sdlPrintUsage) { rlm@1: usage(argv[0]); rlm@1: exit(-1); rlm@1: } rlm@1: rlm@1: #ifdef MMX rlm@1: if(disableMMX) rlm@1: cpu_mmx = 0; rlm@1: #endif rlm@1: rlm@1: if(rewindTimer) rlm@1: rewindMemory = (char *)malloc(8*REWIND_SIZE); rlm@1: rlm@1: if(sdlFlashSize == 0) rlm@1: flashSetSize(0x10000); rlm@1: else rlm@1: flashSetSize(0x20000); rlm@1: rlm@1: rtcEnable(sdlRtcEnable ? true : false); rlm@1: agbPrintEnable(sdlAgbPrint ? true : false); rlm@1: rlm@1: if(!debuggerStub) { rlm@1: if(optind >= argc) { rlm@1: systemMessage(0,"Missing image name"); rlm@1: usage(argv[0]); rlm@1: exit(-1); rlm@1: } rlm@1: } rlm@1: rlm@1: if(filter) { rlm@1: sizeOption = 1; rlm@1: } rlm@1: rlm@1: for(int i = 0; i < 24;) { rlm@1: systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10); rlm@1: systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10); rlm@1: systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10); rlm@1: systemGbPalette[i++] = 0; rlm@1: } rlm@1: rlm@1: systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; rlm@1: rlm@1: if(optind < argc) rlm@1: { rlm@1: szFile = argv[optind]; rlm@1: file_run(); rlm@39: //printf("RLM: file_run() done\n"); rlm@1: } rlm@1: else rlm@1: { rlm@1: systemCartridgeType = 0; rlm@1: strcpy(filename, "gnu_stub"); rlm@1: rom = (u8 *)malloc(0x2000000); rlm@1: workRAM = (u8 *)calloc(1, 0x40000); rlm@1: bios = (u8 *)calloc(1,0x4000); rlm@1: internalRAM = (u8 *)calloc(1,0x8000); rlm@1: paletteRAM = (u8 *)calloc(1,0x400); rlm@1: vram = (u8 *)calloc(1, 0x20000); rlm@1: oam = (u8 *)calloc(1, 0x400); rlm@1: pix = (u8 *)calloc(1, 4 * 240 * 160); rlm@1: ioMem = (u8 *)calloc(1, 0x400); rlm@1: rlm@1: theEmulator = GBASystem; rlm@1: rlm@1: //CPUInit(biosFileName, useBios); rlm@1: CPUInit(); rlm@33: CPUReset(); rlm@1: } rlm@1: rlm@1: if(debuggerStub) rlm@1: remoteInit(); rlm@1: rlm@1: int flags = SDL_INIT_VIDEO|SDL_INIT_AUDIO| rlm@1: SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE; rlm@1: rlm@1: if(soundOffFlag) rlm@1: flags ^= SDL_INIT_AUDIO; rlm@1: rlm@1: if(SDL_Init(flags)) { rlm@1: systemMessage(0, "Failed to init SDL: %s", SDL_GetError()); rlm@1: exit(-1); rlm@1: } rlm@1: rlm@1: if(SDL_InitSubSystem(SDL_INIT_JOYSTICK)) { rlm@1: systemMessage(0, "Failed to init joystick support: %s", SDL_GetError()); rlm@1: } rlm@1: rlm@1: sdlCheckKeys(); rlm@1: rlm@1: if(systemCartridgeType == 0) { rlm@1: srcWidth = 240; rlm@1: srcHeight = 160; rlm@1: systemFrameSkip = frameSkip; rlm@1: } else if (systemCartridgeType == 1) { rlm@1: if(gbBorderOn) { rlm@1: srcWidth = 256; rlm@1: srcHeight = 224; rlm@1: gbBorderLineSkip = 256; rlm@1: gbBorderColumnSkip = 48; rlm@1: gbBorderRowSkip = 40; rlm@1: } else { rlm@1: srcWidth = 160; rlm@1: srcHeight = 144; rlm@1: gbBorderLineSkip = 160; rlm@1: gbBorderColumnSkip = 0; rlm@1: gbBorderRowSkip = 0; rlm@1: } rlm@1: systemFrameSkip = gbFrameSkip; rlm@1: } else { rlm@1: srcWidth = 320; rlm@1: srcHeight = 240; rlm@1: } rlm@1: rlm@1: destWidth = (sizeOption+1)*srcWidth; rlm@1: destHeight = (sizeOption+1)*srcHeight; rlm@1: rlm@1: surface = SDL_SetVideoMode(destWidth, destHeight, 16, rlm@1: SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF| rlm@1: (fullscreen ? SDL_FULLSCREEN : 0)); rlm@1: rlm@1: if(surface == NULL) { rlm@1: systemMessage(0, "Failed to set video mode"); rlm@1: SDL_Quit(); rlm@1: exit(-1); rlm@1: } rlm@1: rlm@1: systemRedShift = sdlCalculateShift(surface->format->Rmask); rlm@1: systemGreenShift = sdlCalculateShift(surface->format->Gmask); rlm@1: systemBlueShift = sdlCalculateShift(surface->format->Bmask); rlm@1: rlm@1: systemColorDepth = surface->format->BitsPerPixel; rlm@1: if(systemColorDepth == 15) rlm@1: systemColorDepth = 16; rlm@1: rlm@1: if(yuv) { rlm@1: Init_Overlay(surface, yuvType); rlm@1: systemColorDepth = 32; rlm@1: systemRedShift = 3; rlm@1: systemGreenShift = 11; rlm@1: systemBlueShift = 19; rlm@1: } rlm@1: rlm@1: if(systemColorDepth != 16 && systemColorDepth != 24 && rlm@1: systemColorDepth != 32) { rlm@1: fprintf(stderr,"Unsupported color depth '%d'.\nOnly 16, 24 and 32 bit color depths are supported\n", systemColorDepth); rlm@1: exit(-1); rlm@1: } rlm@1: rlm@1: #ifndef C_CORE rlm@1: sdlMakeStretcher(srcWidth); rlm@1: #else rlm@1: switch(systemColorDepth) { rlm@1: case 16: rlm@1: sdlStretcher = sdlStretcher16[sizeOption]; rlm@1: break; rlm@1: case 24: rlm@1: sdlStretcher = sdlStretcher24[sizeOption]; rlm@1: break; rlm@1: case 32: rlm@1: sdlStretcher = sdlStretcher32[sizeOption]; rlm@1: break; rlm@1: default: rlm@1: fprintf(stderr, "Unsupported resolution: %d\n", systemColorDepth); rlm@1: exit(-1); rlm@1: } rlm@1: #endif rlm@1: rlm@1: fprintf(stderr,"Color depth: %d\n", systemColorDepth); rlm@1: rlm@1: if(systemColorDepth == 16) { rlm@1: if(sdlCalculateMaskWidth(surface->format->Gmask) == 6) { rlm@1: Init_2xSaI(565); rlm@1: RGB_LOW_BITS_MASK = 0x821; rlm@1: } else { rlm@1: Init_2xSaI(555); rlm@1: RGB_LOW_BITS_MASK = 0x421; rlm@1: } rlm@1: if(systemCartridgeType == 2) { rlm@1: for(int i = 0; i < 0x10000; i++) { rlm@1: systemColorMap16[i] = (((i >> 1) & 0x1f) << systemBlueShift) | rlm@1: (((i & 0x7c0) >> 6) << systemGreenShift) | rlm@1: (((i & 0xf800) >> 11) << systemRedShift); rlm@1: } rlm@1: } else { rlm@1: for(int i = 0; i < 0x10000; i++) { rlm@1: systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | rlm@1: (((i & 0x3e0) >> 5) << systemGreenShift) | rlm@1: (((i & 0x7c00) >> 10) << systemBlueShift); rlm@1: } rlm@1: } rlm@1: srcPitch = srcWidth * 2+4; rlm@1: } else { rlm@1: if(systemColorDepth != 32) rlm@1: filterFunction = NULL; rlm@1: RGB_LOW_BITS_MASK = 0x010101; rlm@1: if(systemColorDepth == 32) { rlm@1: Init_2xSaI(32); rlm@1: } rlm@1: for(int i = 0; i < 0x10000; i++) { rlm@1: systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | rlm@1: (((i & 0x3e0) >> 5) << systemGreenShift) | rlm@1: (((i & 0x7c00) >> 10) << systemBlueShift); rlm@1: } rlm@1: if(systemColorDepth == 32) rlm@1: srcPitch = srcWidth*4 + 4; rlm@1: else rlm@1: srcPitch = srcWidth*3; rlm@1: } rlm@1: rlm@1: if(systemColorDepth != 32) { rlm@1: switch(filter) { rlm@1: case 0: rlm@1: filterFunction = NULL; rlm@1: break; rlm@1: case 1: rlm@1: filterFunction = ScanlinesTV; rlm@1: break; rlm@1: case 2: rlm@1: filterFunction = _2xSaI; rlm@1: break; rlm@1: case 3: rlm@1: filterFunction = Super2xSaI; rlm@1: break; rlm@1: case 4: rlm@1: filterFunction = SuperEagle; rlm@1: break; rlm@1: case 5: rlm@1: filterFunction = Pixelate2x16; rlm@1: break; rlm@1: case 6: rlm@1: filterFunction = MotionBlur; rlm@1: break; rlm@1: case 7: rlm@1: filterFunction = AdMame2x; rlm@1: break; rlm@1: case 8: rlm@1: filterFunction = Simple2x16; rlm@1: break; rlm@1: case 9: rlm@1: filterFunction = Bilinear; rlm@1: break; rlm@1: case 10: rlm@1: filterFunction = BilinearPlus; rlm@1: break; rlm@1: case 11: rlm@1: filterFunction = Scanlines; rlm@1: break; rlm@1: case 12: rlm@1: filterFunction = hq2x; rlm@1: break; rlm@1: case 13: rlm@1: filterFunction = lq2x; rlm@1: break; rlm@1: default: rlm@1: filterFunction = NULL; rlm@1: break; rlm@1: } rlm@1: } else { rlm@1: switch(filter) { rlm@1: case 0: rlm@1: filterFunction = NULL; rlm@1: break; rlm@1: case 1: rlm@1: filterFunction = ScanlinesTV32; rlm@1: break; rlm@1: case 2: rlm@1: filterFunction = _2xSaI32; rlm@1: break; rlm@1: case 3: rlm@1: filterFunction = Super2xSaI32; rlm@1: break; rlm@1: case 4: rlm@1: filterFunction = SuperEagle32; rlm@1: break; rlm@1: case 5: rlm@1: filterFunction = Pixelate2x32; rlm@1: break; rlm@1: case 6: rlm@1: filterFunction = MotionBlur32; rlm@1: break; rlm@1: case 7: rlm@1: filterFunction = AdMame2x32; rlm@1: break; rlm@1: case 8: rlm@1: filterFunction = Simple2x32; rlm@1: break; rlm@1: case 9: rlm@1: filterFunction = Bilinear32; rlm@1: break; rlm@1: case 10: rlm@1: filterFunction = BilinearPlus32; rlm@1: break; rlm@1: case 11: rlm@1: filterFunction = Scanlines32; rlm@1: break; rlm@1: case 12: rlm@1: filterFunction = hq2x32; rlm@1: break; rlm@1: case 13: rlm@1: filterFunction = lq2x32; rlm@1: break; rlm@1: default: rlm@1: filterFunction = NULL; rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: if(systemColorDepth == 16) { rlm@1: switch(ifbType) { rlm@1: case 0: rlm@1: default: rlm@1: ifbFunction = NULL; rlm@1: break; rlm@1: case 1: rlm@1: ifbFunction = MotionBlurIB; rlm@1: break; rlm@1: case 2: rlm@1: ifbFunction = SmartIB; rlm@1: break; rlm@1: } rlm@1: } else if(systemColorDepth == 32) { rlm@1: switch(ifbType) { rlm@1: case 0: rlm@1: default: rlm@1: ifbFunction = NULL; rlm@1: break; rlm@1: case 1: rlm@1: ifbFunction = MotionBlurIB32; rlm@1: break; rlm@1: case 2: rlm@1: ifbFunction = SmartIB32; rlm@1: break; rlm@1: } rlm@1: } else rlm@1: ifbFunction = NULL; rlm@1: rlm@1: if(delta == NULL) { rlm@1: delta = (u8*)malloc(322*242*4); rlm@1: memset(delta, 255, 322*242*4); rlm@1: } rlm@1: rlm@1: if(!soundOffFlag) rlm@1: soundInit(); rlm@1: rlm@1: autoFrameSkipLastTime = throttleLastTime = systemGetClock(); rlm@39: //printf("RLM: and now for the movie part!\n"); rlm@1: rlm@1: switch(useMovie) rlm@1: { rlm@1: case 1: // --recordMovie rlm@1: VBAMovieCreate(movieFileName, rlm@1: /*authorInfo*/"", rlm@1: /*startFlags*/0, rlm@1: /*controllerFlags*/MOVIE_CONTROLLER(0), rlm@1: /*typeFlags*/(systemCartridgeType==IMAGE_GBA)?(MOVIE_TYPE_GBA):(GBC_CAPABLE?MOVIE_TYPE_GBC:MOVIE_TYPE_SGB)); rlm@1: break; rlm@1: case 2: // --playMovie rlm@1: VBAMovieOpen(movieFileName, false); rlm@1: break; rlm@1: case 3: // --watchMovie rlm@1: VBAMovieOpen(movieFileName, true); rlm@1: break; rlm@1: default: rlm@1: sdlReadBattery(); rlm@1: break; rlm@1: } rlm@39: //printf("RLM: still alive after movie switch\n"); rlm@1: SDL_WM_SetCaption("VisualBoyAdvance", NULL); rlm@1: rlm@1: char *moviefile = getenv("AUTODEMO"); rlm@33: fprintf (stderr, "Checking for AUTODEMO...\n"); rlm@1: if (moviefile) rlm@1: { rlm@33: fprintf (stderr, "I got a filename OMG!\nCalling VBAMovieOpen...\n"); rlm@1: VBAMovieOpen(moviefile, true); rlm@1: } rlm@70: //step(); rlm@1: return 0; rlm@1: } rlm@1: rlm@49: // RLM rlm@49: int runVBA(int argc, char **argv){ rlm@49: return main(argc, argv); rlm@49: } rlm@49: rlm@49: rlm@53: rlm@53: rlm@53: rlm@53: rlm@53: rlm@1: void systemMessage(int num, const char *msg, ...) rlm@1: { rlm@1: char buffer[2048]; rlm@1: va_list valist; rlm@1: rlm@1: va_start(valist, msg); rlm@1: vsprintf(buffer, msg, valist); rlm@1: rlm@1: fprintf(stderr, "%s\n", buffer); rlm@1: va_end(valist); rlm@1: } rlm@1: rlm@1: //On WIN32, this function messages requesting rlm@1: //the window to be redrawn. Can this be ignored here? rlm@1: void systemRefreshScreen(){} rlm@1: rlm@1: void systemRenderFrame() rlm@1: { rlm@1: renderedFrames++; rlm@1: VBAUpdateFrameCountDisplay(); rlm@1: VBAUpdateButtonPressDisplay(); rlm@1: rlm@1: if(yuv) { rlm@1: Draw_Overlay(surface, sizeOption+1); rlm@1: return; rlm@1: } rlm@1: rlm@1: SDL_LockSurface(surface); rlm@1: rlm@1: for(int slot = 0 ; slot < 8 ; slot++) rlm@1: { rlm@1: if(screenMessage[slot]) { rlm@1: if(systemCartridgeType == 1 && gbBorderOn) { rlm@1: gbSgbRenderBorder(); rlm@1: } rlm@1: if(((systemGetClock() - screenMessageTime[slot]) < screenMessageDuration[slot]) && rlm@1: !disableStatusMessages) { rlm@1: drawText(pix, srcPitch, 10, srcHeight - 20*(slot+1), rlm@1: screenMessageBuffer[slot]); rlm@1: } else { rlm@1: screenMessage[slot] = false; rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: if(ifbFunction) { rlm@1: if(systemColorDepth == 16) rlm@1: ifbFunction(pix+destWidth+4, destWidth+4, srcWidth, srcHeight); rlm@1: else rlm@1: ifbFunction(pix+destWidth*2+4, destWidth*2+4, srcWidth, srcHeight); rlm@1: } rlm@1: rlm@1: if(filterFunction) { rlm@1: if(systemColorDepth == 16) rlm@1: filterFunction(pix+destWidth+4,destWidth+4, delta, rlm@1: (u8*)surface->pixels,surface->pitch, rlm@1: srcWidth, rlm@1: srcHeight); rlm@1: else rlm@1: filterFunction(pix+destWidth*2+4, rlm@1: destWidth*2+4, rlm@1: delta, rlm@1: (u8*)surface->pixels, rlm@1: surface->pitch, rlm@1: srcWidth, rlm@1: srcHeight); rlm@1: } else { rlm@1: int destPitch = surface->pitch; rlm@1: u8 *src = pix; rlm@1: u8 *dest = (u8*)surface->pixels; rlm@1: int i; rlm@1: u32 *stretcher = (u32 *)sdlStretcher; rlm@1: if(systemColorDepth == 16) rlm@1: src += srcPitch; rlm@1: int option = sizeOption; rlm@1: if(yuv) rlm@1: option = 0; rlm@1: switch(sizeOption) { rlm@1: case 0: rlm@1: for(i = 0; i < srcHeight; i++) { rlm@1: SDL_CALL_STRETCHER; rlm@1: src += srcPitch; rlm@1: dest += destPitch; rlm@1: } rlm@1: break; rlm@1: case 1: rlm@1: for(i = 0; i < srcHeight; i++) { rlm@1: SDL_CALL_STRETCHER; rlm@1: dest += destPitch; rlm@1: SDL_CALL_STRETCHER; rlm@1: src += srcPitch; rlm@1: dest += destPitch; rlm@1: } rlm@1: break; rlm@1: case 2: rlm@1: for(i = 0; i < srcHeight; i++) { rlm@1: SDL_CALL_STRETCHER; rlm@1: dest += destPitch; rlm@1: SDL_CALL_STRETCHER; rlm@1: dest += destPitch; rlm@1: SDL_CALL_STRETCHER; rlm@1: src += srcPitch; rlm@1: dest += destPitch; rlm@1: } rlm@1: break; rlm@1: case 3: rlm@1: for(i = 0; i < srcHeight; i++) { rlm@1: SDL_CALL_STRETCHER; rlm@1: dest += destPitch; rlm@1: SDL_CALL_STRETCHER; rlm@1: dest += destPitch; rlm@1: SDL_CALL_STRETCHER; rlm@1: dest += destPitch; rlm@1: SDL_CALL_STRETCHER; rlm@1: src += srcPitch; rlm@1: dest += destPitch; rlm@1: } rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: if(showSpeed && fullscreen) { rlm@1: char buffer[50]; rlm@1: if(showSpeed == 1) rlm@1: sprintf(buffer, "%d%%", systemSpeed); rlm@1: else rlm@1: sprintf(buffer, "%3d%%(%d, %d fps)", systemSpeed, rlm@1: systemFrameSkip, rlm@1: showRenderedFrames); rlm@1: if(showSpeedTransparent) rlm@1: drawTextTransp((u8*)surface->pixels, rlm@1: surface->pitch, rlm@1: 10, rlm@1: surface->h-20, rlm@1: buffer); rlm@1: else rlm@1: drawText((u8*)surface->pixels, rlm@1: surface->pitch, rlm@1: 10, rlm@1: surface->h-20, rlm@1: buffer); rlm@1: } rlm@1: rlm@1: SDL_UnlockSurface(surface); rlm@1: // SDL_UpdateRect(surface, 0, 0, destWidth, destHeight); rlm@1: SDL_Flip(surface); rlm@1: } rlm@1: rlm@1: bool systemReadJoypads() rlm@1: { rlm@1: return true; rlm@1: } rlm@1: rlm@1: // Kludge to make Lua call the right function. rlm@1: u32 systemGetOriginalJoypad(int which, bool sensor){ rlm@1: return systemGetJoypad(which,sensor); rlm@1: } rlm@1: rlm@1: u32 systemGetJoypad(int which, bool sensor) rlm@1: { rlm@1: sensorOn = sensor; rlm@1: if(which < 0 || which > 3) rlm@1: which = sdlDefaultJoypad; rlm@1: rlm@1: //VBAMovieUpdate(which); rlm@1: //VBAMovieUpdateState(); rlm@1: u32 res = 0; rlm@1: rlm@1: //----------------------------// rlm@1: if (VBAMoviePlaying()){ rlm@1: // VBAMovieRead() overwrites currentButtons[i] rlm@1: VBAMovieRead(which, sensor); rlm@1: res = currentButtons[which]; rlm@1: return res; rlm@1: } rlm@1: //---------------------------// rlm@1: //Temporary implementation, not sure if it's correct --Felipe rlm@1: rlm@1: /* rlm@1: if(sdlButtons[which][KEY_BUTTON_A]) rlm@1: res |= BUTTON_MASK_A; rlm@1: if(sdlButtons[which][KEY_BUTTON_B]) rlm@1: res |= BUTTON_MASK_B; rlm@1: if(sdlButtons[which][KEY_BUTTON_SELECT]) rlm@1: res |= BUTTON_MASK_SELECT; rlm@1: if(sdlButtons[which][KEY_BUTTON_START]) rlm@1: res |= BUTTON_MASK_START; rlm@1: if(sdlButtons[which][KEY_RIGHT]) rlm@1: res |= BUTTON_MASK_RIGHT; rlm@1: if(sdlButtons[which][KEY_LEFT]) rlm@1: res |= BUTTON_MASK_LEFT; rlm@1: if(sdlButtons[which][KEY_UP]) rlm@1: res |= BUTTON_MASK_UP; rlm@1: if(sdlButtons[which][KEY_DOWN]) rlm@1: res |= BUTTON_MASK_DOWN; rlm@1: if(sdlButtons[which][KEY_BUTTON_R]) rlm@1: res |= BUTTON_MASK_R; rlm@1: if(sdlButtons[which][KEY_BUTTON_L]) rlm@1: res |= BUTTON_MASK_L; rlm@1: */ rlm@1: /* rlm@1: // disallow L+R or U+D of being pressed at the same time rlm@1: if((res & 48) == 48) rlm@1: res &= ~16; rlm@1: if((res & 192) == 192) rlm@1: res &= ~128; rlm@1: */ rlm@1: /* rlm@1: if(sdlbuttons[which][KEY_BUTTON_SPEED]) rlm@1: res |= 1024; rlm@1: if(sdlButtons[which][KEY_BUTTON_CAPTURE]) rlm@1: res |= 2048; rlm@1: */ rlm@1: res = currentButtons[which]; rlm@1: rlm@1: if(autoFire) { rlm@1: res &= (~autoFire); rlm@1: if(autoFireToggle) rlm@1: res |= autoFire; rlm@1: autoFireToggle = !autoFireToggle; rlm@1: } rlm@1: rlm@1: //if (res) fprintf(stdout,"%x\n",res); rlm@1: rlm@1: return res; rlm@1: } rlm@1: rlm@1: void systemSetJoypad(int which, u32 buttons) rlm@1: { rlm@1: if(which < 0 || which > 3) rlm@1: which = sdlDefaultJoypad; rlm@1: /* rlm@1: sdlButtons[which][KEY_BUTTON_A] = (buttons & 1) != 0; rlm@1: sdlButtons[which][KEY_BUTTON_B] = (buttons & 2) != 0; rlm@1: sdlButtons[which][KEY_BUTTON_SELECT] = (buttons & 4) != 0; rlm@1: sdlButtons[which][KEY_BUTTON_START] = (buttons & 8) != 0; rlm@1: sdlButtons[which][KEY_RIGHT] = (buttons & 16) != 0; rlm@1: sdlButtons[which][KEY_LEFT] = (buttons & 32) != 0; rlm@1: sdlButtons[which][KEY_UP] = (buttons & 64) != 0; rlm@1: sdlButtons[which][KEY_DOWN] = (buttons & 128) != 0; rlm@1: sdlButtons[which][KEY_BUTTON_R] = (buttons & 256) != 0; rlm@1: sdlButtons[which][KEY_BUTTON_L] = (buttons & 512) != 0; rlm@1: */ rlm@1: currentButtons[which]= buttons & 0x3ff; rlm@1: } rlm@1: rlm@1: void systemClearJoypads() rlm@1: { rlm@1: for (int i = 0; i < 4; ++i) rlm@1: currentButtons[i] = 0; rlm@1: rlm@1: //lastKeys = 0; rlm@1: } rlm@1: rlm@1: void systemSetTitle(const char *title) rlm@1: { rlm@1: SDL_WM_SetCaption(title, NULL); rlm@1: } rlm@1: rlm@1: void systemShowSpeed(int speed) rlm@1: { rlm@1: systemSpeed = speed; rlm@1: rlm@1: showRenderedFrames = renderedFrames; rlm@1: renderedFrames = 0; rlm@1: rlm@1: if(!fullscreen && showSpeed) { rlm@1: char buffer[80]; rlm@1: if(showSpeed == 1) rlm@1: sprintf(buffer, "VisualBoyAdvance-%3d%%", systemSpeed); rlm@1: else rlm@1: sprintf(buffer, "VisualBoyAdvance-%3d%%(%d, %d fps)", systemSpeed, rlm@1: systemFrameSkip, rlm@1: showRenderedFrames); rlm@1: rlm@1: systemSetTitle(buffer); rlm@1: } rlm@1: } rlm@1: rlm@1: // FIXME: the timing rlm@1: void systemFrame(/*int rate*/) //Looking at System.cpp, it looks like rate should be 600 rlm@1: { rlm@1: u32 time = systemGetClock(); rlm@1: if(!wasPaused && autoFrameSkip && !throttle) { rlm@1: u32 diff = time - autoFrameSkipLastTime; rlm@1: int speed = 100; rlm@1: rlm@1: if(diff) rlm@1: speed = (1000000/600)/diff; rlm@1: rlm@1: if(speed >= 98) { rlm@1: frameskipadjust++; rlm@1: rlm@1: if(frameskipadjust >= 3) { rlm@1: frameskipadjust=0; rlm@1: if(systemFrameSkip > 0) rlm@1: systemFrameSkip--; rlm@1: } rlm@1: } else { rlm@1: if(speed < 80) rlm@1: frameskipadjust -= (90 - speed)/5; rlm@1: else if(systemFrameSkip < 9) rlm@1: frameskipadjust--; rlm@1: rlm@1: if(frameskipadjust <= -2) { rlm@1: frameskipadjust += 2; rlm@1: if(systemFrameSkip < 9) rlm@1: systemFrameSkip++; rlm@1: } rlm@1: } rlm@1: } rlm@1: if(!wasPaused && throttle) { rlm@1: /*if(!speedup) { rlm@1: u32 diff = time - throttleLastTime; rlm@1: rlm@1: int target = (1000000.0/(600*throttle)); rlm@1: int d = (target - diff); rlm@1: rlm@1: if(d > 0) { rlm@1: SDL_Delay(d); rlm@1: } rlm@1: } rlm@1: throttleLastTime = systemGetClock(); rlm@1: */ rlm@1: } rlm@1: if(rewindMemory) { rlm@1: if(++rewindCounter >= rewindTimer) { rlm@1: rewindSaveNeeded = true; rlm@1: rewindCounter = 0; rlm@1: } rlm@1: } rlm@1: rlm@1: if(systemSaveUpdateCounter) { rlm@1: if(--systemSaveUpdateCounter <= SYSTEM_SAVE_NOT_UPDATED) { rlm@1: sdlWriteBattery(); rlm@1: systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; rlm@1: } rlm@1: } rlm@1: rlm@1: wasPaused = false; rlm@1: autoFrameSkipLastTime = time; rlm@1: } rlm@1: rlm@1: int systemFramesToSkip(){ rlm@1: return systemFrameSkip; rlm@1: } rlm@1: rlm@1: int systemScreenCapture(int a) rlm@1: { rlm@1: char buffer[2048]; rlm@1: rlm@1: if(captureFormat) { rlm@1: if(captureDir[0]) rlm@1: sprintf(buffer, "%s/%s%02d.bmp", captureDir, sdlGetFilename(filename), a); rlm@1: else rlm@1: sprintf(buffer, "%s%02d.bmp", filename, a); rlm@1: rlm@1: theEmulator.emuWriteBMP(buffer); rlm@1: } else { rlm@1: if(captureDir[0]) rlm@1: sprintf(buffer, "%s/%s%02d.png", captureDir, sdlGetFilename(filename), a); rlm@1: else rlm@1: sprintf(buffer, "%s%02d.png", filename, a); rlm@1: theEmulator.emuWritePNG(buffer); rlm@1: } rlm@1: rlm@1: systemScreenMessage("Screen capture"); rlm@1: return a; rlm@1: } rlm@1: rlm@1: void soundCallback(void *,u8 *stream,int len){} rlm@1: rlm@1: void systemSoundWriteToBuffer(){ rlm@1: soundDriver->write(soundFinalWave, soundBufferLen); rlm@1: } rlm@1: rlm@1: void systemSoundClearBuffer() rlm@1: { rlm@1: SDL_mutexP(mutex); rlm@1: memset(sdlBuffer,0,soundBufferTotalLen); rlm@1: sdlSoundLen=0; rlm@1: printf("Hi\n"); rlm@1: SDL_mutexV(mutex); rlm@1: } rlm@1: rlm@1: bool systemSoundInit(){ rlm@1: systemSoundShutdown(); rlm@1: soundDriver = new SoundSDL(); rlm@1: if ( !soundDriver ) rlm@1: return false; rlm@1: rlm@1: if (!soundDriver->init()) //<-- sound sample rate rlm@1: return false; rlm@1: rlm@1: if (!(soundDriver->setThrottle(throttle))){ rlm@1: fprintf(stderr,"Failed to set desired throttle, defaulting to 100 %%.\n"); rlm@1: if (!soundDriver->setThrottle(100)) return false; rlm@1: } rlm@1: soundPaused = true; rlm@1: systemSoundOn = true; rlm@1: return true; rlm@1: } rlm@1: rlm@1: void systemSoundShutdown(){ rlm@1: if (soundDriver) rlm@1: { rlm@1: delete soundDriver; rlm@1: soundDriver = 0; rlm@1: } rlm@1: } rlm@1: rlm@1: void systemSoundPause() rlm@1: { rlm@1: SDL_PauseAudio(1); rlm@1: } rlm@1: rlm@1: void systemSoundResume() rlm@1: { rlm@1: SDL_PauseAudio(0); rlm@1: } rlm@1: rlm@1: void systemSoundReset() rlm@1: { rlm@1: } rlm@1: rlm@1: u32 systemGetClock() rlm@1: { rlm@1: return SDL_GetTicks(); rlm@1: } rlm@1: rlm@1: void systemUpdateMotionSensor() rlm@1: { rlm@1: if(sdlMotionButtons[KEY_LEFT]) { rlm@1: sensorX += 3; rlm@1: if(sensorX > 2197) rlm@1: sensorX = 2197; rlm@1: if(sensorX < 2047) rlm@1: sensorX = 2057; rlm@1: } else if(sdlMotionButtons[KEY_RIGHT]) { rlm@1: sensorX -= 3; rlm@1: if(sensorX < 1897) rlm@1: sensorX = 1897; rlm@1: if(sensorX > 2047) rlm@1: sensorX = 2037; rlm@1: } else if(sensorX > 2047) { rlm@1: sensorX -= 2; rlm@1: if(sensorX < 2047) rlm@1: sensorX = 2047; rlm@1: } else { rlm@1: sensorX += 2; rlm@1: if(sensorX > 2047) rlm@1: sensorX = 2047; rlm@1: } rlm@1: rlm@1: if(sdlMotionButtons[KEY_UP]) { rlm@1: sensorY += 3; rlm@1: if(sensorY > 2197) rlm@1: sensorY = 2197; rlm@1: if(sensorY < 2047) rlm@1: sensorY = 2057; rlm@1: } else if(sdlMotionButtons[KEY_DOWN]) { rlm@1: sensorY -= 3; rlm@1: if(sensorY < 1897) rlm@1: sensorY = 1897; rlm@1: if(sensorY > 2047) rlm@1: sensorY = 2037; rlm@1: } else if(sensorY > 2047) { rlm@1: sensorY -= 2; rlm@1: if(sensorY < 2047) rlm@1: sensorY = 2047; rlm@1: } else { rlm@1: sensorY += 2; rlm@1: if(sensorY > 2047) rlm@1: sensorY = 2047; rlm@1: } rlm@1: } rlm@1: rlm@1: void systemResetSensor() rlm@1: { rlm@1: sensorX = sensorY = INITIAL_SENSOR_VALUE; rlm@1: } rlm@1: rlm@1: int systemGetSensorX() rlm@1: { rlm@1: return sensorX; rlm@1: } rlm@1: rlm@1: int systemGetSensorY() rlm@1: { rlm@1: return sensorY; rlm@1: } rlm@1: rlm@1: void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast) rlm@1: { rlm@1: } rlm@1: rlm@1: void systemScreenMessage(const char *msg, int slot, int duration, const char *colorList) rlm@1: { rlm@1: screenMessage[slot] = true; rlm@1: screenMessageTime[slot] = systemGetClock(); rlm@1: screenMessageDuration[slot] = duration; rlm@1: if(strlen(msg) > 20) { rlm@1: strncpy(screenMessageBuffer[slot], msg, 20); rlm@1: screenMessageBuffer[slot][20] = 0; rlm@1: } else rlm@1: strcpy(screenMessageBuffer[slot], msg); rlm@1: } rlm@1: rlm@1: bool systemSoundCanChangeQuality() rlm@1: { rlm@1: return false; rlm@1: } rlm@1: rlm@1: bool systemSoundSetQuality(int quality) rlm@1: { rlm@1: if (systemCartridgeType == 0) rlm@1: soundSetQuality(quality); rlm@1: else rlm@1: gbSoundSetQuality(quality); rlm@1: rlm@1: return true; rlm@1: } rlm@1: rlm@1: bool systemPauseOnFrame() rlm@1: { rlm@1: if(pauseNextFrame) { rlm@1: paused = true; rlm@1: pauseNextFrame = false; rlm@1: return true; rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: // Code donated by Niels Wagenaar (BoycottAdvance) rlm@1: rlm@1: // GBA screensize. rlm@1: #define GBA_WIDTH 240 rlm@1: #define GBA_HEIGHT 160 rlm@1: rlm@1: void Init_Overlay(SDL_Surface *gbascreen, int overlaytype) rlm@1: { rlm@1: rlm@1: overlay = SDL_CreateYUVOverlay( GBA_WIDTH, rlm@1: GBA_HEIGHT, rlm@1: overlaytype, gbascreen); rlm@1: fprintf(stderr, "Created %dx%dx%d %s %s overlay\n", rlm@1: overlay->w,overlay->h,overlay->planes, rlm@1: overlay->hw_overlay?"hardware":"software", rlm@1: overlay->format==SDL_YV12_OVERLAY?"YV12": rlm@1: overlay->format==SDL_IYUV_OVERLAY?"IYUV": rlm@1: overlay->format==SDL_YUY2_OVERLAY?"YUY2": rlm@1: overlay->format==SDL_UYVY_OVERLAY?"UYVY": rlm@1: overlay->format==SDL_YVYU_OVERLAY?"YVYU": rlm@1: "Unknown"); rlm@1: } rlm@1: rlm@1: void Quit_Overlay(void) rlm@1: { rlm@1: rlm@1: SDL_FreeYUVOverlay(overlay); rlm@1: } rlm@1: rlm@1: /* NOTE: These RGB conversion functions are not intended for speed, rlm@1: only as examples. rlm@1: */ rlm@1: inline void RGBtoYUV(Uint8 *rgb, int *yuv) rlm@1: { rlm@1: yuv[0] = (int)((0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16); rlm@1: yuv[1] = (int)(128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2])); rlm@1: yuv[2] = (int)(128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2])); rlm@1: } rlm@1: rlm@1: inline void ConvertRGBtoYV12(SDL_Overlay *o) rlm@1: { rlm@1: int x,y; rlm@1: int yuv[3]; rlm@1: Uint8 *p,*op[3]; rlm@1: rlm@1: SDL_LockYUVOverlay(o); rlm@1: rlm@1: /* Black initialization */ rlm@1: /* rlm@1: memset(o->pixels[0],0,o->pitches[0]*o->h); rlm@1: memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2)); rlm@1: memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2)); rlm@1: */ rlm@1: rlm@1: /* Convert */ rlm@1: for(y=0; y<160 && yh; y++) { rlm@1: p=(Uint8 *)pix+srcPitch*y; rlm@1: op[0]=o->pixels[0]+o->pitches[0]*y; rlm@1: op[1]=o->pixels[1]+o->pitches[1]*(y/2); rlm@1: op[2]=o->pixels[2]+o->pitches[2]*(y/2); rlm@1: for(x=0; x<240 && xw; x++) { rlm@1: RGBtoYUV(p,yuv); rlm@1: *(op[0]++)=yuv[0]; rlm@1: if(x%2==0 && y%2==0) { rlm@1: *(op[1]++)=yuv[2]; rlm@1: *(op[2]++)=yuv[1]; rlm@1: } rlm@1: p+=4;//s->format->BytesPerPixel; rlm@1: } rlm@1: } rlm@1: rlm@1: SDL_UnlockYUVOverlay(o); rlm@1: } rlm@1: rlm@1: inline void ConvertRGBtoIYUV(SDL_Overlay *o) rlm@1: { rlm@1: int x,y; rlm@1: int yuv[3]; rlm@1: Uint8 *p,*op[3]; rlm@1: rlm@1: SDL_LockYUVOverlay(o); rlm@1: rlm@1: /* Black initialization */ rlm@1: /* rlm@1: memset(o->pixels[0],0,o->pitches[0]*o->h); rlm@1: memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2)); rlm@1: memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2)); rlm@1: */ rlm@1: rlm@1: /* Convert */ rlm@1: for(y=0; y<160 && yh; y++) { rlm@1: p=(Uint8 *)pix+srcPitch*y; rlm@1: op[0]=o->pixels[0]+o->pitches[0]*y; rlm@1: op[1]=o->pixels[1]+o->pitches[1]*(y/2); rlm@1: op[2]=o->pixels[2]+o->pitches[2]*(y/2); rlm@1: for(x=0; x<240 && xw; x++) { rlm@1: RGBtoYUV(p,yuv); rlm@1: *(op[0]++)=yuv[0]; rlm@1: if(x%2==0 && y%2==0) { rlm@1: *(op[1]++)=yuv[1]; rlm@1: *(op[2]++)=yuv[2]; rlm@1: } rlm@1: p+=4; //s->format->BytesPerPixel; rlm@1: } rlm@1: } rlm@1: rlm@1: SDL_UnlockYUVOverlay(o); rlm@1: } rlm@1: rlm@1: inline void ConvertRGBtoUYVY(SDL_Overlay *o) rlm@1: { rlm@1: int x,y; rlm@1: int yuv[3]; rlm@1: Uint8 *p,*op; rlm@1: rlm@1: SDL_LockYUVOverlay(o); rlm@1: rlm@1: for(y=0; y<160 && yh; y++) { rlm@1: p=(Uint8 *)pix+srcPitch*y; rlm@1: op=o->pixels[0]+o->pitches[0]*y; rlm@1: for(x=0; x<240 && xw; x++) { rlm@1: RGBtoYUV(p,yuv); rlm@1: if(x%2==0) { rlm@1: *(op++)=yuv[1]; rlm@1: *(op++)=yuv[0]; rlm@1: *(op++)=yuv[2]; rlm@1: } else rlm@1: *(op++)=yuv[0]; rlm@1: rlm@1: p+=4; //s->format->BytesPerPixel; rlm@1: } rlm@1: } rlm@1: rlm@1: SDL_UnlockYUVOverlay(o); rlm@1: } rlm@1: rlm@1: inline void ConvertRGBtoYVYU(SDL_Overlay *o) rlm@1: { rlm@1: int x,y; rlm@1: int yuv[3]; rlm@1: Uint8 *p,*op; rlm@1: rlm@1: SDL_LockYUVOverlay(o); rlm@1: rlm@1: for(y=0; y<160 && yh; y++) { rlm@1: p=(Uint8 *)pix+srcPitch*y; rlm@1: op=o->pixels[0]+o->pitches[0]*y; rlm@1: for(x=0; x<240 && xw; x++) { rlm@1: RGBtoYUV(p,yuv); rlm@1: if(x%2==0) { rlm@1: *(op++)=yuv[0]; rlm@1: *(op++)=yuv[2]; rlm@1: op[1]=yuv[1]; rlm@1: } else { rlm@1: *op=yuv[0]; rlm@1: op+=2; rlm@1: } rlm@1: rlm@1: p+=4; //s->format->BytesPerPixel; rlm@1: } rlm@1: } rlm@1: rlm@1: SDL_UnlockYUVOverlay(o); rlm@1: } rlm@1: rlm@1: inline void ConvertRGBtoYUY2(SDL_Overlay *o) rlm@1: { rlm@1: int x,y; rlm@1: int yuv[3]; rlm@1: Uint8 *p,*op; rlm@1: rlm@1: SDL_LockYUVOverlay(o); rlm@1: rlm@1: for(y=0; y<160 && yh; y++) { rlm@1: p=(Uint8 *)pix+srcPitch*y; rlm@1: op=o->pixels[0]+o->pitches[0]*y; rlm@1: for(x=0; x<240 && xw; x++) { rlm@1: RGBtoYUV(p,yuv); rlm@1: if(x%2==0) { rlm@1: *(op++)=yuv[0]; rlm@1: *(op++)=yuv[1]; rlm@1: op[1]=yuv[2]; rlm@1: } else { rlm@1: *op=yuv[0]; rlm@1: op+=2; rlm@1: } rlm@1: rlm@1: p+=4; //s->format->BytesPerPixel; rlm@1: } rlm@1: } rlm@1: rlm@1: SDL_UnlockYUVOverlay(o); rlm@1: } rlm@1: rlm@1: inline void Convert32bit(SDL_Surface *display) rlm@1: { rlm@1: switch(overlay->format) { rlm@1: case SDL_YV12_OVERLAY: rlm@1: ConvertRGBtoYV12(overlay); rlm@1: break; rlm@1: case SDL_UYVY_OVERLAY: rlm@1: ConvertRGBtoUYVY(overlay); rlm@1: break; rlm@1: case SDL_YVYU_OVERLAY: rlm@1: ConvertRGBtoYVYU(overlay); rlm@1: break; rlm@1: case SDL_YUY2_OVERLAY: rlm@1: ConvertRGBtoYUY2(overlay); rlm@1: break; rlm@1: case SDL_IYUV_OVERLAY: rlm@1: ConvertRGBtoIYUV(overlay); rlm@1: break; rlm@1: default: rlm@1: fprintf(stderr, "cannot convert RGB picture to obtained YUV format!\n"); rlm@1: exit(1); rlm@1: break; rlm@1: } rlm@1: rlm@1: } rlm@1: rlm@1: rlm@1: inline void Draw_Overlay(SDL_Surface *display, int size) rlm@1: { rlm@1: SDL_LockYUVOverlay(overlay); rlm@1: rlm@1: Convert32bit(display); rlm@1: rlm@1: overlay_rect.x = 0; rlm@1: overlay_rect.y = 0; rlm@1: overlay_rect.w = GBA_WIDTH * size; rlm@1: overlay_rect.h = GBA_HEIGHT * size; rlm@1: rlm@1: SDL_DisplayYUVOverlay(overlay, &overlay_rect); rlm@1: SDL_UnlockYUVOverlay(overlay); rlm@1: } rlm@1: rlm@1: bool systemIsEmulating() rlm@1: { rlm@1: return emulating != 0; rlm@1: } rlm@1: rlm@1: void systemGbBorderOn() rlm@1: { rlm@1: srcWidth = 256; rlm@1: srcHeight = 224; rlm@1: gbBorderLineSkip = 256; rlm@1: gbBorderColumnSkip = 48; rlm@1: gbBorderRowSkip = 40; rlm@1: rlm@1: destWidth = (sizeOption+1)*srcWidth; rlm@1: destHeight = (sizeOption+1)*srcHeight; rlm@1: rlm@1: surface = SDL_SetVideoMode(destWidth, destHeight, 16, rlm@1: SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF| rlm@1: (fullscreen ? SDL_FULLSCREEN : 0)); rlm@1: #ifndef C_CORE rlm@1: sdlMakeStretcher(srcWidth); rlm@1: #else rlm@1: switch(systemColorDepth) { rlm@1: case 16: rlm@1: sdlStretcher = sdlStretcher16[sizeOption]; rlm@1: break; rlm@1: case 24: rlm@1: sdlStretcher = sdlStretcher24[sizeOption]; rlm@1: break; rlm@1: case 32: rlm@1: sdlStretcher = sdlStretcher32[sizeOption]; rlm@1: break; rlm@1: default: rlm@1: fprintf(stderr, "Unsupported resolution: %d\n", systemColorDepth); rlm@1: exit(-1); rlm@1: } rlm@1: #endif rlm@1: rlm@1: if(systemColorDepth == 16) { rlm@1: if(sdlCalculateMaskWidth(surface->format->Gmask) == 6) { rlm@1: Init_2xSaI(565); rlm@1: RGB_LOW_BITS_MASK = 0x821; rlm@1: } else { rlm@1: Init_2xSaI(555); rlm@1: RGB_LOW_BITS_MASK = 0x421; rlm@1: } rlm@1: if(systemCartridgeType == 2) { rlm@1: for(int i = 0; i < 0x10000; i++) { rlm@1: systemColorMap16[i] = (((i >> 1) & 0x1f) << systemBlueShift) | rlm@1: (((i & 0x7c0) >> 6) << systemGreenShift) | rlm@1: (((i & 0xf800) >> 11) << systemRedShift); rlm@1: } rlm@1: } else { rlm@1: for(int i = 0; i < 0x10000; i++) { rlm@1: systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | rlm@1: (((i & 0x3e0) >> 5) << systemGreenShift) | rlm@1: (((i & 0x7c00) >> 10) << systemBlueShift); rlm@1: } rlm@1: } rlm@1: srcPitch = srcWidth * 2+4; rlm@1: } else { rlm@1: if(systemColorDepth != 32) rlm@1: filterFunction = NULL; rlm@1: RGB_LOW_BITS_MASK = 0x010101; rlm@1: if(systemColorDepth == 32) { rlm@1: Init_2xSaI(32); rlm@1: } rlm@1: for(int i = 0; i < 0x10000; i++) { rlm@1: systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | rlm@1: (((i & 0x3e0) >> 5) << systemGreenShift) | rlm@1: (((i & 0x7c00) >> 10) << systemBlueShift); rlm@1: } rlm@1: if(systemColorDepth == 32) rlm@1: srcPitch = srcWidth*4 + 4; rlm@1: else rlm@1: srcPitch = srcWidth*3; rlm@1: } rlm@1: } rlm@1: rlm@1: bool systemIsRunningGBA() rlm@1: { rlm@1: return (rom != NULL); rlm@1: } rlm@1: rlm@1: int systemGetDefaultJoypad() rlm@1: { rlm@1: return sdlDefaultJoypad; rlm@1: } rlm@1: rlm@1: bool systemIsPaused() rlm@1: { rlm@1: return paused; rlm@1: } rlm@1: rlm@1: void systemSetPause(bool pause) rlm@1: { rlm@1: paused = pause; rlm@1: if (pause) rlm@1: systemSoundPause(); rlm@1: else rlm@1: systemSoundResume(); rlm@1: } rlm@1: rlm@1: u16 checksumBIOS() rlm@1: { rlm@1: bool hasBIOS = false; rlm@1: u8 * tempBIOS; rlm@1: if(useBios) rlm@1: { rlm@1: tempBIOS = (u8 *)malloc(0x4000); rlm@1: int size = 0x4000; rlm@1: if(utilLoad(biosFileName, rlm@1: utilIsGBABios, rlm@1: tempBIOS, rlm@1: size)) { rlm@1: if(size == 0x4000) rlm@1: hasBIOS = true; rlm@1: } rlm@1: } rlm@1: rlm@1: u16 biosCheck = 0; rlm@1: if(hasBIOS) { rlm@1: for(int i = 0; i < 0x4000; i += 4) rlm@1: biosCheck += *((u32 *)&tempBIOS[i]); rlm@1: free(tempBIOS); rlm@1: } rlm@1: rlm@1: return biosCheck; rlm@1: } rlm@1: rlm@1: EmulatedSystemCounters systemCounters = { rlm@1: 0, //framecount rlm@1: 0, //lagcount rlm@1: 0, //extracount rlm@1: true, //lagged rlm@1: true //laggedLast rlm@1: }; rlm@1: rlm@1: void VBAOnEnteringFrameBoundary() rlm@1: { rlm@39: //printf("RLM: Entering Frame Boundary\n"); rlm@33: CallRegisteredLuaFunctions(LUACALL_AFTEREMULATION); rlm@33: rlm@33: if (VBALuaRunning()) rlm@33: { rlm@33: VBALuaFrameBoundary(); rlm@33: } rlm@33: rlm@39: //printf("RLM: Movie state update pending\n"); rlm@33: VBAMovieUpdateState(); rlm@39: //printf("RLM: Movie state updated\n"); rlm@1: } rlm@1: rlm@1: void VBAOnExitingFrameBoundary() rlm@1: { rlm@1: ; rlm@1: } rlm@1: rlm@1: