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