rlm@1
|
1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
rlm@1
|
2 // Copyright (C) 1999-2003 Forgotten
|
rlm@1
|
3 // Copyright (C) 2004 Forgotten and the VBA development team
|
rlm@1
|
4
|
rlm@1
|
5 // This program is free software; you can redistribute it and/or modify
|
rlm@1
|
6 // it under the terms of the GNU General Public License as published by
|
rlm@1
|
7 // the Free Software Foundation; either version 2, or(at your option)
|
rlm@1
|
8 // any later version.
|
rlm@1
|
9 //
|
rlm@1
|
10 // This program is distributed in the hope that it will be useful,
|
rlm@1
|
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
rlm@1
|
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
rlm@1
|
13 // GNU General Public License for more details.
|
rlm@1
|
14 //
|
rlm@1
|
15 // You should have received a copy of the GNU General Public License
|
rlm@1
|
16 // along with this program; if not, write to the Free Software Foundation,
|
rlm@1
|
17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
rlm@1
|
18
|
rlm@1
|
19 #include <stdarg.h>
|
rlm@1
|
20 #include <stdlib.h>
|
rlm@1
|
21 #include <stdio.h>
|
rlm@1
|
22 #include <string.h>
|
rlm@1
|
23 #include <sys/types.h>
|
rlm@1
|
24 #include <sys/stat.h>
|
rlm@30
|
25 #include <config.h>
|
rlm@1
|
26 #include "AutoBuild.h"
|
rlm@1
|
27
|
rlm@1
|
28 #include "Port.h"
|
rlm@1
|
29 #include "SDL.h"
|
rlm@1
|
30 #include "debugger.h"
|
rlm@1
|
31 #include "gba/GBA.h"
|
rlm@1
|
32 #include "gba/GBAGlobals.h"
|
rlm@1
|
33 #include "gba/agbprint.h"
|
rlm@1
|
34 #include "gba/Flash.h"
|
rlm@1
|
35 #include "gba/RTC.h"
|
rlm@1
|
36 #include "gba/GBASound.h"
|
rlm@1
|
37 #include "gb/GB.h"
|
rlm@1
|
38 #include "gb/gbGlobals.h"
|
rlm@1
|
39 #include "common/Text.h"
|
rlm@1
|
40 #include "common/unzip.h"
|
rlm@1
|
41 #include "common/Util.h"
|
rlm@1
|
42 #include "common/movie.h"
|
rlm@1
|
43 #include "common/System.h"
|
rlm@1
|
44 #include "common/inputGlobal.h"
|
rlm@1
|
45 #include "../common/vbalua.h"
|
rlm@1
|
46 #include "SoundSDL.h"
|
rlm@1
|
47
|
rlm@1
|
48
|
rlm@1
|
49 #define GBC_CAPABLE ((gbRom[0x143] & 0x80) != 0)
|
rlm@1
|
50 #define SGB_CAPABLE (gbRom[0x146] == 0x03)
|
rlm@1
|
51
|
rlm@1
|
52 #ifndef WIN32
|
rlm@1
|
53 # include <unistd.h>
|
rlm@1
|
54 # define GETCWD getcwd
|
rlm@1
|
55 #else // WIN32
|
rlm@1
|
56 # include <direct.h>
|
rlm@1
|
57 # define GETCWD _getcwd
|
rlm@1
|
58 #endif // WIN32
|
rlm@1
|
59
|
rlm@1
|
60 #ifndef __GNUC__
|
rlm@1
|
61 # define HAVE_DECL_GETOPT 0
|
rlm@1
|
62 # define __STDC__ 1
|
rlm@1
|
63 # include "getopt.h"
|
rlm@1
|
64 #else // ! __GNUC__
|
rlm@1
|
65 # define HAVE_DECL_GETOPT 1
|
rlm@1
|
66 # include "getopt.h"
|
rlm@1
|
67 #endif // ! __GNUC__
|
rlm@1
|
68
|
rlm@1
|
69 #ifdef MMX
|
rlm@1
|
70 extern "C" bool cpu_mmx;
|
rlm@1
|
71 #endif
|
rlm@1
|
72 extern bool8 soundEcho;
|
rlm@1
|
73 extern bool8 soundLowPass;
|
rlm@1
|
74 extern bool8 soundReverse;
|
rlm@1
|
75 extern int Init_2xSaI(u32);
|
rlm@1
|
76 extern void _2xSaI(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
77 extern void _2xSaI32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
78 extern void Super2xSaI(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
79 extern void Super2xSaI32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
80 extern void SuperEagle(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
81 extern void SuperEagle32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
82 extern void Pixelate2x16(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
83 extern void Pixelate2x32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
84 extern void MotionBlur(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
85 extern void MotionBlur32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
86 extern void AdMame2x(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
87 extern void AdMame2x32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
88 extern void Simple2x16(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
89 extern void Simple2x32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
90 extern void Bilinear(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
91 extern void Bilinear32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
92 extern void BilinearPlus(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
93 extern void BilinearPlus32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
94 extern void Scanlines(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
95 extern void Scanlines32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
96 extern void ScanlinesTV(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
97 extern void ScanlinesTV32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
98 extern void hq2x(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
99 extern void hq2x32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
100 extern void lq2x(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
101 extern void lq2x32(u8*,u32,u8*,u8*,u32,int,int);
|
rlm@1
|
102
|
rlm@1
|
103 extern void SmartIB(u8*,u32,int,int);
|
rlm@1
|
104 extern void SmartIB32(u8*,u32,int,int);
|
rlm@1
|
105 extern void MotionBlurIB(u8*,u32,int,int);
|
rlm@1
|
106 extern void MotionBlurIB32(u8*,u32,int,int);
|
rlm@1
|
107
|
rlm@1
|
108 void Init_Overlay(SDL_Surface *surface, int overlaytype);
|
rlm@1
|
109 void Quit_Overlay(void);
|
rlm@1
|
110 void Draw_Overlay(SDL_Surface *surface, int size);
|
rlm@1
|
111
|
rlm@1
|
112 extern void remoteInit();
|
rlm@1
|
113 extern void remoteCleanUp();
|
rlm@1
|
114 extern void remoteStubMain();
|
rlm@1
|
115 extern void remoteStubSignal(int,int);
|
rlm@1
|
116 extern void remoteOutput(char *, u32);
|
rlm@1
|
117 extern void remoteSetProtocol(int);
|
rlm@1
|
118 extern void remoteSetPort(int);
|
rlm@1
|
119 extern void debuggerOutput(char *, u32);
|
rlm@1
|
120
|
rlm@1
|
121 extern void CPUUpdateRenderBuffers(bool);
|
rlm@1
|
122
|
rlm@1
|
123 struct EmulatedSystem theEmulator = {
|
rlm@1
|
124 NULL,
|
rlm@1
|
125 NULL,
|
rlm@1
|
126 NULL,
|
rlm@1
|
127 NULL,
|
rlm@1
|
128 NULL,
|
rlm@1
|
129 NULL,
|
rlm@1
|
130 NULL,
|
rlm@1
|
131 NULL,
|
rlm@1
|
132 NULL,
|
rlm@1
|
133 NULL,
|
rlm@1
|
134 NULL,
|
rlm@1
|
135 NULL,
|
rlm@1
|
136 false,
|
rlm@1
|
137 0
|
rlm@1
|
138 };
|
rlm@1
|
139
|
rlm@1
|
140 SDL_Surface *surface = NULL;
|
rlm@1
|
141 SDL_Overlay *overlay = NULL;
|
rlm@1
|
142 SDL_Rect overlay_rect;
|
rlm@1
|
143
|
rlm@1
|
144 int systemSpeed = 0;
|
rlm@1
|
145 int systemRedShift = 0;
|
rlm@1
|
146 int systemBlueShift = 0;
|
rlm@1
|
147 int systemGreenShift = 0;
|
rlm@1
|
148 int systemColorDepth = 0;
|
rlm@1
|
149 int systemDebug = 0;
|
rlm@1
|
150 int systemVerbose = 0;
|
rlm@1
|
151 int systemFrameSkip = 0;
|
rlm@1
|
152 int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
rlm@1
|
153
|
rlm@1
|
154 int srcPitch = 0;
|
rlm@1
|
155 int srcWidth = 0;
|
rlm@1
|
156 int srcHeight = 0;
|
rlm@1
|
157 int destWidth = 0;
|
rlm@1
|
158 int destHeight = 0;
|
rlm@1
|
159
|
rlm@1
|
160 int sensorX = 2047;
|
rlm@1
|
161 int sensorY = 2047;
|
rlm@1
|
162 bool sensorOn = false;
|
rlm@1
|
163
|
rlm@1
|
164 int filter = 0;
|
rlm@1
|
165 u8 *delta = NULL;
|
rlm@1
|
166
|
rlm@1
|
167 int sdlPrintUsage = 0;
|
rlm@1
|
168 int disableMMX = 0;
|
rlm@1
|
169
|
rlm@1
|
170 int systemCartridgeType = 3;
|
rlm@1
|
171 int sizeOption = 0;
|
rlm@1
|
172 int captureFormat = 0;
|
rlm@1
|
173 int useMovie = 0;
|
rlm@1
|
174
|
rlm@1
|
175 int pauseWhenInactive = 0;
|
rlm@1
|
176 int active = 1;
|
rlm@1
|
177 int emulating = 0;
|
rlm@1
|
178 int RGB_LOW_BITS_MASK=0x821;
|
rlm@1
|
179 u32 systemColorMap32[0x10000];
|
rlm@1
|
180 u16 systemColorMap16[0x10000];
|
rlm@1
|
181 u16 systemGbPalette[24];
|
rlm@1
|
182 void (*filterFunction)(u8*,u32,u8*,u8*,u32,int,int) = NULL;
|
rlm@1
|
183 void (*ifbFunction)(u8*,u32,int,int) = NULL;
|
rlm@1
|
184 int ifbType = 0;
|
rlm@1
|
185 char filename[2048];
|
rlm@1
|
186 char ipsname[2048];
|
rlm@1
|
187 char biosFileName[2048];
|
rlm@1
|
188 char movieFileName[2048];
|
rlm@1
|
189 char captureDir[2048];
|
rlm@1
|
190 char saveDir[2048];
|
rlm@1
|
191 char batteryDir[2048];
|
rlm@1
|
192
|
rlm@1
|
193 static char *rewindMemory = NULL;
|
rlm@1
|
194 static int rewindPos = 0;
|
rlm@1
|
195 static int rewindTopPos = 0;
|
rlm@1
|
196 static int rewindCounter = 0;
|
rlm@1
|
197 static int rewindCount = 0;
|
rlm@1
|
198 static bool rewindSaveNeeded = false;
|
rlm@1
|
199 static int rewindTimer = 0;
|
rlm@1
|
200
|
rlm@1
|
201 #define REWIND_SIZE 400000
|
rlm@1
|
202
|
rlm@1
|
203 #define _stricmp strcasecmp
|
rlm@1
|
204
|
rlm@1
|
205 /*bool sdlButtons[4][12] = {
|
rlm@1
|
206 { false, false, false, false, false, false,
|
rlm@1
|
207 false, false, false, false, false, false },
|
rlm@1
|
208 { false, false, false, false, false, false,
|
rlm@1
|
209 false, false, false, false, false, false },
|
rlm@1
|
210 { false, false, false, false, false, false,
|
rlm@1
|
211 false, false, false, false, false, false },
|
rlm@1
|
212 { false, false, false, false, false, false,
|
rlm@1
|
213 false, false, false, false, false, false }
|
rlm@1
|
214 };*/
|
rlm@1
|
215 /*
|
rlm@1
|
216 I'm changing the way the SDL GUI handles the button
|
rlm@1
|
217 input to match the one in win32, this is needed in
|
rlm@1
|
218 order to be compatible with the format required by
|
rlm@1
|
219 common/movie.cpp
|
rlm@1
|
220 --Felipe
|
rlm@1
|
221 */
|
rlm@1
|
222
|
rlm@1
|
223 u16 currentButtons[4] = {0, 0, 0, 0};
|
rlm@1
|
224
|
rlm@1
|
225 bool sdlMotionButtons[4] = { false, false, false, false };
|
rlm@1
|
226 const int32 INITIAL_SENSOR_VALUE = 2047;
|
rlm@1
|
227
|
rlm@1
|
228 int sdlNumDevices = 0;
|
rlm@1
|
229 SDL_Joystick **sdlDevices = NULL;
|
rlm@1
|
230
|
rlm@1
|
231 bool wasPaused = false;
|
rlm@1
|
232 int autoFrameSkip = 0;
|
rlm@1
|
233 int frameskipadjust = 0;
|
rlm@1
|
234 int showRenderedFrames = 0;
|
rlm@1
|
235 int renderedFrames = 0;
|
rlm@1
|
236
|
rlm@1
|
237 int throttle = 0;
|
rlm@1
|
238 u32 throttleLastTime = 0;
|
rlm@1
|
239 u32 autoFrameSkipLastTime = 0;
|
rlm@1
|
240
|
rlm@1
|
241 int showSpeed = 1;
|
rlm@1
|
242 int showSpeedTransparent = 1;
|
rlm@1
|
243 bool disableStatusMessages = false;
|
rlm@1
|
244 bool paused = false;
|
rlm@1
|
245 bool pauseNextFrame = false;
|
rlm@1
|
246 bool debugger = false;
|
rlm@1
|
247 bool debuggerStub = false;
|
rlm@1
|
248 int fullscreen = 0;
|
rlm@1
|
249 bool systemSoundOn = false;
|
rlm@1
|
250 bool yuv = false;
|
rlm@1
|
251 int yuvType = 0;
|
rlm@1
|
252 bool removeIntros = false;
|
rlm@1
|
253 int sdlFlashSize = 0;
|
rlm@1
|
254 int sdlAutoIPS = 1;
|
rlm@1
|
255 int sdlRtcEnable = 0;
|
rlm@1
|
256 int sdlAgbPrint = 0;
|
rlm@1
|
257
|
rlm@1
|
258 int sdlDefaultJoypad = 0;
|
rlm@1
|
259
|
rlm@1
|
260 extern void debuggerSignal(int,int);
|
rlm@1
|
261
|
rlm@1
|
262 void (*dbgMain)() = debuggerMain;
|
rlm@1
|
263 void (*dbgSignal)(int,int) = debuggerSignal;
|
rlm@1
|
264 void (*dbgOutput)(char *, u32) = debuggerOutput;
|
rlm@1
|
265
|
rlm@1
|
266 int mouseCounter = 0;
|
rlm@1
|
267 int autoFire = 0;
|
rlm@1
|
268 bool autoFireToggle = false;
|
rlm@1
|
269
|
rlm@1
|
270 bool screenMessage[8] = {false,false,false,false,false,false,false,false};
|
rlm@1
|
271 char screenMessageBuffer[8][21];
|
rlm@1
|
272 u32 screenMessageTime[8] = {0,0,0,0,0,0,0,0};
|
rlm@1
|
273 u32 screenMessageDuration[8] = {0,0,0,0,0,0,0,0};
|
rlm@1
|
274
|
rlm@1
|
275 SDL_cond *cond = NULL;
|
rlm@1
|
276 SDL_mutex *mutex = NULL;
|
rlm@1
|
277 u8* sdlBuffer;
|
rlm@1
|
278 int sdlSoundLen = 0;
|
rlm@1
|
279 SoundSDL* soundDriver = NULL;
|
rlm@1
|
280
|
rlm@1
|
281 char *arg0;
|
rlm@1
|
282
|
rlm@1
|
283 #ifndef C_CORE
|
rlm@1
|
284 u8 sdlStretcher[16384];
|
rlm@1
|
285 int sdlStretcherPos;
|
rlm@1
|
286 #else
|
rlm@1
|
287 void (*sdlStretcher)(u8 *, u8*) = NULL;
|
rlm@1
|
288 #endif
|
rlm@1
|
289
|
rlm@1
|
290 u16 joypad[4][12] = {
|
rlm@1
|
291 { SDLK_LEFT, SDLK_RIGHT,
|
rlm@1
|
292 SDLK_UP, SDLK_DOWN,
|
rlm@1
|
293 SDLK_z, SDLK_x,
|
rlm@1
|
294 SDLK_RETURN,SDLK_BACKSPACE,
|
rlm@1
|
295 SDLK_a, SDLK_s,
|
rlm@1
|
296 SDLK_SPACE, SDLK_F12
|
rlm@1
|
297 },
|
rlm@1
|
298 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
rlm@1
|
299 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
rlm@1
|
300 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
rlm@1
|
301 };
|
rlm@1
|
302
|
rlm@1
|
303 u16 defaultJoypad[12] = {
|
rlm@1
|
304 SDLK_LEFT, SDLK_RIGHT,
|
rlm@1
|
305 SDLK_UP, SDLK_DOWN,
|
rlm@1
|
306 SDLK_z, SDLK_x,
|
rlm@1
|
307 SDLK_RETURN,SDLK_BACKSPACE,
|
rlm@1
|
308 SDLK_a, SDLK_s,
|
rlm@1
|
309 SDLK_SPACE, SDLK_F12
|
rlm@1
|
310 };
|
rlm@1
|
311
|
rlm@1
|
312 u16 motion[4] = {
|
rlm@1
|
313 SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2
|
rlm@1
|
314 };
|
rlm@1
|
315
|
rlm@1
|
316 u16 defaultMotion[4] = {
|
rlm@1
|
317 SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2
|
rlm@1
|
318 };
|
rlm@1
|
319
|
rlm@1
|
320 struct option sdlOptions[] = {
|
rlm@1
|
321 { "agb-print", no_argument, &sdlAgbPrint, 1 },
|
rlm@1
|
322 { "auto-frameskip", no_argument, &autoFrameSkip, 1 },
|
rlm@1
|
323 { "bios", required_argument, 0, 'b' },
|
rlm@1
|
324 { "config", required_argument, 0, 'c' },
|
rlm@1
|
325 { "debug", no_argument, 0, 'd' },
|
rlm@1
|
326 { "filter", required_argument, 0, 'f' },
|
rlm@1
|
327 { "filter-normal", no_argument, &filter, 0 },
|
rlm@1
|
328 { "filter-tv-mode", no_argument, &filter, 1 },
|
rlm@1
|
329 { "filter-2xsai", no_argument, &filter, 2 },
|
rlm@1
|
330 { "filter-super-2xsai", no_argument, &filter, 3 },
|
rlm@1
|
331 { "filter-super-eagle", no_argument, &filter, 4 },
|
rlm@1
|
332 { "filter-pixelate", no_argument, &filter, 5 },
|
rlm@1
|
333 { "filter-motion-blur", no_argument, &filter, 6 },
|
rlm@1
|
334 { "filter-advmame", no_argument, &filter, 7 },
|
rlm@1
|
335 { "filter-simple2x", no_argument, &filter, 8 },
|
rlm@1
|
336 { "filter-bilinear", no_argument, &filter, 9 },
|
rlm@1
|
337 { "filter-bilinear+", no_argument, &filter, 10 },
|
rlm@1
|
338 { "filter-scanlines", no_argument, &filter, 11 },
|
rlm@1
|
339 { "filter-hq2x", no_argument, &filter, 12 },
|
rlm@1
|
340 { "filter-lq2x", no_argument, &filter, 13 },
|
rlm@1
|
341 { "flash-size", required_argument, 0, 'S' },
|
rlm@1
|
342 { "flash-64k", no_argument, &sdlFlashSize, 0 },
|
rlm@1
|
343 { "flash-128k", no_argument, &sdlFlashSize, 1 },
|
rlm@1
|
344 { "frameskip", required_argument, 0, 's' },
|
rlm@1
|
345 { "fullscreen", no_argument, &fullscreen, 1 },
|
rlm@1
|
346 { "gdb", required_argument, 0, 'G' },
|
rlm@1
|
347 { "help", no_argument, &sdlPrintUsage, 1 },
|
rlm@1
|
348 { "ifb-none", no_argument, &ifbType, 0 },
|
rlm@1
|
349 { "ifb-motion-blur", no_argument, &ifbType, 1 },
|
rlm@1
|
350 { "ifb-smart", no_argument, &ifbType, 2 },
|
rlm@1
|
351 { "ips", required_argument, 0, 'i' },
|
rlm@1
|
352 { "no-agb-print", no_argument, &sdlAgbPrint, 0 },
|
rlm@1
|
353 { "no-auto-frameskip", no_argument, &autoFrameSkip, 0 },
|
rlm@1
|
354 { "no-debug", no_argument, 0, 'N' },
|
rlm@1
|
355 { "no-ips", no_argument, &sdlAutoIPS, 0 },
|
rlm@1
|
356 { "no-mmx", no_argument, &disableMMX, 1 },
|
rlm@1
|
357 { "no-pause-when-inactive", no_argument, &pauseWhenInactive, 0 },
|
rlm@1
|
358 { "no-rtc", no_argument, &sdlRtcEnable, 0 },
|
rlm@1
|
359 { "no-show-speed", no_argument, &showSpeed, 0 },
|
rlm@1
|
360 { "no-throttle", no_argument, &throttle, 0 },
|
rlm@1
|
361 { "pause-when-inactive", no_argument, &pauseWhenInactive, 1 },
|
rlm@1
|
362 { "profile", optional_argument, 0, 'P' },
|
rlm@1
|
363 { "rtc", no_argument, &sdlRtcEnable, 1 },
|
rlm@1
|
364 { "save-type", required_argument, 0, 't' },
|
rlm@1
|
365 { "save-auto", no_argument, &cpuSaveType, 0 },
|
rlm@1
|
366 { "save-eeprom", no_argument, &cpuSaveType, 1 },
|
rlm@1
|
367 { "save-sram", no_argument, &cpuSaveType, 2 },
|
rlm@1
|
368 { "save-flash", no_argument, &cpuSaveType, 3 },
|
rlm@1
|
369 { "save-sensor", no_argument, &cpuSaveType, 4 },
|
rlm@1
|
370 { "save-none", no_argument, &cpuSaveType, 5 },
|
rlm@1
|
371 { "show-speed-normal", no_argument, &showSpeed, 1 },
|
rlm@1
|
372 { "show-speed-detailed", no_argument, &showSpeed, 2 },
|
rlm@1
|
373 { "throttle", required_argument, 0, 'T' },
|
rlm@1
|
374 { "verbose", required_argument, 0, 'v' },
|
rlm@1
|
375 { "video-1x", no_argument, &sizeOption, 0 },
|
rlm@1
|
376 { "video-2x", no_argument, &sizeOption, 1 },
|
rlm@1
|
377 { "video-3x", no_argument, &sizeOption, 2 },
|
rlm@1
|
378 { "video-4x", no_argument, &sizeOption, 3 },
|
rlm@1
|
379 { "yuv", required_argument, 0, 'Y' },
|
rlm@1
|
380 { "recordmovie", required_argument, 0, 'r' },
|
rlm@1
|
381 { "playmovie", required_argument, 0, 'p' },
|
rlm@1
|
382 { "watchmovie", required_argument, 0, 'w' },
|
rlm@1
|
383 { NULL, no_argument, NULL, 0 }
|
rlm@1
|
384 };
|
rlm@1
|
385
|
rlm@1
|
386 #ifndef C_CORE
|
rlm@1
|
387 #define SDL_LONG(val) \
|
rlm@1
|
388 *((u32 *)&sdlStretcher[sdlStretcherPos]) = val;\
|
rlm@1
|
389 sdlStretcherPos+=4;
|
rlm@1
|
390
|
rlm@1
|
391 #define SDL_AND_EAX(val) \
|
rlm@1
|
392 sdlStretcher[sdlStretcherPos++] = 0x25;\
|
rlm@1
|
393 SDL_LONG(val);
|
rlm@1
|
394
|
rlm@1
|
395 #define SDL_AND_EBX(val) \
|
rlm@1
|
396 sdlStretcher[sdlStretcherPos++] = 0x81;\
|
rlm@1
|
397 sdlStretcher[sdlStretcherPos++] = 0xe3;\
|
rlm@1
|
398 SDL_LONG(val);
|
rlm@1
|
399
|
rlm@1
|
400 #define SDL_OR_EAX_EBX \
|
rlm@1
|
401 sdlStretcher[sdlStretcherPos++] = 0x09;\
|
rlm@1
|
402 sdlStretcher[sdlStretcherPos++] = 0xd8;
|
rlm@1
|
403
|
rlm@1
|
404 #define SDL_LOADL_EBX \
|
rlm@1
|
405 sdlStretcher[sdlStretcherPos++] = 0x8b;\
|
rlm@1
|
406 sdlStretcher[sdlStretcherPos++] = 0x1f;
|
rlm@1
|
407
|
rlm@1
|
408 #define SDL_LOADW \
|
rlm@1
|
409 sdlStretcher[sdlStretcherPos++] = 0x66;\
|
rlm@1
|
410 sdlStretcher[sdlStretcherPos++] = 0x8b;\
|
rlm@1
|
411 sdlStretcher[sdlStretcherPos++] = 0x06;\
|
rlm@1
|
412 sdlStretcher[sdlStretcherPos++] = 0x83;\
|
rlm@1
|
413 sdlStretcher[sdlStretcherPos++] = 0xc6;\
|
rlm@1
|
414 sdlStretcher[sdlStretcherPos++] = 0x02;
|
rlm@1
|
415
|
rlm@1
|
416 #define SDL_LOADL \
|
rlm@1
|
417 sdlStretcher[sdlStretcherPos++] = 0x8b;\
|
rlm@1
|
418 sdlStretcher[sdlStretcherPos++] = 0x06;\
|
rlm@1
|
419 sdlStretcher[sdlStretcherPos++] = 0x83;\
|
rlm@1
|
420 sdlStretcher[sdlStretcherPos++] = 0xc6;\
|
rlm@1
|
421 sdlStretcher[sdlStretcherPos++] = 0x04;
|
rlm@1
|
422
|
rlm@1
|
423 #define SDL_LOADL2 \
|
rlm@1
|
424 sdlStretcher[sdlStretcherPos++] = 0x8b;\
|
rlm@1
|
425 sdlStretcher[sdlStretcherPos++] = 0x06;\
|
rlm@1
|
426 sdlStretcher[sdlStretcherPos++] = 0x83;\
|
rlm@1
|
427 sdlStretcher[sdlStretcherPos++] = 0xc6;\
|
rlm@1
|
428 sdlStretcher[sdlStretcherPos++] = 0x03;
|
rlm@1
|
429
|
rlm@1
|
430 #define SDL_STOREW \
|
rlm@1
|
431 sdlStretcher[sdlStretcherPos++] = 0x66;\
|
rlm@1
|
432 sdlStretcher[sdlStretcherPos++] = 0x89;\
|
rlm@1
|
433 sdlStretcher[sdlStretcherPos++] = 0x07;\
|
rlm@1
|
434 sdlStretcher[sdlStretcherPos++] = 0x83;\
|
rlm@1
|
435 sdlStretcher[sdlStretcherPos++] = 0xc7;\
|
rlm@1
|
436 sdlStretcher[sdlStretcherPos++] = 0x02;
|
rlm@1
|
437
|
rlm@1
|
438 #define SDL_STOREL \
|
rlm@1
|
439 sdlStretcher[sdlStretcherPos++] = 0x89;\
|
rlm@1
|
440 sdlStretcher[sdlStretcherPos++] = 0x07;\
|
rlm@1
|
441 sdlStretcher[sdlStretcherPos++] = 0x83;\
|
rlm@1
|
442 sdlStretcher[sdlStretcherPos++] = 0xc7;\
|
rlm@1
|
443 sdlStretcher[sdlStretcherPos++] = 0x04;
|
rlm@1
|
444
|
rlm@1
|
445 #define SDL_STOREL2 \
|
rlm@1
|
446 sdlStretcher[sdlStretcherPos++] = 0x89;\
|
rlm@1
|
447 sdlStretcher[sdlStretcherPos++] = 0x07;\
|
rlm@1
|
448 sdlStretcher[sdlStretcherPos++] = 0x83;\
|
rlm@1
|
449 sdlStretcher[sdlStretcherPos++] = 0xc7;\
|
rlm@1
|
450 sdlStretcher[sdlStretcherPos++] = 0x03;
|
rlm@1
|
451
|
rlm@1
|
452 #define SDL_RET \
|
rlm@1
|
453 sdlStretcher[sdlStretcherPos++] = 0xc3;
|
rlm@1
|
454
|
rlm@1
|
455 #define SDL_PUSH_EAX \
|
rlm@1
|
456 sdlStretcher[sdlStretcherPos++] = 0x50;
|
rlm@1
|
457
|
rlm@1
|
458 #define SDL_PUSH_ECX \
|
rlm@1
|
459 sdlStretcher[sdlStretcherPos++] = 0x51;
|
rlm@1
|
460
|
rlm@1
|
461 #define SDL_PUSH_EBX \
|
rlm@1
|
462 sdlStretcher[sdlStretcherPos++] = 0x53;
|
rlm@1
|
463
|
rlm@1
|
464 #define SDL_PUSH_ESI \
|
rlm@1
|
465 sdlStretcher[sdlStretcherPos++] = 0x56;
|
rlm@1
|
466
|
rlm@1
|
467 #define SDL_PUSH_EDI \
|
rlm@1
|
468 sdlStretcher[sdlStretcherPos++] = 0x57;
|
rlm@1
|
469
|
rlm@1
|
470 #define SDL_POP_EAX \
|
rlm@1
|
471 sdlStretcher[sdlStretcherPos++] = 0x58;
|
rlm@1
|
472
|
rlm@1
|
473 #define SDL_POP_ECX \
|
rlm@1
|
474 sdlStretcher[sdlStretcherPos++] = 0x59;
|
rlm@1
|
475
|
rlm@1
|
476 #define SDL_POP_EBX \
|
rlm@1
|
477 sdlStretcher[sdlStretcherPos++] = 0x5b;
|
rlm@1
|
478
|
rlm@1
|
479 #define SDL_POP_ESI \
|
rlm@1
|
480 sdlStretcher[sdlStretcherPos++] = 0x5e;
|
rlm@1
|
481
|
rlm@1
|
482 #define SDL_POP_EDI \
|
rlm@1
|
483 sdlStretcher[sdlStretcherPos++] = 0x5f;
|
rlm@1
|
484
|
rlm@1
|
485 #define SDL_MOV_ECX(val) \
|
rlm@1
|
486 sdlStretcher[sdlStretcherPos++] = 0xb9;\
|
rlm@1
|
487 SDL_LONG(val);
|
rlm@1
|
488
|
rlm@1
|
489 #define SDL_REP_MOVSB \
|
rlm@1
|
490 sdlStretcher[sdlStretcherPos++] = 0xf3;\
|
rlm@1
|
491 sdlStretcher[sdlStretcherPos++] = 0xa4;
|
rlm@1
|
492
|
rlm@1
|
493 #define SDL_REP_MOVSW \
|
rlm@1
|
494 sdlStretcher[sdlStretcherPos++] = 0xf3;\
|
rlm@1
|
495 sdlStretcher[sdlStretcherPos++] = 0x66;\
|
rlm@1
|
496 sdlStretcher[sdlStretcherPos++] = 0xa5;
|
rlm@1
|
497
|
rlm@1
|
498 #define SDL_REP_MOVSL \
|
rlm@1
|
499 sdlStretcher[sdlStretcherPos++] = 0xf3;\
|
rlm@1
|
500 sdlStretcher[sdlStretcherPos++] = 0xa5;
|
rlm@1
|
501
|
rlm@1
|
502 void sdlMakeStretcher(int width)
|
rlm@1
|
503 {
|
rlm@1
|
504 sdlStretcherPos = 0;
|
rlm@1
|
505 switch(systemColorDepth) {
|
rlm@1
|
506 case 16:
|
rlm@1
|
507 if(sizeOption) {
|
rlm@1
|
508 SDL_PUSH_EAX;
|
rlm@1
|
509 SDL_PUSH_ESI;
|
rlm@1
|
510 SDL_PUSH_EDI;
|
rlm@1
|
511 for(int i = 0; i < width; i++) {
|
rlm@1
|
512 SDL_LOADW;
|
rlm@1
|
513 SDL_STOREW;
|
rlm@1
|
514 SDL_STOREW;
|
rlm@1
|
515 if(sizeOption > 1) {
|
rlm@1
|
516 SDL_STOREW;
|
rlm@1
|
517 }
|
rlm@1
|
518 if(sizeOption > 2) {
|
rlm@1
|
519 SDL_STOREW;
|
rlm@1
|
520 }
|
rlm@1
|
521 }
|
rlm@1
|
522 SDL_POP_EDI;
|
rlm@1
|
523 SDL_POP_ESI;
|
rlm@1
|
524 SDL_POP_EAX;
|
rlm@1
|
525 SDL_RET;
|
rlm@1
|
526 } else {
|
rlm@1
|
527 SDL_PUSH_ESI;
|
rlm@1
|
528 SDL_PUSH_EDI;
|
rlm@1
|
529 SDL_PUSH_ECX;
|
rlm@1
|
530 SDL_MOV_ECX(width);
|
rlm@1
|
531 SDL_REP_MOVSW;
|
rlm@1
|
532 SDL_POP_ECX;
|
rlm@1
|
533 SDL_POP_EDI;
|
rlm@1
|
534 SDL_POP_ESI;
|
rlm@1
|
535 SDL_RET;
|
rlm@1
|
536 }
|
rlm@1
|
537 break;
|
rlm@1
|
538 case 24:
|
rlm@1
|
539 if(sizeOption) {
|
rlm@1
|
540 SDL_PUSH_EAX;
|
rlm@1
|
541 SDL_PUSH_ESI;
|
rlm@1
|
542 SDL_PUSH_EDI;
|
rlm@1
|
543 int w = width - 1;
|
rlm@1
|
544 for(int i = 0; i < w; i++) {
|
rlm@1
|
545 SDL_LOADL2;
|
rlm@1
|
546 SDL_STOREL2;
|
rlm@1
|
547 SDL_STOREL2;
|
rlm@1
|
548 if(sizeOption > 1) {
|
rlm@1
|
549 SDL_STOREL2;
|
rlm@1
|
550 }
|
rlm@1
|
551 if(sizeOption > 2) {
|
rlm@1
|
552 SDL_STOREL2;
|
rlm@1
|
553 }
|
rlm@1
|
554 }
|
rlm@1
|
555 // need to write the last one
|
rlm@1
|
556 SDL_LOADL2;
|
rlm@1
|
557 SDL_STOREL2;
|
rlm@1
|
558 if(sizeOption > 1) {
|
rlm@1
|
559 SDL_STOREL2;
|
rlm@1
|
560 }
|
rlm@1
|
561 if(sizeOption > 2) {
|
rlm@1
|
562 SDL_STOREL2;
|
rlm@1
|
563 }
|
rlm@1
|
564 SDL_AND_EAX(0x00ffffff);
|
rlm@1
|
565 SDL_PUSH_EBX;
|
rlm@1
|
566 SDL_LOADL_EBX;
|
rlm@1
|
567 SDL_AND_EBX(0xff000000);
|
rlm@1
|
568 SDL_OR_EAX_EBX;
|
rlm@1
|
569 SDL_POP_EBX;
|
rlm@1
|
570 SDL_STOREL2;
|
rlm@1
|
571 SDL_POP_EDI;
|
rlm@1
|
572 SDL_POP_ESI;
|
rlm@1
|
573 SDL_POP_EAX;
|
rlm@1
|
574 SDL_RET;
|
rlm@1
|
575 } else {
|
rlm@1
|
576 SDL_PUSH_ESI;
|
rlm@1
|
577 SDL_PUSH_EDI;
|
rlm@1
|
578 SDL_PUSH_ECX;
|
rlm@1
|
579 SDL_MOV_ECX(3*width);
|
rlm@1
|
580 SDL_REP_MOVSB;
|
rlm@1
|
581 SDL_POP_ECX;
|
rlm@1
|
582 SDL_POP_EDI;
|
rlm@1
|
583 SDL_POP_ESI;
|
rlm@1
|
584 SDL_RET;
|
rlm@1
|
585 }
|
rlm@1
|
586 break;
|
rlm@1
|
587 case 32:
|
rlm@1
|
588 if(sizeOption) {
|
rlm@1
|
589 SDL_PUSH_EAX;
|
rlm@1
|
590 SDL_PUSH_ESI;
|
rlm@1
|
591 SDL_PUSH_EDI;
|
rlm@1
|
592 for(int i = 0; i < width; i++) {
|
rlm@1
|
593 SDL_LOADL;
|
rlm@1
|
594 SDL_STOREL;
|
rlm@1
|
595 SDL_STOREL;
|
rlm@1
|
596 if(sizeOption > 1) {
|
rlm@1
|
597 SDL_STOREL;
|
rlm@1
|
598 }
|
rlm@1
|
599 if(sizeOption > 2) {
|
rlm@1
|
600 SDL_STOREL;
|
rlm@1
|
601 }
|
rlm@1
|
602 }
|
rlm@1
|
603 SDL_POP_EDI;
|
rlm@1
|
604 SDL_POP_ESI;
|
rlm@1
|
605 SDL_POP_EAX;
|
rlm@1
|
606 SDL_RET;
|
rlm@1
|
607 } else {
|
rlm@1
|
608 SDL_PUSH_ESI;
|
rlm@1
|
609 SDL_PUSH_EDI;
|
rlm@1
|
610 SDL_PUSH_ECX;
|
rlm@1
|
611 SDL_MOV_ECX(width);
|
rlm@1
|
612 SDL_REP_MOVSL;
|
rlm@1
|
613 SDL_POP_ECX;
|
rlm@1
|
614 SDL_POP_EDI;
|
rlm@1
|
615 SDL_POP_ESI;
|
rlm@1
|
616 SDL_RET;
|
rlm@1
|
617 }
|
rlm@1
|
618 break;
|
rlm@1
|
619 }
|
rlm@1
|
620 }
|
rlm@1
|
621
|
rlm@1
|
622 #ifdef _MSC_VER
|
rlm@1
|
623 #define SDL_CALL_STRETCHER \
|
rlm@1
|
624 {\
|
rlm@1
|
625 __asm mov eax, stretcher\
|
rlm@1
|
626 __asm mov edi, dest\
|
rlm@1
|
627 __asm mov esi, src\
|
rlm@1
|
628 __asm call eax\
|
rlm@1
|
629 }
|
rlm@1
|
630 #else
|
rlm@1
|
631 #define SDL_CALL_STRETCHER \
|
rlm@1
|
632 asm volatile("call *%%eax"::"a" (stretcher),"S" (src),"D" (dest))
|
rlm@1
|
633 #endif
|
rlm@1
|
634 #else
|
rlm@1
|
635 #define SDL_CALL_STRETCHER \
|
rlm@1
|
636 sdlStretcher(src, dest)
|
rlm@1
|
637
|
rlm@1
|
638 void sdlStretch16x1(u8 *src, u8 *dest)
|
rlm@1
|
639 {
|
rlm@1
|
640 u16 *s = (u16 *)src;
|
rlm@1
|
641 u16 *d = (u16 *)dest;
|
rlm@1
|
642 for(int i = 0; i < srcWidth; i++)
|
rlm@1
|
643 *d++ = *s++;
|
rlm@1
|
644 }
|
rlm@1
|
645
|
rlm@1
|
646 void sdlStretch16x2(u8 *src, u8 *dest)
|
rlm@1
|
647 {
|
rlm@1
|
648 u16 *s = (u16 *)src;
|
rlm@1
|
649 u16 *d = (u16 *)dest;
|
rlm@1
|
650 for(int i = 0; i < srcWidth; i++) {
|
rlm@1
|
651 *d++ = *s;
|
rlm@1
|
652 *d++ = *s++;
|
rlm@1
|
653 }
|
rlm@1
|
654 }
|
rlm@1
|
655
|
rlm@1
|
656 void sdlStretch16x3(u8 *src, u8 *dest)
|
rlm@1
|
657 {
|
rlm@1
|
658 u16 *s = (u16 *)src;
|
rlm@1
|
659 u16 *d = (u16 *)dest;
|
rlm@1
|
660 for(int i = 0; i < srcWidth; i++) {
|
rlm@1
|
661 *d++ = *s;
|
rlm@1
|
662 *d++ = *s;
|
rlm@1
|
663 *d++ = *s++;
|
rlm@1
|
664 }
|
rlm@1
|
665 }
|
rlm@1
|
666
|
rlm@1
|
667 void sdlStretch16x4(u8 *src, u8 *dest)
|
rlm@1
|
668 {
|
rlm@1
|
669 u16 *s = (u16 *)src;
|
rlm@1
|
670 u16 *d = (u16 *)dest;
|
rlm@1
|
671 for(int i = 0; i < srcWidth; i++) {
|
rlm@1
|
672 *d++ = *s;
|
rlm@1
|
673 *d++ = *s;
|
rlm@1
|
674 *d++ = *s;
|
rlm@1
|
675 *d++ = *s++;
|
rlm@1
|
676 }
|
rlm@1
|
677 }
|
rlm@1
|
678
|
rlm@1
|
679 void (*sdlStretcher16[4])(u8 *, u8 *) = {
|
rlm@1
|
680 sdlStretch16x1,
|
rlm@1
|
681 sdlStretch16x2,
|
rlm@1
|
682 sdlStretch16x3,
|
rlm@1
|
683 sdlStretch16x4
|
rlm@1
|
684 };
|
rlm@1
|
685
|
rlm@1
|
686 void sdlStretch32x1(u8 *src, u8 *dest)
|
rlm@1
|
687 {
|
rlm@1
|
688 u32 *s = (u32 *)src;
|
rlm@1
|
689 u32 *d = (u32 *)dest;
|
rlm@1
|
690 for(int i = 0; i < srcWidth; i++)
|
rlm@1
|
691 *d++ = *s++;
|
rlm@1
|
692 }
|
rlm@1
|
693
|
rlm@1
|
694 void sdlStretch32x2(u8 *src, u8 *dest)
|
rlm@1
|
695 {
|
rlm@1
|
696 u32 *s = (u32 *)src;
|
rlm@1
|
697 u32 *d = (u32 *)dest;
|
rlm@1
|
698 for(int i = 0; i < srcWidth; i++) {
|
rlm@1
|
699 *d++ = *s;
|
rlm@1
|
700 *d++ = *s++;
|
rlm@1
|
701 }
|
rlm@1
|
702 }
|
rlm@1
|
703
|
rlm@1
|
704 void sdlStretch32x3(u8 *src, u8 *dest)
|
rlm@1
|
705 {
|
rlm@1
|
706 u32 *s = (u32 *)src;
|
rlm@1
|
707 u32 *d = (u32 *)dest;
|
rlm@1
|
708 for(int i = 0; i < srcWidth; i++) {
|
rlm@1
|
709 *d++ = *s;
|
rlm@1
|
710 *d++ = *s;
|
rlm@1
|
711 *d++ = *s++;
|
rlm@1
|
712 }
|
rlm@1
|
713 }
|
rlm@1
|
714
|
rlm@1
|
715 void sdlStretch32x4(u8 *src, u8 *dest)
|
rlm@1
|
716 {
|
rlm@1
|
717 u32 *s = (u32 *)src;
|
rlm@1
|
718 u32 *d = (u32 *)dest;
|
rlm@1
|
719 for(int i = 0; i < srcWidth; i++) {
|
rlm@1
|
720 *d++ = *s;
|
rlm@1
|
721 *d++ = *s;
|
rlm@1
|
722 *d++ = *s;
|
rlm@1
|
723 *d++ = *s++;
|
rlm@1
|
724 }
|
rlm@1
|
725 }
|
rlm@1
|
726
|
rlm@1
|
727 void (*sdlStretcher32[4])(u8 *, u8 *) = {
|
rlm@1
|
728 sdlStretch32x1,
|
rlm@1
|
729 sdlStretch32x2,
|
rlm@1
|
730 sdlStretch32x3,
|
rlm@1
|
731 sdlStretch32x4
|
rlm@1
|
732 };
|
rlm@1
|
733
|
rlm@1
|
734 void sdlStretch24x1(u8 *src, u8 *dest)
|
rlm@1
|
735 {
|
rlm@1
|
736 u8 *s = src;
|
rlm@1
|
737 u8 *d = dest;
|
rlm@1
|
738 for(int i = 0; i < srcWidth; i++) {
|
rlm@1
|
739 *d++ = *s++;
|
rlm@1
|
740 *d++ = *s++;
|
rlm@1
|
741 *d++ = *s++;
|
rlm@1
|
742 }
|
rlm@1
|
743 }
|
rlm@1
|
744
|
rlm@1
|
745 void sdlStretch24x2(u8 *src, u8 *dest)
|
rlm@1
|
746 {
|
rlm@1
|
747 u8 *s = (u8 *)src;
|
rlm@1
|
748 u8 *d = (u8 *)dest;
|
rlm@1
|
749 for(int i = 0; i < srcWidth; i++) {
|
rlm@1
|
750 *d++ = *s;
|
rlm@1
|
751 *d++ = *(s+1);
|
rlm@1
|
752 *d++ = *(s+2);
|
rlm@1
|
753 s += 3;
|
rlm@1
|
754 *d++ = *s;
|
rlm@1
|
755 *d++ = *(s+1);
|
rlm@1
|
756 *d++ = *(s+2);
|
rlm@1
|
757 s += 3;
|
rlm@1
|
758 }
|
rlm@1
|
759 }
|
rlm@1
|
760
|
rlm@1
|
761 void sdlStretch24x3(u8 *src, u8 *dest)
|
rlm@1
|
762 {
|
rlm@1
|
763 u8 *s = (u8 *)src;
|
rlm@1
|
764 u8 *d = (u8 *)dest;
|
rlm@1
|
765 for(int i = 0; i < srcWidth; i++) {
|
rlm@1
|
766 *d++ = *s;
|
rlm@1
|
767 *d++ = *(s+1);
|
rlm@1
|
768 *d++ = *(s+2);
|
rlm@1
|
769 s += 3;
|
rlm@1
|
770 *d++ = *s;
|
rlm@1
|
771 *d++ = *(s+1);
|
rlm@1
|
772 *d++ = *(s+2);
|
rlm@1
|
773 s += 3;
|
rlm@1
|
774 *d++ = *s;
|
rlm@1
|
775 *d++ = *(s+1);
|
rlm@1
|
776 *d++ = *(s+2);
|
rlm@1
|
777 s += 3;
|
rlm@1
|
778 }
|
rlm@1
|
779 }
|
rlm@1
|
780
|
rlm@1
|
781 void sdlStretch24x4(u8 *src, u8 *dest)
|
rlm@1
|
782 {
|
rlm@1
|
783 u8 *s = (u8 *)src;
|
rlm@1
|
784 u8 *d = (u8 *)dest;
|
rlm@1
|
785 for(int i = 0; i < srcWidth; i++) {
|
rlm@1
|
786 *d++ = *s;
|
rlm@1
|
787 *d++ = *(s+1);
|
rlm@1
|
788 *d++ = *(s+2);
|
rlm@1
|
789 s += 3;
|
rlm@1
|
790 *d++ = *s;
|
rlm@1
|
791 *d++ = *(s+1);
|
rlm@1
|
792 *d++ = *(s+2);
|
rlm@1
|
793 s += 3;
|
rlm@1
|
794 *d++ = *s;
|
rlm@1
|
795 *d++ = *(s+1);
|
rlm@1
|
796 *d++ = *(s+2);
|
rlm@1
|
797 s += 3;
|
rlm@1
|
798 *d++ = *s;
|
rlm@1
|
799 *d++ = *(s+1);
|
rlm@1
|
800 *d++ = *(s+2);
|
rlm@1
|
801 s += 3;
|
rlm@1
|
802 }
|
rlm@1
|
803 }
|
rlm@1
|
804
|
rlm@1
|
805 void (*sdlStretcher24[4])(u8 *, u8 *) = {
|
rlm@1
|
806 sdlStretch24x1,
|
rlm@1
|
807 sdlStretch24x2,
|
rlm@1
|
808 sdlStretch24x3,
|
rlm@1
|
809 sdlStretch24x4
|
rlm@1
|
810 };
|
rlm@1
|
811
|
rlm@1
|
812 #endif
|
rlm@1
|
813
|
rlm@1
|
814 u32 sdlFromHex(char *s)
|
rlm@1
|
815 {
|
rlm@1
|
816 u32 value;
|
rlm@1
|
817 sscanf(s, "%x", &value);
|
rlm@1
|
818 return value;
|
rlm@1
|
819 }
|
rlm@1
|
820
|
rlm@1
|
821 #ifdef __MSC__
|
rlm@1
|
822 #define stat _stat
|
rlm@1
|
823 #define S_IFDIR _S_IFDIR
|
rlm@1
|
824 #endif
|
rlm@1
|
825
|
rlm@1
|
826 void sdlCheckDirectory(char *dir)
|
rlm@1
|
827 {
|
rlm@1
|
828 struct stat buf;
|
rlm@1
|
829
|
rlm@1
|
830 int len = strlen(dir);
|
rlm@1
|
831
|
rlm@1
|
832 char *p = dir + len - 1;
|
rlm@1
|
833
|
rlm@1
|
834 if(*p == '/' ||
|
rlm@1
|
835 *p == '\\')
|
rlm@1
|
836 *p = 0;
|
rlm@1
|
837
|
rlm@1
|
838 if(stat(dir, &buf) == 0) {
|
rlm@1
|
839 if(!(buf.st_mode & S_IFDIR)) {
|
rlm@1
|
840 fprintf(stderr, "Error: %s is not a directory\n", dir);
|
rlm@1
|
841 dir[0] = 0;
|
rlm@1
|
842 }
|
rlm@1
|
843 } else {
|
rlm@1
|
844 fprintf(stderr, "Error: %s does not exist\n", dir);
|
rlm@1
|
845 dir[0] = 0;
|
rlm@1
|
846 }
|
rlm@1
|
847 }
|
rlm@1
|
848
|
rlm@1
|
849 char *sdlGetFilename(char *name)
|
rlm@1
|
850 {
|
rlm@1
|
851 static char filebuffer[2048];
|
rlm@1
|
852
|
rlm@1
|
853 int len = strlen(name);
|
rlm@1
|
854
|
rlm@1
|
855 char *p = name + len - 1;
|
rlm@1
|
856
|
rlm@1
|
857 while(true) {
|
rlm@1
|
858 if(*p == '/' ||
|
rlm@1
|
859 *p == '\\') {
|
rlm@1
|
860 p++;
|
rlm@1
|
861 break;
|
rlm@1
|
862 }
|
rlm@1
|
863 len--;
|
rlm@1
|
864 p--;
|
rlm@1
|
865 if(len == 0)
|
rlm@1
|
866 break;
|
rlm@1
|
867 }
|
rlm@1
|
868
|
rlm@1
|
869 if(len == 0)
|
rlm@1
|
870 strcpy(filebuffer, name);
|
rlm@1
|
871 else
|
rlm@1
|
872 strcpy(filebuffer, p);
|
rlm@1
|
873 return filebuffer;
|
rlm@1
|
874 }
|
rlm@1
|
875
|
rlm@1
|
876 FILE *sdlFindFile(const char *name)
|
rlm@1
|
877 {
|
rlm@1
|
878 char buffer[4096];
|
rlm@1
|
879 char path[2048];
|
rlm@1
|
880
|
rlm@1
|
881 #ifdef WIN32
|
rlm@1
|
882 #define PATH_SEP ";"
|
rlm@1
|
883 #define FILE_SEP '\\'
|
rlm@1
|
884 #define EXE_NAME "VisualBoyAdvance-SDL.exe"
|
rlm@1
|
885 #else // ! WIN32
|
rlm@1
|
886 #define PATH_SEP ":"
|
rlm@1
|
887 #define FILE_SEP '/'
|
rlm@1
|
888 #define EXE_NAME "VisualBoyAdvance"
|
rlm@1
|
889 #endif // ! WIN32
|
rlm@1
|
890
|
rlm@1
|
891 fprintf(stderr, "Searching for file %s\n", name);
|
rlm@1
|
892
|
rlm@1
|
893 if(GETCWD(buffer, 2048)) {
|
rlm@1
|
894 fprintf(stderr, "Searching current directory: %s\n", buffer);
|
rlm@1
|
895 }
|
rlm@1
|
896
|
rlm@1
|
897 FILE *f = fopen(name, "r");
|
rlm@1
|
898 if(f != NULL) {
|
rlm@1
|
899 return f;
|
rlm@1
|
900 }
|
rlm@1
|
901
|
rlm@1
|
902 char *home = getenv("HOME");
|
rlm@1
|
903
|
rlm@1
|
904 if(home != NULL) {
|
rlm@1
|
905 fprintf(stderr, "Searching home directory: %s\n", home);
|
rlm@1
|
906 sprintf(path, "%s%c%s", home, FILE_SEP, name);
|
rlm@1
|
907 f = fopen(path, "r");
|
rlm@1
|
908 if(f != NULL)
|
rlm@1
|
909 return f;
|
rlm@1
|
910 }
|
rlm@1
|
911
|
rlm@1
|
912 #ifdef WIN32
|
rlm@1
|
913 home = getenv("USERPROFILE");
|
rlm@1
|
914 if(home != NULL) {
|
rlm@1
|
915 fprintf(stderr, "Searching user profile directory: %s\n", home);
|
rlm@1
|
916 sprintf(path, "%s%c%s", home, FILE_SEP, name);
|
rlm@1
|
917 f = fopen(path, "r");
|
rlm@1
|
918 if(f != NULL)
|
rlm@1
|
919 return f;
|
rlm@1
|
920 }
|
rlm@1
|
921 #else // ! WIN32
|
rlm@1
|
922 fprintf(stderr, "Searching system config directory: %s\n", SYSCONFDIR);
|
rlm@1
|
923 sprintf(path, "%s%c%s", SYSCONFDIR, FILE_SEP, name);
|
rlm@1
|
924 f = fopen(path, "r");
|
rlm@1
|
925 if(f != NULL)
|
rlm@1
|
926 return f;
|
rlm@1
|
927 #endif // ! WIN32
|
rlm@1
|
928
|
rlm@1
|
929 if(!strchr(arg0, '/') &&
|
rlm@1
|
930 !strchr(arg0, '\\')) {
|
rlm@1
|
931 char *path = getenv("PATH");
|
rlm@1
|
932
|
rlm@1
|
933 if(path != NULL) {
|
rlm@1
|
934 fprintf(stderr, "Searching PATH\n");
|
rlm@1
|
935 strncpy(buffer, path, 4096);
|
rlm@1
|
936 buffer[4095] = 0;
|
rlm@1
|
937 char *tok = strtok(buffer, PATH_SEP);
|
rlm@1
|
938
|
rlm@1
|
939 while(tok) {
|
rlm@1
|
940 sprintf(path, "%s%c%s", tok, FILE_SEP, EXE_NAME);
|
rlm@1
|
941 f = fopen(path, "r");
|
rlm@1
|
942 if(f != NULL) {
|
rlm@1
|
943 char path2[2048];
|
rlm@1
|
944 fclose(f);
|
rlm@1
|
945 sprintf(path2, "%s%c%s", tok, FILE_SEP, name);
|
rlm@1
|
946 f = fopen(path2, "r");
|
rlm@1
|
947 if(f != NULL) {
|
rlm@1
|
948 fprintf(stderr, "Found at %s\n", path2);
|
rlm@1
|
949 return f;
|
rlm@1
|
950 }
|
rlm@1
|
951 }
|
rlm@1
|
952 tok = strtok(NULL, PATH_SEP);
|
rlm@1
|
953 }
|
rlm@1
|
954 }
|
rlm@1
|
955 } else {
|
rlm@1
|
956 // executable is relative to some directory
|
rlm@1
|
957 fprintf(stderr, "Searching executable directory\n");
|
rlm@1
|
958 strcpy(buffer, arg0);
|
rlm@1
|
959 char *p = strrchr(buffer, FILE_SEP);
|
rlm@1
|
960 if(p) {
|
rlm@1
|
961 *p = 0;
|
rlm@1
|
962 sprintf(path, "%s%c%s", buffer, FILE_SEP, name);
|
rlm@1
|
963 f = fopen(path, "r");
|
rlm@1
|
964 if(f != NULL)
|
rlm@1
|
965 return f;
|
rlm@1
|
966 }
|
rlm@1
|
967 }
|
rlm@1
|
968 return NULL;
|
rlm@1
|
969 }
|
rlm@1
|
970
|
rlm@1
|
971 void sdlReadPreferences(FILE *f)
|
rlm@1
|
972 {
|
rlm@1
|
973 char buffer[2048];
|
rlm@1
|
974
|
rlm@1
|
975 while(1) {
|
rlm@1
|
976 char *s = fgets(buffer, 2048, f);
|
rlm@1
|
977
|
rlm@1
|
978 if(s == NULL)
|
rlm@1
|
979 break;
|
rlm@1
|
980
|
rlm@1
|
981 char *p = strchr(s, '#');
|
rlm@1
|
982
|
rlm@1
|
983 if(p)
|
rlm@1
|
984 *p = 0;
|
rlm@1
|
985
|
rlm@1
|
986 char *token = strtok(s, " \t\n\r=");
|
rlm@1
|
987
|
rlm@1
|
988 if(!token)
|
rlm@1
|
989 continue;
|
rlm@1
|
990
|
rlm@1
|
991 if(strlen(token) == 0)
|
rlm@1
|
992 continue;
|
rlm@1
|
993
|
rlm@1
|
994 char *key = token;
|
rlm@1
|
995 char *value = strtok(NULL, "\t\n\r");
|
rlm@1
|
996
|
rlm@1
|
997 if(value == NULL) {
|
rlm@1
|
998 fprintf(stderr, "Empty value for key %s\n", key);
|
rlm@1
|
999 continue;
|
rlm@1
|
1000 }
|
rlm@1
|
1001
|
rlm@1
|
1002 if(!strcmp(key,"Joy0_Left")) {
|
rlm@1
|
1003 joypad[0][KEY_LEFT] = sdlFromHex(value);
|
rlm@1
|
1004 } else if(!strcmp(key, "Joy0_Right")) {
|
rlm@1
|
1005 joypad[0][KEY_RIGHT] = sdlFromHex(value);
|
rlm@1
|
1006 } else if(!strcmp(key, "Joy0_Up")) {
|
rlm@1
|
1007 joypad[0][KEY_UP] = sdlFromHex(value);
|
rlm@1
|
1008 } else if(!strcmp(key, "Joy0_Down")) {
|
rlm@1
|
1009 joypad[0][KEY_DOWN] = sdlFromHex(value);
|
rlm@1
|
1010 } else if(!strcmp(key, "Joy0_A")) {
|
rlm@1
|
1011 joypad[0][KEY_BUTTON_A] = sdlFromHex(value);
|
rlm@1
|
1012 } else if(!strcmp(key, "Joy0_B")) {
|
rlm@1
|
1013 joypad[0][KEY_BUTTON_B] = sdlFromHex(value);
|
rlm@1
|
1014 } else if(!strcmp(key, "Joy0_L")) {
|
rlm@1
|
1015 joypad[0][KEY_BUTTON_L] = sdlFromHex(value);
|
rlm@1
|
1016 } else if(!strcmp(key, "Joy0_R")) {
|
rlm@1
|
1017 joypad[0][KEY_BUTTON_R] = sdlFromHex(value);
|
rlm@1
|
1018 } else if(!strcmp(key, "Joy0_Start")) {
|
rlm@1
|
1019 joypad[0][KEY_BUTTON_START] = sdlFromHex(value);
|
rlm@1
|
1020 } else if(!strcmp(key, "Joy0_Select")) {
|
rlm@1
|
1021 joypad[0][KEY_BUTTON_SELECT] = sdlFromHex(value);
|
rlm@1
|
1022 } else if(!strcmp(key, "Joy0_Speed")) {
|
rlm@1
|
1023 joypad[0][KEY_BUTTON_SPEED] = sdlFromHex(value);
|
rlm@1
|
1024 } else if(!strcmp(key, "Joy0_Capture")) {
|
rlm@1
|
1025 joypad[0][KEY_BUTTON_CAPTURE] = sdlFromHex(value);
|
rlm@1
|
1026 } else if(!strcmp(key,"Joy1_Left")) {
|
rlm@1
|
1027 joypad[1][KEY_LEFT] = sdlFromHex(value);
|
rlm@1
|
1028 } else if(!strcmp(key, "Joy1_Right")) {
|
rlm@1
|
1029 joypad[1][KEY_RIGHT] = sdlFromHex(value);
|
rlm@1
|
1030 } else if(!strcmp(key, "Joy1_Up")) {
|
rlm@1
|
1031 joypad[1][KEY_UP] = sdlFromHex(value);
|
rlm@1
|
1032 } else if(!strcmp(key, "Joy1_Down")) {
|
rlm@1
|
1033 joypad[1][KEY_DOWN] = sdlFromHex(value);
|
rlm@1
|
1034 } else if(!strcmp(key, "Joy1_A")) {
|
rlm@1
|
1035 joypad[1][KEY_BUTTON_A] = sdlFromHex(value);
|
rlm@1
|
1036 } else if(!strcmp(key, "Joy1_B")) {
|
rlm@1
|
1037 joypad[1][KEY_BUTTON_B] = sdlFromHex(value);
|
rlm@1
|
1038 } else if(!strcmp(key, "Joy1_L")) {
|
rlm@1
|
1039 joypad[1][KEY_BUTTON_L] = sdlFromHex(value);
|
rlm@1
|
1040 } else if(!strcmp(key, "Joy1_R")) {
|
rlm@1
|
1041 joypad[1][KEY_BUTTON_R] = sdlFromHex(value);
|
rlm@1
|
1042 } else if(!strcmp(key, "Joy1_Start")) {
|
rlm@1
|
1043 joypad[1][KEY_BUTTON_START] = sdlFromHex(value);
|
rlm@1
|
1044 } else if(!strcmp(key, "Joy1_Select")) {
|
rlm@1
|
1045 joypad[1][KEY_BUTTON_SELECT] = sdlFromHex(value);
|
rlm@1
|
1046 } else if(!strcmp(key, "Joy1_Speed")) {
|
rlm@1
|
1047 joypad[1][KEY_BUTTON_SPEED] = sdlFromHex(value);
|
rlm@1
|
1048 } else if(!strcmp(key, "Joy1_Capture")) {
|
rlm@1
|
1049 joypad[1][KEY_BUTTON_CAPTURE] = sdlFromHex(value);
|
rlm@1
|
1050 } else if(!strcmp(key,"Joy2_Left")) {
|
rlm@1
|
1051 joypad[2][KEY_LEFT] = sdlFromHex(value);
|
rlm@1
|
1052 } else if(!strcmp(key, "Joy2_Right")) {
|
rlm@1
|
1053 joypad[2][KEY_RIGHT] = sdlFromHex(value);
|
rlm@1
|
1054 } else if(!strcmp(key, "Joy2_Up")) {
|
rlm@1
|
1055 joypad[2][KEY_UP] = sdlFromHex(value);
|
rlm@1
|
1056 } else if(!strcmp(key, "Joy2_Down")) {
|
rlm@1
|
1057 joypad[2][KEY_DOWN] = sdlFromHex(value);
|
rlm@1
|
1058 } else if(!strcmp(key, "Joy2_A")) {
|
rlm@1
|
1059 joypad[2][KEY_BUTTON_A] = sdlFromHex(value);
|
rlm@1
|
1060 } else if(!strcmp(key, "Joy2_B")) {
|
rlm@1
|
1061 joypad[2][KEY_BUTTON_B] = sdlFromHex(value);
|
rlm@1
|
1062 } else if(!strcmp(key, "Joy2_L")) {
|
rlm@1
|
1063 joypad[2][KEY_BUTTON_L] = sdlFromHex(value);
|
rlm@1
|
1064 } else if(!strcmp(key, "Joy2_R")) {
|
rlm@1
|
1065 joypad[2][KEY_BUTTON_R] = sdlFromHex(value);
|
rlm@1
|
1066 } else if(!strcmp(key, "Joy2_Start")) {
|
rlm@1
|
1067 joypad[2][KEY_BUTTON_START] = sdlFromHex(value);
|
rlm@1
|
1068 } else if(!strcmp(key, "Joy2_Select")) {
|
rlm@1
|
1069 joypad[2][KEY_BUTTON_SELECT] = sdlFromHex(value);
|
rlm@1
|
1070 } else if(!strcmp(key, "Joy2_Speed")) {
|
rlm@1
|
1071 joypad[2][KEY_BUTTON_SPEED] = sdlFromHex(value);
|
rlm@1
|
1072 } else if(!strcmp(key, "Joy2_Capture")) {
|
rlm@1
|
1073 joypad[2][KEY_BUTTON_CAPTURE] = sdlFromHex(value);
|
rlm@1
|
1074 } else if(!strcmp(key,"Joy4_Left")) {
|
rlm@1
|
1075 joypad[4][KEY_LEFT] = sdlFromHex(value);
|
rlm@1
|
1076 } else if(!strcmp(key, "Joy4_Right")) {
|
rlm@1
|
1077 joypad[4][KEY_RIGHT] = sdlFromHex(value);
|
rlm@1
|
1078 } else if(!strcmp(key, "Joy4_Up")) {
|
rlm@1
|
1079 joypad[4][KEY_UP] = sdlFromHex(value);
|
rlm@1
|
1080 } else if(!strcmp(key, "Joy4_Down")) {
|
rlm@1
|
1081 joypad[4][KEY_DOWN] = sdlFromHex(value);
|
rlm@1
|
1082 } else if(!strcmp(key, "Joy4_A")) {
|
rlm@1
|
1083 joypad[4][KEY_BUTTON_A] = sdlFromHex(value);
|
rlm@1
|
1084 } else if(!strcmp(key, "Joy4_B")) {
|
rlm@1
|
1085 joypad[4][KEY_BUTTON_B] = sdlFromHex(value);
|
rlm@1
|
1086 } else if(!strcmp(key, "Joy4_L")) {
|
rlm@1
|
1087 joypad[4][KEY_BUTTON_L] = sdlFromHex(value);
|
rlm@1
|
1088 } else if(!strcmp(key, "Joy4_R")) {
|
rlm@1
|
1089 joypad[4][KEY_BUTTON_R] = sdlFromHex(value);
|
rlm@1
|
1090 } else if(!strcmp(key, "Joy4_Start")) {
|
rlm@1
|
1091 joypad[4][KEY_BUTTON_START] = sdlFromHex(value);
|
rlm@1
|
1092 } else if(!strcmp(key, "Joy4_Select")) {
|
rlm@1
|
1093 joypad[4][KEY_BUTTON_SELECT] = sdlFromHex(value);
|
rlm@1
|
1094 } else if(!strcmp(key, "Joy4_Speed")) {
|
rlm@1
|
1095 joypad[4][KEY_BUTTON_SPEED] = sdlFromHex(value);
|
rlm@1
|
1096 } else if(!strcmp(key, "Joy4_Capture")) {
|
rlm@1
|
1097 joypad[4][KEY_BUTTON_CAPTURE] = sdlFromHex(value);
|
rlm@1
|
1098 } else if(!strcmp(key, "Motion_Left")) {
|
rlm@1
|
1099 motion[KEY_LEFT] = sdlFromHex(value);
|
rlm@1
|
1100 } else if(!strcmp(key, "Motion_Right")) {
|
rlm@1
|
1101 motion[KEY_RIGHT] = sdlFromHex(value);
|
rlm@1
|
1102 } else if(!strcmp(key, "Motion_Up")) {
|
rlm@1
|
1103 motion[KEY_UP] = sdlFromHex(value);
|
rlm@1
|
1104 } else if(!strcmp(key, "Motion_Down")) {
|
rlm@1
|
1105 motion[KEY_DOWN] = sdlFromHex(value);
|
rlm@1
|
1106 } else if(!strcmp(key, "frameSkip")) {
|
rlm@1
|
1107 frameSkip = sdlFromHex(value);
|
rlm@1
|
1108 if(frameSkip < 0 || frameSkip > 9)
|
rlm@1
|
1109 frameSkip = 2;
|
rlm@1
|
1110 } else if(!strcmp(key, "gbFrameSkip")) {
|
rlm@1
|
1111 gbFrameSkip = sdlFromHex(value);
|
rlm@1
|
1112 if(gbFrameSkip < 0 || gbFrameSkip > 9)
|
rlm@1
|
1113 gbFrameSkip = 0;
|
rlm@1
|
1114 } else if(!strcmp(key, "video")) {
|
rlm@1
|
1115 sizeOption = sdlFromHex(value);
|
rlm@1
|
1116 if(sizeOption < 0 || sizeOption > 3)
|
rlm@1
|
1117 sizeOption = 1;
|
rlm@1
|
1118 } else if(!strcmp(key, "fullScreen")) {
|
rlm@1
|
1119 fullscreen = sdlFromHex(value) ? 1 : 0;
|
rlm@1
|
1120 } else if(!strcmp(key, "useBios")) {
|
rlm@1
|
1121 useBios = sdlFromHex(value) ? true : false;
|
rlm@1
|
1122 } else if(!strcmp(key, "skipBios")) {
|
rlm@1
|
1123 skipBios = sdlFromHex(value) ? true : false;
|
rlm@1
|
1124 } else if(!strcmp(key, "biosFile")) {
|
rlm@1
|
1125 strcpy(biosFileName, value);
|
rlm@1
|
1126 } else if(!strcmp(key, "filter")) {
|
rlm@1
|
1127 filter = sdlFromHex(value);
|
rlm@1
|
1128 if(filter < 0 || filter > 13)
|
rlm@1
|
1129 filter = 0;
|
rlm@1
|
1130 } else if(!strcmp(key, "disableStatus")) {
|
rlm@1
|
1131 disableStatusMessages = sdlFromHex(value) ? true : false;
|
rlm@1
|
1132 } else if(!strcmp(key, "borderOn")) {
|
rlm@1
|
1133 gbBorderOn = sdlFromHex(value) ? true : false;
|
rlm@1
|
1134 } else if(!strcmp(key, "borderAutomatic")) {
|
rlm@1
|
1135 gbBorderAutomatic = sdlFromHex(value) ? true : false;
|
rlm@1
|
1136 } else if(!strcmp(key, "emulatorType")) {
|
rlm@1
|
1137 gbEmulatorType = sdlFromHex(value);
|
rlm@1
|
1138 if(gbEmulatorType < 0 || gbEmulatorType > 5)
|
rlm@1
|
1139 gbEmulatorType = 1;
|
rlm@1
|
1140 } else if(!strcmp(key, "colorOption")) {
|
rlm@1
|
1141 gbColorOption = sdlFromHex(value) ? true : false;
|
rlm@1
|
1142 } else if(!strcmp(key, "captureDir")) {
|
rlm@1
|
1143 sdlCheckDirectory(value);
|
rlm@1
|
1144 strcpy(captureDir, value);
|
rlm@1
|
1145 } else if(!strcmp(key, "saveDir")) {
|
rlm@1
|
1146 sdlCheckDirectory(value);
|
rlm@1
|
1147 strcpy(saveDir, value);
|
rlm@1
|
1148 } else if(!strcmp(key, "batteryDir")) {
|
rlm@1
|
1149 sdlCheckDirectory(value);
|
rlm@1
|
1150 strcpy(batteryDir, value);
|
rlm@1
|
1151 } else if(!strcmp(key, "captureFormat")) {
|
rlm@1
|
1152 captureFormat = sdlFromHex(value);
|
rlm@1
|
1153 } else if(!strcmp(key, "soundQuality")) {
|
rlm@1
|
1154 soundQuality = sdlFromHex(value);
|
rlm@1
|
1155 switch(soundQuality) {
|
rlm@1
|
1156 case 1: break;
|
rlm@1
|
1157 default:
|
rlm@1
|
1158 fprintf(stderr, "The rerecording version will run only sound at highest quality. Defaulting to 44.1 KHz\n");
|
rlm@1
|
1159 soundQuality = 1;
|
rlm@1
|
1160 break;
|
rlm@1
|
1161 }
|
rlm@1
|
1162 } else if(!strcmp(key, "soundOff")) {
|
rlm@1
|
1163 soundOffFlag = sdlFromHex(value) ? true : false;
|
rlm@1
|
1164 } else if(!strcmp(key, "soundEnable")) {
|
rlm@1
|
1165 int res = sdlFromHex(value) & 0x30f;
|
rlm@1
|
1166 soundEnableChannels(res);
|
rlm@1
|
1167 soundDisableChannels(~res);
|
rlm@1
|
1168 } else if(!strcmp(key, "soundEcho")) {
|
rlm@1
|
1169 soundEcho = sdlFromHex(value) ? true : false;
|
rlm@1
|
1170 } else if(!strcmp(key, "soundLowPass")) {
|
rlm@1
|
1171 soundLowPass = sdlFromHex(value) ? true : false;
|
rlm@1
|
1172 } else if(!strcmp(key, "soundReverse")) {
|
rlm@1
|
1173 soundReverse = sdlFromHex(value) ? true : false;
|
rlm@1
|
1174 } else if(!strcmp(key, "soundVolume")) {
|
rlm@1
|
1175 soundVolume = sdlFromHex(value);
|
rlm@1
|
1176 if(soundVolume < 0 || soundVolume > 3)
|
rlm@1
|
1177 soundVolume = 0;
|
rlm@1
|
1178 } else if(!strcmp(key, "removeIntros")) {
|
rlm@1
|
1179 removeIntros = sdlFromHex(value) ? true : false;
|
rlm@1
|
1180 } else if(!strcmp(key, "saveType")) {
|
rlm@1
|
1181 cpuSaveType = sdlFromHex(value);
|
rlm@1
|
1182 if(cpuSaveType < 0 || cpuSaveType > 5)
|
rlm@1
|
1183 cpuSaveType = 0;
|
rlm@1
|
1184 } else if(!strcmp(key, "flashSize")) {
|
rlm@1
|
1185 sdlFlashSize = sdlFromHex(value);
|
rlm@1
|
1186 if(sdlFlashSize != 0 && sdlFlashSize != 1)
|
rlm@1
|
1187 sdlFlashSize = 0;
|
rlm@1
|
1188 } else if(!strcmp(key, "ifbType")) {
|
rlm@1
|
1189 ifbType = sdlFromHex(value);
|
rlm@1
|
1190 if(ifbType < 0 || ifbType > 2)
|
rlm@1
|
1191 ifbType = 0;
|
rlm@1
|
1192 } else if(!strcmp(key, "showSpeed")) {
|
rlm@1
|
1193 showSpeed = sdlFromHex(value);
|
rlm@1
|
1194 if(showSpeed < 0 || showSpeed > 2)
|
rlm@1
|
1195 showSpeed = 1;
|
rlm@1
|
1196 } else if(!strcmp(key, "showSpeedTransparent")) {
|
rlm@1
|
1197 showSpeedTransparent = sdlFromHex(value);
|
rlm@1
|
1198 } else if(!strcmp(key, "autoFrameSkip")) {
|
rlm@1
|
1199 autoFrameSkip = sdlFromHex(value);
|
rlm@1
|
1200 } else if(!strcmp(key, "throttle")) {
|
rlm@1
|
1201 throttle = sdlFromHex(value);
|
rlm@1
|
1202 if(throttle != 0 && (throttle < 5 || throttle > 1000))
|
rlm@1
|
1203 throttle = 0;
|
rlm@1
|
1204 } else if(!strcmp(key, "disableMMX")) {
|
rlm@1
|
1205 #ifdef MMX
|
rlm@1
|
1206 cpu_mmx = sdlFromHex(value) ? false : true;
|
rlm@1
|
1207 #endif
|
rlm@1
|
1208 } else if(!strcmp(key, "pauseWhenInactive")) {
|
rlm@1
|
1209 pauseWhenInactive = sdlFromHex(value) ? true : false;
|
rlm@1
|
1210 } else if(!strcmp(key, "agbPrint")) {
|
rlm@1
|
1211 sdlAgbPrint = sdlFromHex(value);
|
rlm@1
|
1212 } else if(!strcmp(key, "rtcEnabled")) {
|
rlm@1
|
1213 sdlRtcEnable = sdlFromHex(value);
|
rlm@1
|
1214 } else if(!strcmp(key, "rewindTimer")) {
|
rlm@1
|
1215 rewindTimer = sdlFromHex(value);
|
rlm@1
|
1216 if(rewindTimer < 0 || rewindTimer > 600)
|
rlm@1
|
1217 rewindTimer = 0;
|
rlm@1
|
1218 rewindTimer *= 6; // convert value to 10 frames multiple
|
rlm@1
|
1219 } else if(!strcmp(key, "enhancedDetection")) {
|
rlm@1
|
1220 cpuEnhancedDetection = sdlFromHex(value) ? true : false;
|
rlm@1
|
1221 } else {
|
rlm@1
|
1222 fprintf(stderr, "Unknown configuration key %s\n", key);
|
rlm@1
|
1223 }
|
rlm@1
|
1224 }
|
rlm@1
|
1225 }
|
rlm@1
|
1226
|
rlm@1
|
1227 void sdlReadPreferences()
|
rlm@1
|
1228 {
|
rlm@1
|
1229 FILE *f = sdlFindFile("VisualBoyAdvance.cfg");
|
rlm@1
|
1230
|
rlm@1
|
1231 if(f == NULL) {
|
rlm@1
|
1232 fprintf(stderr, "Configuration file NOT FOUND (using defaults)\n");
|
rlm@1
|
1233 return;
|
rlm@1
|
1234 } else
|
rlm@1
|
1235 fprintf(stderr, "Reading configuration file.\n");
|
rlm@1
|
1236
|
rlm@1
|
1237 sdlReadPreferences(f);
|
rlm@1
|
1238
|
rlm@1
|
1239 fclose(f);
|
rlm@1
|
1240 }
|
rlm@1
|
1241
|
rlm@1
|
1242 static void sdlApplyPerImagePreferences()
|
rlm@1
|
1243 {
|
rlm@1
|
1244 FILE *f = sdlFindFile("vba-over.ini");
|
rlm@1
|
1245 if(!f) {
|
rlm@1
|
1246 fprintf(stderr, "vba-over.ini NOT FOUND (using emulator settings)\n");
|
rlm@1
|
1247 return;
|
rlm@1
|
1248 } else
|
rlm@1
|
1249 fprintf(stderr, "Reading vba-over.ini\n");
|
rlm@1
|
1250
|
rlm@1
|
1251 char buffer[7];
|
rlm@1
|
1252 buffer[0] = '[';
|
rlm@1
|
1253 buffer[1] = rom[0xac];
|
rlm@1
|
1254 buffer[2] = rom[0xad];
|
rlm@1
|
1255 buffer[3] = rom[0xae];
|
rlm@1
|
1256 buffer[4] = rom[0xaf];
|
rlm@1
|
1257 buffer[5] = ']';
|
rlm@1
|
1258 buffer[6] = 0;
|
rlm@1
|
1259
|
rlm@1
|
1260 char readBuffer[2048];
|
rlm@1
|
1261
|
rlm@1
|
1262 bool found = false;
|
rlm@1
|
1263
|
rlm@1
|
1264 while(1) {
|
rlm@1
|
1265 char *s = fgets(readBuffer, 2048, f);
|
rlm@1
|
1266
|
rlm@1
|
1267 if(s == NULL)
|
rlm@1
|
1268 break;
|
rlm@1
|
1269
|
rlm@1
|
1270 char *p = strchr(s, ';');
|
rlm@1
|
1271
|
rlm@1
|
1272 if(p)
|
rlm@1
|
1273 *p = 0;
|
rlm@1
|
1274
|
rlm@1
|
1275 char *token = strtok(s, " \t\n\r=");
|
rlm@1
|
1276
|
rlm@1
|
1277 if(!token)
|
rlm@1
|
1278 continue;
|
rlm@1
|
1279 if(strlen(token) == 0)
|
rlm@1
|
1280 continue;
|
rlm@1
|
1281
|
rlm@1
|
1282 if(!strcmp(token, buffer)) {
|
rlm@1
|
1283 found = true;
|
rlm@1
|
1284 break;
|
rlm@1
|
1285 }
|
rlm@1
|
1286 }
|
rlm@1
|
1287
|
rlm@1
|
1288 if(found) {
|
rlm@1
|
1289 while(1) {
|
rlm@1
|
1290 char *s = fgets(readBuffer, 2048, f);
|
rlm@1
|
1291
|
rlm@1
|
1292 if(s == NULL)
|
rlm@1
|
1293 break;
|
rlm@1
|
1294
|
rlm@1
|
1295 char *p = strchr(s, ';');
|
rlm@1
|
1296 if(p)
|
rlm@1
|
1297 *p = 0;
|
rlm@1
|
1298
|
rlm@1
|
1299 char *token = strtok(s, " \t\n\r=");
|
rlm@1
|
1300 if(!token)
|
rlm@1
|
1301 continue;
|
rlm@1
|
1302 if(strlen(token) == 0)
|
rlm@1
|
1303 continue;
|
rlm@1
|
1304
|
rlm@1
|
1305 if(token[0] == '[') // starting another image settings
|
rlm@1
|
1306 break;
|
rlm@1
|
1307 char *value = strtok(NULL, "\t\n\r=");
|
rlm@1
|
1308 if(value == NULL)
|
rlm@1
|
1309 continue;
|
rlm@1
|
1310
|
rlm@1
|
1311 if(!strcmp(token, "rtcEnabled"))
|
rlm@1
|
1312 rtcEnable(atoi(value) == 0 ? false : true);
|
rlm@1
|
1313 else if(!strcmp(token, "flashSize")) {
|
rlm@1
|
1314 int size = atoi(value);
|
rlm@1
|
1315 if(size == 0x10000 || size == 0x20000)
|
rlm@1
|
1316 flashSetSize(size);
|
rlm@1
|
1317 } else if(!strcmp(token, "saveType")) {
|
rlm@1
|
1318 int save = atoi(value);
|
rlm@1
|
1319 if(save >= 0 && save <= 5)
|
rlm@1
|
1320 cpuSaveType = save;
|
rlm@1
|
1321 }
|
rlm@1
|
1322 }
|
rlm@1
|
1323 }
|
rlm@1
|
1324 fclose(f);
|
rlm@1
|
1325 }
|
rlm@1
|
1326
|
rlm@1
|
1327 static int sdlCalculateShift(u32 mask)
|
rlm@1
|
1328 {
|
rlm@1
|
1329 int m = 0;
|
rlm@1
|
1330
|
rlm@1
|
1331 while(mask) {
|
rlm@1
|
1332 m++;
|
rlm@1
|
1333 mask >>= 1;
|
rlm@1
|
1334 }
|
rlm@1
|
1335
|
rlm@1
|
1336 return m-5;
|
rlm@1
|
1337 }
|
rlm@1
|
1338
|
rlm@1
|
1339 static int sdlCalculateMaskWidth(u32 mask)
|
rlm@1
|
1340 {
|
rlm@1
|
1341 int m = 0;
|
rlm@1
|
1342 int mask2 = mask;
|
rlm@1
|
1343
|
rlm@1
|
1344 while(mask2) {
|
rlm@1
|
1345 m++;
|
rlm@1
|
1346 mask2 >>= 1;
|
rlm@1
|
1347 }
|
rlm@1
|
1348
|
rlm@1
|
1349 int m2 = 0;
|
rlm@1
|
1350 mask2 = mask;
|
rlm@1
|
1351 while(!(mask2 & 1)) {
|
rlm@1
|
1352 m2++;
|
rlm@1
|
1353 mask2 >>= 1;
|
rlm@1
|
1354 }
|
rlm@1
|
1355
|
rlm@1
|
1356 return m - m2;
|
rlm@1
|
1357 }
|
rlm@1
|
1358
|
rlm@1
|
1359 void sdlWriteState(int num)
|
rlm@1
|
1360 {
|
rlm@1
|
1361 char stateName[2048];
|
rlm@1
|
1362
|
rlm@1
|
1363 if(saveDir[0])
|
rlm@1
|
1364 sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename),
|
rlm@1
|
1365 num+1);
|
rlm@1
|
1366 else
|
rlm@1
|
1367 sprintf(stateName,"%s%d.sgm", filename, num+1);
|
rlm@1
|
1368 if(theEmulator.emuWriteState)
|
rlm@1
|
1369 theEmulator.emuWriteState(stateName);
|
rlm@1
|
1370 sprintf(stateName, "Wrote state %d", num+1);
|
rlm@1
|
1371 systemScreenMessage(stateName);
|
rlm@1
|
1372 }
|
rlm@1
|
1373
|
rlm@1
|
1374 void sdlReadState(int num)
|
rlm@1
|
1375 {
|
rlm@1
|
1376 char stateName[2048];
|
rlm@1
|
1377
|
rlm@1
|
1378 if(saveDir[0])
|
rlm@1
|
1379 sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename),
|
rlm@1
|
1380 num+1);
|
rlm@1
|
1381 else
|
rlm@1
|
1382 sprintf(stateName,"%s%d.sgm", filename, num+1);
|
rlm@1
|
1383
|
rlm@1
|
1384 if(theEmulator.emuReadState)
|
rlm@1
|
1385 theEmulator.emuReadState(stateName);
|
rlm@1
|
1386
|
rlm@1
|
1387 sprintf(stateName, "Loaded state %d", num+1);
|
rlm@1
|
1388 systemScreenMessage(stateName);
|
rlm@1
|
1389 }
|
rlm@1
|
1390
|
rlm@1
|
1391 void sdlWriteBattery()
|
rlm@1
|
1392 {
|
rlm@1
|
1393 char buffer[1048];
|
rlm@1
|
1394
|
rlm@1
|
1395 if(batteryDir[0])
|
rlm@1
|
1396 sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename));
|
rlm@1
|
1397 else
|
rlm@1
|
1398 sprintf(buffer, "%s.sav", filename);
|
rlm@1
|
1399
|
rlm@1
|
1400 theEmulator.emuWriteBattery(buffer);
|
rlm@1
|
1401
|
rlm@1
|
1402 systemScreenMessage("Wrote battery");
|
rlm@1
|
1403 }
|
rlm@1
|
1404
|
rlm@1
|
1405 void sdlReadBattery()
|
rlm@1
|
1406 {
|
rlm@1
|
1407 char buffer[1048];
|
rlm@1
|
1408
|
rlm@1
|
1409 if(batteryDir[0])
|
rlm@1
|
1410 sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename));
|
rlm@1
|
1411 else
|
rlm@1
|
1412 sprintf(buffer, "%s.sav", filename);
|
rlm@1
|
1413
|
rlm@1
|
1414 bool res = false;
|
rlm@1
|
1415
|
rlm@1
|
1416 res = theEmulator.emuReadBattery(buffer);
|
rlm@1
|
1417
|
rlm@1
|
1418 if(res)
|
rlm@1
|
1419 systemScreenMessage("Loaded battery");
|
rlm@1
|
1420 }
|
rlm@1
|
1421
|
rlm@1
|
1422 #define MOD_KEYS (KMOD_CTRL|KMOD_SHIFT|KMOD_ALT|KMOD_META)
|
rlm@1
|
1423 #define MOD_NOCTRL (KMOD_SHIFT|KMOD_ALT|KMOD_META)
|
rlm@1
|
1424 #define MOD_NOALT (KMOD_CTRL|KMOD_SHIFT|KMOD_META)
|
rlm@1
|
1425 #define MOD_NOSHIFT (KMOD_CTRL|KMOD_ALT|KMOD_META)
|
rlm@1
|
1426
|
rlm@1
|
1427 void sdlUpdateKey(int key, bool down)
|
rlm@1
|
1428 {
|
rlm@1
|
1429 int i;
|
rlm@1
|
1430 for(int j = 0; j < 4; j++) {
|
rlm@1
|
1431 for(i = 0 ; i < 12; i++) {
|
rlm@1
|
1432 if((joypad[j][i] & 0xf000) == 0) {
|
rlm@1
|
1433 if(key == joypad[j][i])
|
rlm@1
|
1434 if (down) currentButtons[j] |= 1<<i;
|
rlm@1
|
1435 else currentButtons[j] ^= 1<<i;
|
rlm@1
|
1436 }
|
rlm@1
|
1437 }
|
rlm@1
|
1438 }
|
rlm@1
|
1439 for(i = 0 ; i < 4; i++) {
|
rlm@1
|
1440 if((motion[i] & 0xf000) == 0) {
|
rlm@1
|
1441 if(key == motion[i])
|
rlm@1
|
1442 sdlMotionButtons[i] = down;
|
rlm@1
|
1443 }
|
rlm@1
|
1444 }
|
rlm@1
|
1445 }
|
rlm@1
|
1446
|
rlm@1
|
1447 void sdlUpdateJoyButton(int which,
|
rlm@1
|
1448 int button,
|
rlm@1
|
1449 bool pressed)
|
rlm@1
|
1450 {
|
rlm@1
|
1451 int i;
|
rlm@1
|
1452 for(int j = 0; j < 4; j++) {
|
rlm@1
|
1453 for(i = 0; i < 12; i++) {
|
rlm@1
|
1454 int dev = (joypad[j][i] >> 12);
|
rlm@1
|
1455 int b = joypad[j][i] & 0xfff;
|
rlm@1
|
1456 if(dev) {
|
rlm@1
|
1457 dev--;
|
rlm@1
|
1458
|
rlm@1
|
1459 if((dev == which) && (b >= 128) && (b == (button+128))) {
|
rlm@1
|
1460 if (pressed) currentButtons[j] |= 1<<i;
|
rlm@1
|
1461 else currentButtons[j] ^= 1<<i;
|
rlm@1
|
1462 }
|
rlm@1
|
1463 }
|
rlm@1
|
1464 }
|
rlm@1
|
1465 }
|
rlm@1
|
1466 for(i = 0; i < 4; i++) {
|
rlm@1
|
1467 int dev = (motion[i] >> 12);
|
rlm@1
|
1468 int b = motion[i] & 0xfff;
|
rlm@1
|
1469 if(dev) {
|
rlm@1
|
1470 dev--;
|
rlm@1
|
1471
|
rlm@1
|
1472 if((dev == which) && (b >= 128) && (b == (button+128))) {
|
rlm@1
|
1473 sdlMotionButtons[i] = pressed;
|
rlm@1
|
1474 }
|
rlm@1
|
1475 }
|
rlm@1
|
1476 }
|
rlm@1
|
1477 }
|
rlm@1
|
1478
|
rlm@1
|
1479 void sdlUpdateJoyHat(int which,
|
rlm@1
|
1480 int hat,
|
rlm@1
|
1481 int value)
|
rlm@1
|
1482 {
|
rlm@1
|
1483 int i;
|
rlm@1
|
1484 for(int j = 0; j < 4; j++) {
|
rlm@1
|
1485 for(i = 0; i < 12; i++) {
|
rlm@1
|
1486 int dev = (joypad[j][i] >> 12);
|
rlm@1
|
1487 int a = joypad[j][i] & 0xfff;
|
rlm@1
|
1488 if(dev) {
|
rlm@1
|
1489 dev--;
|
rlm@1
|
1490
|
rlm@1
|
1491 if((dev == which) && (a>=32) && (a < 48) && (((a&15)>>2) == hat)) {
|
rlm@1
|
1492 int dir = a & 3;
|
rlm@1
|
1493 int v = 0;
|
rlm@1
|
1494 switch(dir) {
|
rlm@1
|
1495 case 0:
|
rlm@1
|
1496 v = value & SDL_HAT_UP;
|
rlm@1
|
1497 break;
|
rlm@1
|
1498 case 1:
|
rlm@1
|
1499 v = value & SDL_HAT_DOWN;
|
rlm@1
|
1500 break;
|
rlm@1
|
1501 case 2:
|
rlm@1
|
1502 v = value & SDL_HAT_RIGHT;
|
rlm@1
|
1503 break;
|
rlm@1
|
1504 case 3:
|
rlm@1
|
1505 v = value & SDL_HAT_LEFT;
|
rlm@1
|
1506 break;
|
rlm@1
|
1507 }
|
rlm@1
|
1508 if (v) currentButtons[j] |= 1<<i;
|
rlm@1
|
1509 else currentButtons[j] ^= 1<<i;
|
rlm@1
|
1510 }
|
rlm@1
|
1511 }
|
rlm@1
|
1512 }
|
rlm@1
|
1513 }
|
rlm@1
|
1514 for(i = 0; i < 4; i++) {
|
rlm@1
|
1515 int dev = (motion[i] >> 12);
|
rlm@1
|
1516 int a = motion[i] & 0xfff;
|
rlm@1
|
1517 if(dev) {
|
rlm@1
|
1518 dev--;
|
rlm@1
|
1519
|
rlm@1
|
1520 if((dev == which) && (a>=32) && (a < 48) && (((a&15)>>2) == hat)) {
|
rlm@1
|
1521 int dir = a & 3;
|
rlm@1
|
1522 int v = 0;
|
rlm@1
|
1523 switch(dir) {
|
rlm@1
|
1524 case 0:
|
rlm@1
|
1525 v = value & SDL_HAT_UP;
|
rlm@1
|
1526 break;
|
rlm@1
|
1527 case 1:
|
rlm@1
|
1528 v = value & SDL_HAT_DOWN;
|
rlm@1
|
1529 break;
|
rlm@1
|
1530 case 2:
|
rlm@1
|
1531 v = value & SDL_HAT_RIGHT;
|
rlm@1
|
1532 break;
|
rlm@1
|
1533 case 3:
|
rlm@1
|
1534 v = value & SDL_HAT_LEFT;
|
rlm@1
|
1535 break;
|
rlm@1
|
1536 }
|
rlm@1
|
1537 sdlMotionButtons[i] = (v ? true : false);
|
rlm@1
|
1538 }
|
rlm@1
|
1539 }
|
rlm@1
|
1540 }
|
rlm@1
|
1541 }
|
rlm@1
|
1542
|
rlm@1
|
1543 void sdlUpdateJoyAxis(int which,
|
rlm@1
|
1544 int axis,
|
rlm@1
|
1545 int value)
|
rlm@1
|
1546 {
|
rlm@1
|
1547 int i;
|
rlm@1
|
1548 for(int j = 0; j < 4; j++) {
|
rlm@1
|
1549 for(i = 0; i < 12; i++) {
|
rlm@1
|
1550 int dev = (joypad[j][i] >> 12);
|
rlm@1
|
1551 int a = joypad[j][i] & 0xfff;
|
rlm@1
|
1552 if(dev) {
|
rlm@1
|
1553 dev--;
|
rlm@1
|
1554
|
rlm@1
|
1555 if((dev == which) && (a < 32) && ((a>>1) == axis)) {
|
rlm@1
|
1556 //I have no idea what this does, is this reimplementation correct? --Felipe
|
rlm@1
|
1557 if (value>16384) {
|
rlm@1
|
1558 if (a&1) currentButtons[j] |= 1<<i;
|
rlm@1
|
1559 else currentButtons[j] ^= 1<<i;
|
rlm@1
|
1560 }
|
rlm@1
|
1561 else if (value<16384){
|
rlm@1
|
1562 if (a&1) currentButtons[j] ^= 1<<i;
|
rlm@1
|
1563 else currentButtons[j] |= 1<<i;
|
rlm@1
|
1564 }
|
rlm@1
|
1565 }
|
rlm@1
|
1566 }
|
rlm@1
|
1567 }
|
rlm@1
|
1568 }
|
rlm@1
|
1569 for(i = 0; i < 4; i++) {
|
rlm@1
|
1570 int dev = (motion[i] >> 12);
|
rlm@1
|
1571 int a = motion[i] & 0xfff;
|
rlm@1
|
1572 if(dev) {
|
rlm@1
|
1573 dev--;
|
rlm@1
|
1574
|
rlm@1
|
1575 if((dev == which) && (a < 32) && ((a>>1) == axis)) {
|
rlm@1
|
1576 sdlMotionButtons[i] = (a & 1) ? (value > 16384) : (value < -16384);
|
rlm@1
|
1577 }
|
rlm@1
|
1578 }
|
rlm@1
|
1579 }
|
rlm@1
|
1580 }
|
rlm@1
|
1581
|
rlm@1
|
1582 bool sdlCheckJoyKey(int key)
|
rlm@1
|
1583 {
|
rlm@1
|
1584 int dev = (key >> 12) - 1;
|
rlm@1
|
1585 int what = key & 0xfff;
|
rlm@1
|
1586
|
rlm@1
|
1587 if(what >= 128) {
|
rlm@1
|
1588 // joystick button
|
rlm@1
|
1589 int button = what - 128;
|
rlm@1
|
1590
|
rlm@1
|
1591 if(button >= SDL_JoystickNumButtons(sdlDevices[dev]))
|
rlm@1
|
1592 return false;
|
rlm@1
|
1593 } else if (what < 0x20) {
|
rlm@1
|
1594 // joystick axis
|
rlm@1
|
1595 what >>= 1;
|
rlm@1
|
1596 if(what >= SDL_JoystickNumAxes(sdlDevices[dev]))
|
rlm@1
|
1597 return false;
|
rlm@1
|
1598 } else if (what < 0x30) {
|
rlm@1
|
1599 // joystick hat
|
rlm@1
|
1600 what = (what & 15);
|
rlm@1
|
1601 what >>= 2;
|
rlm@1
|
1602 if(what >= SDL_JoystickNumHats(sdlDevices[dev]))
|
rlm@1
|
1603 return false;
|
rlm@1
|
1604 }
|
rlm@1
|
1605
|
rlm@1
|
1606 // no problem found
|
rlm@1
|
1607 return true;
|
rlm@1
|
1608 }
|
rlm@1
|
1609
|
rlm@1
|
1610 void sdlCheckKeys()
|
rlm@1
|
1611 {
|
rlm@1
|
1612 sdlNumDevices = SDL_NumJoysticks();
|
rlm@1
|
1613
|
rlm@1
|
1614 if(sdlNumDevices)
|
rlm@1
|
1615 sdlDevices = (SDL_Joystick **)calloc(1,sdlNumDevices *
|
rlm@1
|
1616 sizeof(SDL_Joystick **));
|
rlm@1
|
1617 int i;
|
rlm@1
|
1618
|
rlm@1
|
1619 bool usesJoy = false;
|
rlm@1
|
1620
|
rlm@1
|
1621 for(int j = 0; j < 4; j++) {
|
rlm@1
|
1622 for(i = 0; i < 12; i++) {
|
rlm@1
|
1623 int dev = joypad[j][i] >> 12;
|
rlm@1
|
1624 if(dev) {
|
rlm@1
|
1625 dev--;
|
rlm@1
|
1626 bool ok = false;
|
rlm@1
|
1627
|
rlm@1
|
1628 if(sdlDevices) {
|
rlm@1
|
1629 if(dev < sdlNumDevices) {
|
rlm@1
|
1630 if(sdlDevices[dev] == NULL) {
|
rlm@1
|
1631 sdlDevices[dev] = SDL_JoystickOpen(dev);
|
rlm@1
|
1632 }
|
rlm@1
|
1633
|
rlm@1
|
1634 ok = sdlCheckJoyKey(joypad[j][i]);
|
rlm@1
|
1635 } else
|
rlm@1
|
1636 ok = false;
|
rlm@1
|
1637 }
|
rlm@1
|
1638
|
rlm@1
|
1639 if(!ok)
|
rlm@1
|
1640 joypad[j][i] = defaultJoypad[i];
|
rlm@1
|
1641 else
|
rlm@1
|
1642 usesJoy = true;
|
rlm@1
|
1643 }
|
rlm@1
|
1644 }
|
rlm@1
|
1645 }
|
rlm@1
|
1646
|
rlm@1
|
1647 for(i = 0; i < 4; i++) {
|
rlm@1
|
1648 int dev = motion[i] >> 12;
|
rlm@1
|
1649 if(dev) {
|
rlm@1
|
1650 dev--;
|
rlm@1
|
1651 bool ok = false;
|
rlm@1
|
1652
|
rlm@1
|
1653 if(sdlDevices) {
|
rlm@1
|
1654 if(dev < sdlNumDevices) {
|
rlm@1
|
1655 if(sdlDevices[dev] == NULL) {
|
rlm@1
|
1656 sdlDevices[dev] = SDL_JoystickOpen(dev);
|
rlm@1
|
1657 }
|
rlm@1
|
1658
|
rlm@1
|
1659 ok = sdlCheckJoyKey(motion[i]);
|
rlm@1
|
1660 } else
|
rlm@1
|
1661 ok = false;
|
rlm@1
|
1662 }
|
rlm@1
|
1663
|
rlm@1
|
1664 if(!ok)
|
rlm@1
|
1665 motion[i] = defaultMotion[i];
|
rlm@1
|
1666 else
|
rlm@1
|
1667 usesJoy = true;
|
rlm@1
|
1668 }
|
rlm@1
|
1669 }
|
rlm@1
|
1670
|
rlm@1
|
1671 if(usesJoy)
|
rlm@1
|
1672 SDL_JoystickEventState(SDL_ENABLE);
|
rlm@1
|
1673 }
|
rlm@1
|
1674
|
rlm@1
|
1675 void sdlPollEvents()
|
rlm@1
|
1676 {
|
rlm@1
|
1677 SDL_Event event;
|
rlm@1
|
1678 while(SDL_PollEvent(&event)) {
|
rlm@1
|
1679 switch(event.type) {
|
rlm@1
|
1680 case SDL_QUIT:
|
rlm@1
|
1681 emulating = 0;
|
rlm@1
|
1682 break;
|
rlm@1
|
1683 case SDL_ACTIVEEVENT:
|
rlm@1
|
1684 if(pauseWhenInactive && (event.active.state & SDL_APPINPUTFOCUS)) {
|
rlm@1
|
1685 active = event.active.gain;
|
rlm@1
|
1686 if(active) {
|
rlm@1
|
1687 if(!paused) {
|
rlm@1
|
1688 if(emulating)
|
rlm@1
|
1689 soundResume();
|
rlm@1
|
1690 }
|
rlm@1
|
1691 } else {
|
rlm@1
|
1692 wasPaused = true;
|
rlm@1
|
1693 if(pauseWhenInactive) {
|
rlm@1
|
1694 if(emulating)
|
rlm@1
|
1695 soundPause();
|
rlm@1
|
1696 }
|
rlm@1
|
1697
|
rlm@1
|
1698 memset(delta,255,sizeof(delta));
|
rlm@1
|
1699 }
|
rlm@1
|
1700 }
|
rlm@1
|
1701 break;
|
rlm@1
|
1702 case SDL_MOUSEMOTION:
|
rlm@1
|
1703 case SDL_MOUSEBUTTONUP:
|
rlm@1
|
1704 case SDL_MOUSEBUTTONDOWN:
|
rlm@1
|
1705 if(fullscreen) {
|
rlm@1
|
1706 SDL_ShowCursor(SDL_ENABLE);
|
rlm@1
|
1707 mouseCounter = 120;
|
rlm@1
|
1708 }
|
rlm@1
|
1709 break;
|
rlm@1
|
1710 case SDL_JOYHATMOTION:
|
rlm@1
|
1711 sdlUpdateJoyHat(event.jhat.which,
|
rlm@1
|
1712 event.jhat.hat,
|
rlm@1
|
1713 event.jhat.value);
|
rlm@1
|
1714 break;
|
rlm@1
|
1715 case SDL_JOYBUTTONDOWN:
|
rlm@1
|
1716 case SDL_JOYBUTTONUP:
|
rlm@1
|
1717 sdlUpdateJoyButton(event.jbutton.which,
|
rlm@1
|
1718 event.jbutton.button,
|
rlm@1
|
1719 event.jbutton.state == SDL_PRESSED);
|
rlm@1
|
1720 break;
|
rlm@1
|
1721 case SDL_JOYAXISMOTION:
|
rlm@1
|
1722 sdlUpdateJoyAxis(event.jaxis.which,
|
rlm@1
|
1723 event.jaxis.axis,
|
rlm@1
|
1724 event.jaxis.value);
|
rlm@1
|
1725 break;
|
rlm@1
|
1726 case SDL_KEYDOWN:
|
rlm@1
|
1727 sdlUpdateKey(event.key.keysym.sym, true);
|
rlm@1
|
1728 break;
|
rlm@1
|
1729 case SDL_KEYUP:
|
rlm@1
|
1730 switch(event.key.keysym.sym) {
|
rlm@1
|
1731 case SDLK_r:
|
rlm@1
|
1732 if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
rlm@1
|
1733 (event.key.keysym.mod & KMOD_CTRL)) {
|
rlm@1
|
1734 if(emulating) {
|
rlm@1
|
1735 theEmulator.emuReset(true);
|
rlm@1
|
1736
|
rlm@1
|
1737 systemScreenMessage("Reset");
|
rlm@1
|
1738 }
|
rlm@1
|
1739 }
|
rlm@1
|
1740 break;
|
rlm@1
|
1741 case SDLK_b:
|
rlm@1
|
1742 if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
rlm@1
|
1743 (event.key.keysym.mod & KMOD_CTRL)) {
|
rlm@1
|
1744 if(emulating && theEmulator.emuReadMemState && rewindMemory
|
rlm@1
|
1745 && rewindCount) {
|
rlm@1
|
1746 rewindPos = --rewindPos & 7;
|
rlm@1
|
1747 theEmulator.emuReadMemState(&rewindMemory[REWIND_SIZE*rewindPos],
|
rlm@1
|
1748 REWIND_SIZE);
|
rlm@1
|
1749 rewindCount--;
|
rlm@1
|
1750 rewindCounter = 0;
|
rlm@1
|
1751 systemScreenMessage("Rewind");
|
rlm@1
|
1752 }
|
rlm@1
|
1753 }
|
rlm@1
|
1754 break;
|
rlm@1
|
1755 case SDLK_p:
|
rlm@1
|
1756 if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
rlm@1
|
1757 (event.key.keysym.mod & KMOD_CTRL)) {
|
rlm@1
|
1758 paused = !paused;
|
rlm@1
|
1759 SDL_PauseAudio(paused);
|
rlm@1
|
1760 if(paused)
|
rlm@1
|
1761 wasPaused = true;
|
rlm@1
|
1762 }
|
rlm@1
|
1763 break;
|
rlm@1
|
1764 case SDLK_ESCAPE:
|
rlm@1
|
1765 emulating = 0;
|
rlm@1
|
1766 break;
|
rlm@1
|
1767 case SDLK_f:
|
rlm@1
|
1768 if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
rlm@1
|
1769 (event.key.keysym.mod & KMOD_CTRL)) {
|
rlm@1
|
1770 int flags = 0;
|
rlm@1
|
1771 fullscreen = !fullscreen;
|
rlm@1
|
1772 if(fullscreen)
|
rlm@1
|
1773 flags |= SDL_FULLSCREEN;
|
rlm@1
|
1774 SDL_SetVideoMode(destWidth, destHeight, systemColorDepth, flags);
|
rlm@1
|
1775 // if(SDL_WM_ToggleFullScreen(surface))
|
rlm@1
|
1776 // fullscreen = !fullscreen;
|
rlm@1
|
1777 }
|
rlm@1
|
1778 break;
|
rlm@1
|
1779 case SDLK_F11:
|
rlm@1
|
1780 if(dbgMain != debuggerMain) {
|
rlm@1
|
1781 if(armState) {
|
rlm@1
|
1782 armNextPC -= 4;
|
rlm@1
|
1783 reg[15].I -= 4;
|
rlm@1
|
1784 } else {
|
rlm@1
|
1785 armNextPC -= 2;
|
rlm@1
|
1786 reg[15].I -= 2;
|
rlm@1
|
1787 }
|
rlm@1
|
1788 }
|
rlm@1
|
1789 debugger = true;
|
rlm@1
|
1790 break;
|
rlm@1
|
1791 case SDLK_F1:
|
rlm@1
|
1792 case SDLK_F2:
|
rlm@1
|
1793 case SDLK_F3:
|
rlm@1
|
1794 case SDLK_F4:
|
rlm@1
|
1795 case SDLK_F5:
|
rlm@1
|
1796 case SDLK_F6:
|
rlm@1
|
1797 case SDLK_F7:
|
rlm@1
|
1798 case SDLK_F8:
|
rlm@1
|
1799 case SDLK_F9:
|
rlm@1
|
1800 case SDLK_F10:
|
rlm@1
|
1801 if(!(event.key.keysym.mod & MOD_NOSHIFT) &&
|
rlm@1
|
1802 (event.key.keysym.mod & KMOD_SHIFT)) {
|
rlm@1
|
1803 sdlWriteState(event.key.keysym.sym-SDLK_F1);
|
rlm@1
|
1804 } else if(!(event.key.keysym.mod & MOD_KEYS)) {
|
rlm@1
|
1805 sdlReadState(event.key.keysym.sym-SDLK_F1);
|
rlm@1
|
1806 }
|
rlm@1
|
1807 break;
|
rlm@1
|
1808 case SDLK_1:
|
rlm@1
|
1809 case SDLK_2:
|
rlm@1
|
1810 case SDLK_3:
|
rlm@1
|
1811 case SDLK_4:
|
rlm@1
|
1812 if(!(event.key.keysym.mod & MOD_NOALT) &&
|
rlm@1
|
1813 (event.key.keysym.mod & KMOD_ALT)) {
|
rlm@1
|
1814 char *disableMessages[4] =
|
rlm@1
|
1815 { "autofire A disabled",
|
rlm@1
|
1816 "autofire B disabled",
|
rlm@1
|
1817 "autofire R disabled",
|
rlm@1
|
1818 "autofire L disabled"};
|
rlm@1
|
1819 char *enableMessages[4] =
|
rlm@1
|
1820 { "autofire A",
|
rlm@1
|
1821 "autofire B",
|
rlm@1
|
1822 "autofire R",
|
rlm@1
|
1823 "autofire L"};
|
rlm@1
|
1824 int mask = 1 << (event.key.keysym.sym - SDLK_1);
|
rlm@1
|
1825 if(event.key.keysym.sym > SDLK_2)
|
rlm@1
|
1826 mask <<= 6;
|
rlm@1
|
1827 if(autoFire & mask) {
|
rlm@1
|
1828 autoFire &= ~mask;
|
rlm@1
|
1829 systemScreenMessage(disableMessages[event.key.keysym.sym - SDLK_1]);
|
rlm@1
|
1830 } else {
|
rlm@1
|
1831 autoFire |= mask;
|
rlm@1
|
1832 systemScreenMessage(enableMessages[event.key.keysym.sym - SDLK_1]);
|
rlm@1
|
1833 }
|
rlm@1
|
1834 } if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
rlm@1
|
1835 (event.key.keysym.mod & KMOD_CTRL)) {
|
rlm@1
|
1836 int mask = 0x0100 << (event.key.keysym.sym - SDLK_1);
|
rlm@1
|
1837 layerSettings ^= mask;
|
rlm@1
|
1838 layerEnable = DISPCNT & layerSettings;
|
rlm@1
|
1839 CPUUpdateRenderBuffers(false);
|
rlm@1
|
1840 }
|
rlm@1
|
1841 break;
|
rlm@1
|
1842 case SDLK_5:
|
rlm@1
|
1843 case SDLK_6:
|
rlm@1
|
1844 case SDLK_7:
|
rlm@1
|
1845 case SDLK_8:
|
rlm@1
|
1846 if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
rlm@1
|
1847 (event.key.keysym.mod & KMOD_CTRL)) {
|
rlm@1
|
1848 int mask = 0x0100 << (event.key.keysym.sym - SDLK_1);
|
rlm@1
|
1849 layerSettings ^= mask;
|
rlm@1
|
1850 layerEnable = DISPCNT & layerSettings;
|
rlm@1
|
1851 }
|
rlm@1
|
1852 break;
|
rlm@1
|
1853 case SDLK_n:
|
rlm@1
|
1854 if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
rlm@1
|
1855 (event.key.keysym.mod & KMOD_CTRL)) {
|
rlm@1
|
1856 if(paused)
|
rlm@1
|
1857 paused = false;
|
rlm@1
|
1858 pauseNextFrame = true;
|
rlm@1
|
1859 }
|
rlm@1
|
1860 break;
|
rlm@1
|
1861 default:
|
rlm@1
|
1862 break;
|
rlm@1
|
1863 }
|
rlm@1
|
1864 sdlUpdateKey(event.key.keysym.sym, false);
|
rlm@1
|
1865 break;
|
rlm@1
|
1866 }
|
rlm@1
|
1867 }
|
rlm@1
|
1868 }
|
rlm@1
|
1869
|
rlm@1
|
1870 void usage(char *cmd)
|
rlm@1
|
1871 {
|
rlm@1
|
1872 printf("%s [option ...] file\n", cmd);
|
rlm@1
|
1873 printf("\
|
rlm@1
|
1874 \n\
|
rlm@1
|
1875 Options:\n\
|
rlm@1
|
1876 -1, --video-1x 1x\n\
|
rlm@1
|
1877 -2, --video-2x 2x\n\
|
rlm@1
|
1878 -3, --video-3x 3x\n\
|
rlm@1
|
1879 -4, --video-4x 4x\n\
|
rlm@1
|
1880 -F, --fullscreen Full screen\n\
|
rlm@1
|
1881 -G, --gdb=PROTOCOL GNU Remote Stub mode:\n\
|
rlm@1
|
1882 tcp - use TCP at port 55555\n\
|
rlm@1
|
1883 tcp:PORT - use TCP at port PORT\n\
|
rlm@1
|
1884 pipe - use pipe transport\n\
|
rlm@1
|
1885 -N, --no-debug Don't parse debug information\n\
|
rlm@1
|
1886 -S, --flash-size=SIZE Set the Flash size\n\
|
rlm@1
|
1887 --flash-64k 0 - 64K Flash\n\
|
rlm@1
|
1888 --flash-128k 1 - 128K Flash\n\
|
rlm@1
|
1889 -T, --throttle=THROTTLE Set the desired throttle (5...1000)\n\
|
rlm@1
|
1890 -Y, --yuv=TYPE Use YUV overlay for drawing:\n\
|
rlm@1
|
1891 0 - YV12\n\
|
rlm@1
|
1892 1 - UYVY\n\
|
rlm@1
|
1893 2 - YVYU\n\
|
rlm@1
|
1894 3 - YUY2\n\
|
rlm@1
|
1895 4 - IYUV\n\
|
rlm@1
|
1896 -b, --bios=BIOS Use given bios file\n\
|
rlm@1
|
1897 -c, --config=FILE Read the given configuration file\n\
|
rlm@1
|
1898 -d, --debug Enter debugger\n\
|
rlm@1
|
1899 -f, --filter=FILTER Select filter:\n\
|
rlm@1
|
1900 --filter-normal 0 - normal mode\n\
|
rlm@1
|
1901 --filter-tv-mode 1 - TV Mode\n\
|
rlm@1
|
1902 --filter-2xsai 2 - 2xSaI\n\
|
rlm@1
|
1903 --filter-super-2xsai 3 - Super 2xSaI\n\
|
rlm@1
|
1904 --filter-super-eagle 4 - Super Eagle\n\
|
rlm@1
|
1905 --filter-pixelate 5 - Pixelate\n\
|
rlm@1
|
1906 --filter-motion-blur 6 - Motion Blur\n\
|
rlm@1
|
1907 --filter-advmame 7 - AdvanceMAME Scale2x\n\
|
rlm@1
|
1908 --filter-simple2x 8 - Simple2x\n\
|
rlm@1
|
1909 --filter-bilinear 9 - Bilinear\n\
|
rlm@1
|
1910 --filter-bilinear+ 10 - Bilinear Plus\n\
|
rlm@1
|
1911 --filter-scanlines 11 - Scanlines\n\
|
rlm@1
|
1912 --filter-hq2x 12 - hq2x\n\
|
rlm@1
|
1913 --filter-lq2x 13 - lq2x\n\
|
rlm@1
|
1914 -h, --help Print this help\n\
|
rlm@1
|
1915 -i, --ips=PATCH Apply given IPS patch\n\
|
rlm@1
|
1916 -P, --profile=[HERTZ] Enable profiling\n\
|
rlm@1
|
1917 -s, --frameskip=FRAMESKIP Set frame skip (0...9)\n\
|
rlm@1
|
1918 ");
|
rlm@1
|
1919 printf("\
|
rlm@1
|
1920 -t, --save-type=TYPE Set the available save type\n\
|
rlm@1
|
1921 --save-auto 0 - Automatic (EEPROM, SRAM, FLASH)\n\
|
rlm@1
|
1922 --save-eeprom 1 - EEPROM\n\
|
rlm@1
|
1923 --save-sram 2 - SRAM\n\
|
rlm@1
|
1924 --save-flash 3 - FLASH\n\
|
rlm@1
|
1925 --save-sensor 4 - EEPROM+Sensor\n\
|
rlm@1
|
1926 --save-none 5 - NONE\n\
|
rlm@1
|
1927 -v, --verbose=VERBOSE Set verbose logging (trace.log)\n\
|
rlm@1
|
1928 1 - SWI\n\
|
rlm@1
|
1929 2 - Unaligned memory access\n\
|
rlm@1
|
1930 4 - Illegal memory write\n\
|
rlm@1
|
1931 8 - Illegal memory read\n\
|
rlm@1
|
1932 16 - DMA 0\n\
|
rlm@1
|
1933 32 - DMA 1\n\
|
rlm@1
|
1934 64 - DMA 2\n\
|
rlm@1
|
1935 128 - DMA 3\n\
|
rlm@1
|
1936 256 - Undefined instruction\n\
|
rlm@1
|
1937 512 - AGBPrint messages\n\
|
rlm@1
|
1938 \n\
|
rlm@1
|
1939 Long options only:\n\
|
rlm@1
|
1940 --agb-print Enable AGBPrint support\n\
|
rlm@1
|
1941 --auto-frameskip Enable auto frameskipping\n\
|
rlm@1
|
1942 --ifb-none No interframe blending\n\
|
rlm@1
|
1943 --ifb-motion-blur Interframe motion blur\n\
|
rlm@1
|
1944 --ifb-smart Smart interframe blending\n\
|
rlm@1
|
1945 --no-agb-print Disable AGBPrint support\n\
|
rlm@1
|
1946 --no-auto-frameskip Disable auto frameskipping\n\
|
rlm@1
|
1947 --no-ips Do not apply IPS patch\n\
|
rlm@1
|
1948 --no-mmx Disable MMX support\n\
|
rlm@1
|
1949 --no-pause-when-inactive Don't pause when inactive\n\
|
rlm@1
|
1950 --no-rtc Disable RTC support\n\
|
rlm@1
|
1951 --no-show-speed Don't show emulation speed\n\
|
rlm@1
|
1952 --no-throttle Disable thrrotle\n\
|
rlm@1
|
1953 --pause-when-inactive Pause when inactive\n\
|
rlm@1
|
1954 --rtc Enable RTC support\n\
|
rlm@1
|
1955 --show-speed-normal Show emulation speed\n\
|
rlm@1
|
1956 --show-speed-detailed Show detailed speed data\n\
|
rlm@1
|
1957 ");
|
rlm@1
|
1958 printf("\
|
rlm@1
|
1959 -r, --recordmovie=filename Start recording input movie\n\
|
rlm@1
|
1960 -p, --playmovie=filename Play input movie non-read-only\n\
|
rlm@1
|
1961 -w, --watchmovie=filename Play input movie in read-only mode\n\
|
rlm@1
|
1962 ");
|
rlm@1
|
1963 }
|
rlm@1
|
1964
|
rlm@1
|
1965 static char *szFile;
|
rlm@1
|
1966
|
rlm@1
|
1967 void file_run()
|
rlm@1
|
1968 {
|
rlm@39
|
1969 //printf("RLM: file_run\n");
|
rlm@39
|
1970 utilGetBaseName(szFile, filename);
|
rlm@1
|
1971 char *p = strrchr(filename, '.');
|
rlm@1
|
1972
|
rlm@1
|
1973 if(p)
|
rlm@1
|
1974 *p = 0;
|
rlm@1
|
1975
|
rlm@1
|
1976 if(ipsname[0] == 0)
|
rlm@1
|
1977 sprintf(ipsname, "%s.ips", filename);
|
rlm@1
|
1978
|
rlm@1
|
1979 bool failed = false;
|
rlm@1
|
1980
|
rlm@1
|
1981 IMAGE_TYPE type = utilFindType(szFile);
|
rlm@1
|
1982
|
rlm@1
|
1983 if(type == IMAGE_UNKNOWN) {
|
rlm@1
|
1984 systemMessage(0, "Unknown file type %s", szFile);
|
rlm@1
|
1985 exit(-1);
|
rlm@1
|
1986 }
|
rlm@1
|
1987 systemCartridgeType = (int)type;
|
rlm@1
|
1988
|
rlm@1
|
1989 if(type == IMAGE_GB) {
|
rlm@1
|
1990 failed = !gbLoadRom(szFile);
|
rlm@1
|
1991 if(!failed) {
|
rlm@1
|
1992 systemCartridgeType = 1;
|
rlm@39
|
1993 //printf("RLM: choosing GBSystem\n");
|
rlm@33
|
1994 theEmulator = GBSystem;
|
rlm@1
|
1995 if(sdlAutoIPS) {
|
rlm@1
|
1996 int size = gbRomSize;
|
rlm@1
|
1997 utilApplyIPS(ipsname, &gbRom, &size);
|
rlm@1
|
1998 if(size != gbRomSize) {
|
rlm@1
|
1999 extern bool gbUpdateSizes();
|
rlm@1
|
2000 gbUpdateSizes();
|
rlm@1
|
2001 gbReset();
|
rlm@1
|
2002 }
|
rlm@1
|
2003 }
|
rlm@1
|
2004 }
|
rlm@1
|
2005 } else if(type == IMAGE_GBA) {
|
rlm@1
|
2006 int size = CPULoadRom(szFile);
|
rlm@1
|
2007 failed = (size == 0);
|
rlm@1
|
2008 if(!failed) {
|
rlm@1
|
2009 // if(cpuEnhancedDetection && cpuSaveType == 0) {
|
rlm@1
|
2010 // utilGBAFindSave(rom, size);
|
rlm@1
|
2011 // }
|
rlm@33
|
2012
|
rlm@1
|
2013 sdlApplyPerImagePreferences();
|
rlm@1
|
2014
|
rlm@1
|
2015 systemCartridgeType = 0;
|
rlm@1
|
2016 theEmulator = GBASystem;
|
rlm@1
|
2017
|
rlm@1
|
2018 /* disabled due to problems
|
rlm@1
|
2019 if(removeIntros && rom != NULL) {
|
rlm@1
|
2020 WRITE32LE(&rom[0], 0xea00002e);
|
rlm@1
|
2021 }
|
rlm@1
|
2022 */
|
rlm@1
|
2023
|
rlm@1
|
2024 //CPUInit(biosFileName, useBios);
|
rlm@1
|
2025 CPUInit();
|
rlm@1
|
2026 CPUReset();
|
rlm@1
|
2027 if(sdlAutoIPS) {
|
rlm@1
|
2028 int size = 0x2000000;
|
rlm@1
|
2029 utilApplyIPS(ipsname, &rom, &size);
|
rlm@1
|
2030 if(size != 0x2000000) {
|
rlm@1
|
2031 CPUReset();
|
rlm@1
|
2032 }
|
rlm@1
|
2033 }
|
rlm@1
|
2034 }
|
rlm@1
|
2035 }
|
rlm@1
|
2036
|
rlm@1
|
2037 if(failed) {
|
rlm@1
|
2038 systemMessage(0, "Failed to load file %s", szFile);
|
rlm@1
|
2039 exit(-1);
|
rlm@1
|
2040 }
|
rlm@1
|
2041
|
rlm@1
|
2042 emulating = 1;
|
rlm@1
|
2043 renderedFrames = 0;
|
rlm@1
|
2044 }
|
rlm@1
|
2045
|
rlm@1
|
2046 int main(int argc, char **argv)
|
rlm@1
|
2047 {
|
rlm@30
|
2048 fprintf(stderr, "VisualBoyAdvance version %s [SDL]\n", PACKAGE_VERSION);
|
rlm@1
|
2049
|
rlm@1
|
2050 arg0 = argv[0];
|
rlm@1
|
2051
|
rlm@1
|
2052 captureDir[0] = 0;
|
rlm@1
|
2053 saveDir[0] = 0;
|
rlm@1
|
2054 batteryDir[0] = 0;
|
rlm@1
|
2055 ipsname[0] = 0;
|
rlm@1
|
2056
|
rlm@1
|
2057 int op = -1;
|
rlm@1
|
2058
|
rlm@1
|
2059 frameSkip = 2;
|
rlm@1
|
2060 gbBorderOn = 0;
|
rlm@1
|
2061
|
rlm@1
|
2062 parseDebug = true;
|
rlm@1
|
2063
|
rlm@1
|
2064 sdlReadPreferences();
|
rlm@1
|
2065
|
rlm@1
|
2066 sdlPrintUsage = 0;
|
rlm@1
|
2067
|
rlm@1
|
2068 while((op = getopt_long(argc,
|
rlm@1
|
2069 argv,
|
rlm@1
|
2070 "FNT:Y:G:D:b:c:df:hi:p::s:t:v:1234",
|
rlm@1
|
2071 sdlOptions,
|
rlm@1
|
2072 NULL)) != -1) {
|
rlm@1
|
2073 switch(op) {
|
rlm@1
|
2074 case 0:
|
rlm@1
|
2075 // long option already processed by getopt_long
|
rlm@1
|
2076 break;
|
rlm@1
|
2077 case 'b':
|
rlm@1
|
2078 useBios = true;
|
rlm@1
|
2079 if(optarg == NULL) {
|
rlm@1
|
2080 fprintf(stderr, "Missing BIOS file name\n");
|
rlm@1
|
2081 exit(-1);
|
rlm@1
|
2082 }
|
rlm@1
|
2083 strcpy(biosFileName, optarg);
|
rlm@1
|
2084 break;
|
rlm@1
|
2085 case 'c':
|
rlm@1
|
2086 {
|
rlm@1
|
2087 if(optarg == NULL) {
|
rlm@1
|
2088 fprintf(stderr, "Missing config file name\n");
|
rlm@1
|
2089 exit(-1);
|
rlm@1
|
2090 }
|
rlm@1
|
2091 FILE *f = fopen(optarg, "r");
|
rlm@1
|
2092 if(f == NULL) {
|
rlm@1
|
2093 fprintf(stderr, "File not found %s\n", optarg);
|
rlm@1
|
2094 exit(-1);
|
rlm@1
|
2095 }
|
rlm@1
|
2096 sdlReadPreferences(f);
|
rlm@1
|
2097 fclose(f);
|
rlm@1
|
2098 }
|
rlm@1
|
2099 break;
|
rlm@1
|
2100 case 'd':
|
rlm@1
|
2101 debugger = true;
|
rlm@1
|
2102 break;
|
rlm@1
|
2103 case 'h':
|
rlm@1
|
2104 sdlPrintUsage = 1;
|
rlm@1
|
2105 break;
|
rlm@1
|
2106 case 'i':
|
rlm@1
|
2107 if(optarg == NULL) {
|
rlm@1
|
2108 fprintf(stderr, "Missing IPS name\n");
|
rlm@1
|
2109 exit(-1);
|
rlm@1
|
2110 strcpy(ipsname, optarg);
|
rlm@1
|
2111 }
|
rlm@1
|
2112 break;
|
rlm@1
|
2113 case 'Y':
|
rlm@1
|
2114 yuv = true;
|
rlm@1
|
2115 if(optarg) {
|
rlm@1
|
2116 yuvType = atoi(optarg);
|
rlm@1
|
2117 switch(yuvType) {
|
rlm@1
|
2118 case 0:
|
rlm@1
|
2119 yuvType = SDL_YV12_OVERLAY;
|
rlm@1
|
2120 break;
|
rlm@1
|
2121 case 1:
|
rlm@1
|
2122 yuvType = SDL_UYVY_OVERLAY;
|
rlm@1
|
2123 break;
|
rlm@1
|
2124 case 2:
|
rlm@1
|
2125 yuvType = SDL_YVYU_OVERLAY;
|
rlm@1
|
2126 break;
|
rlm@1
|
2127 case 3:
|
rlm@1
|
2128 yuvType = SDL_YUY2_OVERLAY;
|
rlm@1
|
2129 break;
|
rlm@1
|
2130 case 4:
|
rlm@1
|
2131 yuvType = SDL_IYUV_OVERLAY;
|
rlm@1
|
2132 break;
|
rlm@1
|
2133 default:
|
rlm@1
|
2134 yuvType = SDL_YV12_OVERLAY;
|
rlm@1
|
2135 }
|
rlm@1
|
2136 } else
|
rlm@1
|
2137 yuvType = SDL_YV12_OVERLAY;
|
rlm@1
|
2138 break;
|
rlm@1
|
2139 case 'G':
|
rlm@1
|
2140 dbgMain = remoteStubMain;
|
rlm@1
|
2141 dbgSignal = remoteStubSignal;
|
rlm@1
|
2142 dbgOutput = remoteOutput;
|
rlm@1
|
2143 debugger = true;
|
rlm@1
|
2144 debuggerStub = true;
|
rlm@1
|
2145 if(optarg) {
|
rlm@1
|
2146 char *s = optarg;
|
rlm@1
|
2147 if(strncmp(s,"tcp:", 4) == 0) {
|
rlm@1
|
2148 s+=4;
|
rlm@1
|
2149 int port = atoi(s);
|
rlm@1
|
2150 remoteSetProtocol(0);
|
rlm@1
|
2151 remoteSetPort(port);
|
rlm@1
|
2152 } else if(strcmp(s,"tcp") == 0) {
|
rlm@1
|
2153 remoteSetProtocol(0);
|
rlm@1
|
2154 } else if(strcmp(s, "pipe") == 0) {
|
rlm@1
|
2155 remoteSetProtocol(1);
|
rlm@1
|
2156 } else {
|
rlm@1
|
2157 fprintf(stderr, "Unknown protocol %s\n", s);
|
rlm@1
|
2158 exit(-1);
|
rlm@1
|
2159 }
|
rlm@1
|
2160 } else {
|
rlm@1
|
2161 remoteSetProtocol(0);
|
rlm@1
|
2162 }
|
rlm@1
|
2163 break;
|
rlm@1
|
2164 case 'N':
|
rlm@1
|
2165 parseDebug = false;
|
rlm@1
|
2166 break;
|
rlm@1
|
2167 case 'D':
|
rlm@1
|
2168 if(optarg) {
|
rlm@1
|
2169 systemDebug = atoi(optarg);
|
rlm@1
|
2170 } else {
|
rlm@1
|
2171 systemDebug = 1;
|
rlm@1
|
2172 }
|
rlm@1
|
2173 break;
|
rlm@1
|
2174 case 'F':
|
rlm@1
|
2175 fullscreen = 1;
|
rlm@1
|
2176 mouseCounter = 120;
|
rlm@1
|
2177 break;
|
rlm@1
|
2178 case 'f':
|
rlm@1
|
2179 if(optarg) {
|
rlm@1
|
2180 filter = atoi(optarg);
|
rlm@1
|
2181 } else {
|
rlm@1
|
2182 filter = 0;
|
rlm@1
|
2183 }
|
rlm@1
|
2184 break;
|
rlm@1
|
2185
|
rlm@1
|
2186 case 'r':
|
rlm@1
|
2187 if(optarg == NULL) {
|
rlm@33
|
2188 fprintf(stderr, "ERROR: --recordmovie ('r') needs movie filename as option\n");
|
rlm@1
|
2189 exit(-1);
|
rlm@1
|
2190 }
|
rlm@1
|
2191 strcpy(movieFileName, optarg);
|
rlm@1
|
2192 useMovie = 1;
|
rlm@1
|
2193 break;
|
rlm@1
|
2194 case 'p': // play without read-only (editable)
|
rlm@1
|
2195 fprintf (stderr, "-p got called!\n");
|
rlm@1
|
2196 if(optarg == NULL) {
|
rlm@33
|
2197 fprintf(stderr, "ERROR: --playmovie ('p') needs movie filename as option\n");
|
rlm@1
|
2198 exit(-1);
|
rlm@1
|
2199 }
|
rlm@1
|
2200 strcpy(movieFileName, optarg);
|
rlm@1
|
2201 useMovie = 2;
|
rlm@1
|
2202 break;
|
rlm@1
|
2203 case 'w': // play with read-only
|
rlm@1
|
2204 fprintf (stderr, "-w got called!\n");
|
rlm@1
|
2205 if(optarg == NULL) {
|
rlm@33
|
2206 fprintf(stderr, "ERROR: --watchmovie ('w') needs movie filename as option\n");
|
rlm@1
|
2207 exit(-1);
|
rlm@1
|
2208 }
|
rlm@1
|
2209 strcpy(movieFileName, optarg);
|
rlm@1
|
2210 useMovie = 3;
|
rlm@1
|
2211 break;
|
rlm@1
|
2212
|
rlm@1
|
2213 case 'P':
|
rlm@1
|
2214 #ifdef PROFILING
|
rlm@1
|
2215 if(optarg) {
|
rlm@1
|
2216 cpuEnableProfiling(atoi(optarg));
|
rlm@1
|
2217 } else
|
rlm@1
|
2218 cpuEnableProfiling(100);
|
rlm@1
|
2219 #endif
|
rlm@1
|
2220 break;
|
rlm@1
|
2221 case 'S':
|
rlm@1
|
2222 sdlFlashSize = atoi(optarg);
|
rlm@1
|
2223 if(sdlFlashSize < 0 || sdlFlashSize > 1)
|
rlm@1
|
2224 sdlFlashSize = 0;
|
rlm@1
|
2225 break;
|
rlm@1
|
2226 case 's':
|
rlm@1
|
2227 if(optarg) {
|
rlm@1
|
2228 int a = atoi(optarg);
|
rlm@1
|
2229 if(a >= 0 && a <= 9) {
|
rlm@1
|
2230 gbFrameSkip = a;
|
rlm@1
|
2231 frameSkip = a;
|
rlm@1
|
2232 }
|
rlm@1
|
2233 } else {
|
rlm@1
|
2234 frameSkip = 2;
|
rlm@1
|
2235 gbFrameSkip = 0;
|
rlm@1
|
2236 }
|
rlm@1
|
2237 break;
|
rlm@1
|
2238 case 't':
|
rlm@1
|
2239 if(optarg) {
|
rlm@1
|
2240 int a = atoi(optarg);
|
rlm@1
|
2241 if(a < 0 || a > 5)
|
rlm@1
|
2242 a = 0;
|
rlm@1
|
2243 cpuSaveType = a;
|
rlm@1
|
2244 }
|
rlm@1
|
2245 break;
|
rlm@1
|
2246 case 'T':
|
rlm@1
|
2247 if(optarg) {
|
rlm@1
|
2248 int t = atoi(optarg);
|
rlm@1
|
2249 throttle = t;
|
rlm@1
|
2250 }
|
rlm@1
|
2251 break;
|
rlm@1
|
2252 case 'v':
|
rlm@1
|
2253 if(optarg) {
|
rlm@1
|
2254 systemVerbose = atoi(optarg);
|
rlm@1
|
2255 } else
|
rlm@1
|
2256 systemVerbose = 0;
|
rlm@1
|
2257 break;
|
rlm@1
|
2258 case '1':
|
rlm@1
|
2259 sizeOption = 0;
|
rlm@1
|
2260 break;
|
rlm@1
|
2261 case '2':
|
rlm@1
|
2262 sizeOption = 1;
|
rlm@1
|
2263 break;
|
rlm@1
|
2264 case '3':
|
rlm@1
|
2265 sizeOption = 2;
|
rlm@1
|
2266 break;
|
rlm@1
|
2267 case '4':
|
rlm@1
|
2268 sizeOption = 3;
|
rlm@1
|
2269 break;
|
rlm@1
|
2270 case '?':
|
rlm@1
|
2271 sdlPrintUsage = 1;
|
rlm@1
|
2272 break;
|
rlm@1
|
2273 }
|
rlm@1
|
2274 }
|
rlm@1
|
2275
|
rlm@39
|
2276 //printf("RLM: derpy loves you!\n");
|
rlm@39
|
2277 //printf("RLM: useMovie: %d (1 is record)\n", useMovie);
|
rlm@1
|
2278 if(sdlPrintUsage) {
|
rlm@1
|
2279 usage(argv[0]);
|
rlm@1
|
2280 exit(-1);
|
rlm@1
|
2281 }
|
rlm@1
|
2282
|
rlm@1
|
2283 #ifdef MMX
|
rlm@1
|
2284 if(disableMMX)
|
rlm@1
|
2285 cpu_mmx = 0;
|
rlm@1
|
2286 #endif
|
rlm@1
|
2287
|
rlm@1
|
2288 if(rewindTimer)
|
rlm@1
|
2289 rewindMemory = (char *)malloc(8*REWIND_SIZE);
|
rlm@1
|
2290
|
rlm@1
|
2291 if(sdlFlashSize == 0)
|
rlm@1
|
2292 flashSetSize(0x10000);
|
rlm@1
|
2293 else
|
rlm@1
|
2294 flashSetSize(0x20000);
|
rlm@1
|
2295
|
rlm@1
|
2296 rtcEnable(sdlRtcEnable ? true : false);
|
rlm@1
|
2297 agbPrintEnable(sdlAgbPrint ? true : false);
|
rlm@1
|
2298
|
rlm@1
|
2299 if(!debuggerStub) {
|
rlm@1
|
2300 if(optind >= argc) {
|
rlm@1
|
2301 systemMessage(0,"Missing image name");
|
rlm@1
|
2302 usage(argv[0]);
|
rlm@1
|
2303 exit(-1);
|
rlm@1
|
2304 }
|
rlm@1
|
2305 }
|
rlm@1
|
2306
|
rlm@1
|
2307 if(filter) {
|
rlm@1
|
2308 sizeOption = 1;
|
rlm@1
|
2309 }
|
rlm@1
|
2310
|
rlm@1
|
2311 for(int i = 0; i < 24;) {
|
rlm@1
|
2312 systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10);
|
rlm@1
|
2313 systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10);
|
rlm@1
|
2314 systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10);
|
rlm@1
|
2315 systemGbPalette[i++] = 0;
|
rlm@1
|
2316 }
|
rlm@1
|
2317
|
rlm@1
|
2318 systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
rlm@1
|
2319
|
rlm@1
|
2320 if(optind < argc)
|
rlm@1
|
2321 {
|
rlm@1
|
2322 szFile = argv[optind];
|
rlm@1
|
2323 file_run();
|
rlm@39
|
2324 //printf("RLM: file_run() done\n");
|
rlm@1
|
2325 }
|
rlm@1
|
2326 else
|
rlm@1
|
2327 {
|
rlm@1
|
2328 systemCartridgeType = 0;
|
rlm@1
|
2329 strcpy(filename, "gnu_stub");
|
rlm@1
|
2330 rom = (u8 *)malloc(0x2000000);
|
rlm@1
|
2331 workRAM = (u8 *)calloc(1, 0x40000);
|
rlm@1
|
2332 bios = (u8 *)calloc(1,0x4000);
|
rlm@1
|
2333 internalRAM = (u8 *)calloc(1,0x8000);
|
rlm@1
|
2334 paletteRAM = (u8 *)calloc(1,0x400);
|
rlm@1
|
2335 vram = (u8 *)calloc(1, 0x20000);
|
rlm@1
|
2336 oam = (u8 *)calloc(1, 0x400);
|
rlm@1
|
2337 pix = (u8 *)calloc(1, 4 * 240 * 160);
|
rlm@1
|
2338 ioMem = (u8 *)calloc(1, 0x400);
|
rlm@1
|
2339
|
rlm@1
|
2340 theEmulator = GBASystem;
|
rlm@1
|
2341
|
rlm@1
|
2342 //CPUInit(biosFileName, useBios);
|
rlm@1
|
2343 CPUInit();
|
rlm@33
|
2344 CPUReset();
|
rlm@1
|
2345 }
|
rlm@1
|
2346
|
rlm@1
|
2347 if(debuggerStub)
|
rlm@1
|
2348 remoteInit();
|
rlm@1
|
2349
|
rlm@1
|
2350 int flags = SDL_INIT_VIDEO|SDL_INIT_AUDIO|
|
rlm@1
|
2351 SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE;
|
rlm@1
|
2352
|
rlm@1
|
2353 if(soundOffFlag)
|
rlm@1
|
2354 flags ^= SDL_INIT_AUDIO;
|
rlm@1
|
2355
|
rlm@1
|
2356 if(SDL_Init(flags)) {
|
rlm@1
|
2357 systemMessage(0, "Failed to init SDL: %s", SDL_GetError());
|
rlm@1
|
2358 exit(-1);
|
rlm@1
|
2359 }
|
rlm@1
|
2360
|
rlm@1
|
2361 if(SDL_InitSubSystem(SDL_INIT_JOYSTICK)) {
|
rlm@1
|
2362 systemMessage(0, "Failed to init joystick support: %s", SDL_GetError());
|
rlm@1
|
2363 }
|
rlm@1
|
2364
|
rlm@1
|
2365 sdlCheckKeys();
|
rlm@1
|
2366
|
rlm@1
|
2367 if(systemCartridgeType == 0) {
|
rlm@1
|
2368 srcWidth = 240;
|
rlm@1
|
2369 srcHeight = 160;
|
rlm@1
|
2370 systemFrameSkip = frameSkip;
|
rlm@1
|
2371 } else if (systemCartridgeType == 1) {
|
rlm@1
|
2372 if(gbBorderOn) {
|
rlm@1
|
2373 srcWidth = 256;
|
rlm@1
|
2374 srcHeight = 224;
|
rlm@1
|
2375 gbBorderLineSkip = 256;
|
rlm@1
|
2376 gbBorderColumnSkip = 48;
|
rlm@1
|
2377 gbBorderRowSkip = 40;
|
rlm@1
|
2378 } else {
|
rlm@1
|
2379 srcWidth = 160;
|
rlm@1
|
2380 srcHeight = 144;
|
rlm@1
|
2381 gbBorderLineSkip = 160;
|
rlm@1
|
2382 gbBorderColumnSkip = 0;
|
rlm@1
|
2383 gbBorderRowSkip = 0;
|
rlm@1
|
2384 }
|
rlm@1
|
2385 systemFrameSkip = gbFrameSkip;
|
rlm@1
|
2386 } else {
|
rlm@1
|
2387 srcWidth = 320;
|
rlm@1
|
2388 srcHeight = 240;
|
rlm@1
|
2389 }
|
rlm@1
|
2390
|
rlm@1
|
2391 destWidth = (sizeOption+1)*srcWidth;
|
rlm@1
|
2392 destHeight = (sizeOption+1)*srcHeight;
|
rlm@1
|
2393
|
rlm@1
|
2394 surface = SDL_SetVideoMode(destWidth, destHeight, 16,
|
rlm@1
|
2395 SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF|
|
rlm@1
|
2396 (fullscreen ? SDL_FULLSCREEN : 0));
|
rlm@1
|
2397
|
rlm@1
|
2398 if(surface == NULL) {
|
rlm@1
|
2399 systemMessage(0, "Failed to set video mode");
|
rlm@1
|
2400 SDL_Quit();
|
rlm@1
|
2401 exit(-1);
|
rlm@1
|
2402 }
|
rlm@1
|
2403
|
rlm@1
|
2404 systemRedShift = sdlCalculateShift(surface->format->Rmask);
|
rlm@1
|
2405 systemGreenShift = sdlCalculateShift(surface->format->Gmask);
|
rlm@1
|
2406 systemBlueShift = sdlCalculateShift(surface->format->Bmask);
|
rlm@1
|
2407
|
rlm@1
|
2408 systemColorDepth = surface->format->BitsPerPixel;
|
rlm@1
|
2409 if(systemColorDepth == 15)
|
rlm@1
|
2410 systemColorDepth = 16;
|
rlm@1
|
2411
|
rlm@1
|
2412 if(yuv) {
|
rlm@1
|
2413 Init_Overlay(surface, yuvType);
|
rlm@1
|
2414 systemColorDepth = 32;
|
rlm@1
|
2415 systemRedShift = 3;
|
rlm@1
|
2416 systemGreenShift = 11;
|
rlm@1
|
2417 systemBlueShift = 19;
|
rlm@1
|
2418 }
|
rlm@1
|
2419
|
rlm@1
|
2420 if(systemColorDepth != 16 && systemColorDepth != 24 &&
|
rlm@1
|
2421 systemColorDepth != 32) {
|
rlm@1
|
2422 fprintf(stderr,"Unsupported color depth '%d'.\nOnly 16, 24 and 32 bit color depths are supported\n", systemColorDepth);
|
rlm@1
|
2423 exit(-1);
|
rlm@1
|
2424 }
|
rlm@1
|
2425
|
rlm@1
|
2426 #ifndef C_CORE
|
rlm@1
|
2427 sdlMakeStretcher(srcWidth);
|
rlm@1
|
2428 #else
|
rlm@1
|
2429 switch(systemColorDepth) {
|
rlm@1
|
2430 case 16:
|
rlm@1
|
2431 sdlStretcher = sdlStretcher16[sizeOption];
|
rlm@1
|
2432 break;
|
rlm@1
|
2433 case 24:
|
rlm@1
|
2434 sdlStretcher = sdlStretcher24[sizeOption];
|
rlm@1
|
2435 break;
|
rlm@1
|
2436 case 32:
|
rlm@1
|
2437 sdlStretcher = sdlStretcher32[sizeOption];
|
rlm@1
|
2438 break;
|
rlm@1
|
2439 default:
|
rlm@1
|
2440 fprintf(stderr, "Unsupported resolution: %d\n", systemColorDepth);
|
rlm@1
|
2441 exit(-1);
|
rlm@1
|
2442 }
|
rlm@1
|
2443 #endif
|
rlm@1
|
2444
|
rlm@1
|
2445 fprintf(stderr,"Color depth: %d\n", systemColorDepth);
|
rlm@1
|
2446
|
rlm@1
|
2447 if(systemColorDepth == 16) {
|
rlm@1
|
2448 if(sdlCalculateMaskWidth(surface->format->Gmask) == 6) {
|
rlm@1
|
2449 Init_2xSaI(565);
|
rlm@1
|
2450 RGB_LOW_BITS_MASK = 0x821;
|
rlm@1
|
2451 } else {
|
rlm@1
|
2452 Init_2xSaI(555);
|
rlm@1
|
2453 RGB_LOW_BITS_MASK = 0x421;
|
rlm@1
|
2454 }
|
rlm@1
|
2455 if(systemCartridgeType == 2) {
|
rlm@1
|
2456 for(int i = 0; i < 0x10000; i++) {
|
rlm@1
|
2457 systemColorMap16[i] = (((i >> 1) & 0x1f) << systemBlueShift) |
|
rlm@1
|
2458 (((i & 0x7c0) >> 6) << systemGreenShift) |
|
rlm@1
|
2459 (((i & 0xf800) >> 11) << systemRedShift);
|
rlm@1
|
2460 }
|
rlm@1
|
2461 } else {
|
rlm@1
|
2462 for(int i = 0; i < 0x10000; i++) {
|
rlm@1
|
2463 systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
|
rlm@1
|
2464 (((i & 0x3e0) >> 5) << systemGreenShift) |
|
rlm@1
|
2465 (((i & 0x7c00) >> 10) << systemBlueShift);
|
rlm@1
|
2466 }
|
rlm@1
|
2467 }
|
rlm@1
|
2468 srcPitch = srcWidth * 2+4;
|
rlm@1
|
2469 } else {
|
rlm@1
|
2470 if(systemColorDepth != 32)
|
rlm@1
|
2471 filterFunction = NULL;
|
rlm@1
|
2472 RGB_LOW_BITS_MASK = 0x010101;
|
rlm@1
|
2473 if(systemColorDepth == 32) {
|
rlm@1
|
2474 Init_2xSaI(32);
|
rlm@1
|
2475 }
|
rlm@1
|
2476 for(int i = 0; i < 0x10000; i++) {
|
rlm@1
|
2477 systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
|
rlm@1
|
2478 (((i & 0x3e0) >> 5) << systemGreenShift) |
|
rlm@1
|
2479 (((i & 0x7c00) >> 10) << systemBlueShift);
|
rlm@1
|
2480 }
|
rlm@1
|
2481 if(systemColorDepth == 32)
|
rlm@1
|
2482 srcPitch = srcWidth*4 + 4;
|
rlm@1
|
2483 else
|
rlm@1
|
2484 srcPitch = srcWidth*3;
|
rlm@1
|
2485 }
|
rlm@1
|
2486
|
rlm@1
|
2487 if(systemColorDepth != 32) {
|
rlm@1
|
2488 switch(filter) {
|
rlm@1
|
2489 case 0:
|
rlm@1
|
2490 filterFunction = NULL;
|
rlm@1
|
2491 break;
|
rlm@1
|
2492 case 1:
|
rlm@1
|
2493 filterFunction = ScanlinesTV;
|
rlm@1
|
2494 break;
|
rlm@1
|
2495 case 2:
|
rlm@1
|
2496 filterFunction = _2xSaI;
|
rlm@1
|
2497 break;
|
rlm@1
|
2498 case 3:
|
rlm@1
|
2499 filterFunction = Super2xSaI;
|
rlm@1
|
2500 break;
|
rlm@1
|
2501 case 4:
|
rlm@1
|
2502 filterFunction = SuperEagle;
|
rlm@1
|
2503 break;
|
rlm@1
|
2504 case 5:
|
rlm@1
|
2505 filterFunction = Pixelate2x16;
|
rlm@1
|
2506 break;
|
rlm@1
|
2507 case 6:
|
rlm@1
|
2508 filterFunction = MotionBlur;
|
rlm@1
|
2509 break;
|
rlm@1
|
2510 case 7:
|
rlm@1
|
2511 filterFunction = AdMame2x;
|
rlm@1
|
2512 break;
|
rlm@1
|
2513 case 8:
|
rlm@1
|
2514 filterFunction = Simple2x16;
|
rlm@1
|
2515 break;
|
rlm@1
|
2516 case 9:
|
rlm@1
|
2517 filterFunction = Bilinear;
|
rlm@1
|
2518 break;
|
rlm@1
|
2519 case 10:
|
rlm@1
|
2520 filterFunction = BilinearPlus;
|
rlm@1
|
2521 break;
|
rlm@1
|
2522 case 11:
|
rlm@1
|
2523 filterFunction = Scanlines;
|
rlm@1
|
2524 break;
|
rlm@1
|
2525 case 12:
|
rlm@1
|
2526 filterFunction = hq2x;
|
rlm@1
|
2527 break;
|
rlm@1
|
2528 case 13:
|
rlm@1
|
2529 filterFunction = lq2x;
|
rlm@1
|
2530 break;
|
rlm@1
|
2531 default:
|
rlm@1
|
2532 filterFunction = NULL;
|
rlm@1
|
2533 break;
|
rlm@1
|
2534 }
|
rlm@1
|
2535 } else {
|
rlm@1
|
2536 switch(filter) {
|
rlm@1
|
2537 case 0:
|
rlm@1
|
2538 filterFunction = NULL;
|
rlm@1
|
2539 break;
|
rlm@1
|
2540 case 1:
|
rlm@1
|
2541 filterFunction = ScanlinesTV32;
|
rlm@1
|
2542 break;
|
rlm@1
|
2543 case 2:
|
rlm@1
|
2544 filterFunction = _2xSaI32;
|
rlm@1
|
2545 break;
|
rlm@1
|
2546 case 3:
|
rlm@1
|
2547 filterFunction = Super2xSaI32;
|
rlm@1
|
2548 break;
|
rlm@1
|
2549 case 4:
|
rlm@1
|
2550 filterFunction = SuperEagle32;
|
rlm@1
|
2551 break;
|
rlm@1
|
2552 case 5:
|
rlm@1
|
2553 filterFunction = Pixelate2x32;
|
rlm@1
|
2554 break;
|
rlm@1
|
2555 case 6:
|
rlm@1
|
2556 filterFunction = MotionBlur32;
|
rlm@1
|
2557 break;
|
rlm@1
|
2558 case 7:
|
rlm@1
|
2559 filterFunction = AdMame2x32;
|
rlm@1
|
2560 break;
|
rlm@1
|
2561 case 8:
|
rlm@1
|
2562 filterFunction = Simple2x32;
|
rlm@1
|
2563 break;
|
rlm@1
|
2564 case 9:
|
rlm@1
|
2565 filterFunction = Bilinear32;
|
rlm@1
|
2566 break;
|
rlm@1
|
2567 case 10:
|
rlm@1
|
2568 filterFunction = BilinearPlus32;
|
rlm@1
|
2569 break;
|
rlm@1
|
2570 case 11:
|
rlm@1
|
2571 filterFunction = Scanlines32;
|
rlm@1
|
2572 break;
|
rlm@1
|
2573 case 12:
|
rlm@1
|
2574 filterFunction = hq2x32;
|
rlm@1
|
2575 break;
|
rlm@1
|
2576 case 13:
|
rlm@1
|
2577 filterFunction = lq2x32;
|
rlm@1
|
2578 break;
|
rlm@1
|
2579 default:
|
rlm@1
|
2580 filterFunction = NULL;
|
rlm@1
|
2581 break;
|
rlm@1
|
2582 }
|
rlm@1
|
2583 }
|
rlm@1
|
2584
|
rlm@1
|
2585 if(systemColorDepth == 16) {
|
rlm@1
|
2586 switch(ifbType) {
|
rlm@1
|
2587 case 0:
|
rlm@1
|
2588 default:
|
rlm@1
|
2589 ifbFunction = NULL;
|
rlm@1
|
2590 break;
|
rlm@1
|
2591 case 1:
|
rlm@1
|
2592 ifbFunction = MotionBlurIB;
|
rlm@1
|
2593 break;
|
rlm@1
|
2594 case 2:
|
rlm@1
|
2595 ifbFunction = SmartIB;
|
rlm@1
|
2596 break;
|
rlm@1
|
2597 }
|
rlm@1
|
2598 } else if(systemColorDepth == 32) {
|
rlm@1
|
2599 switch(ifbType) {
|
rlm@1
|
2600 case 0:
|
rlm@1
|
2601 default:
|
rlm@1
|
2602 ifbFunction = NULL;
|
rlm@1
|
2603 break;
|
rlm@1
|
2604 case 1:
|
rlm@1
|
2605 ifbFunction = MotionBlurIB32;
|
rlm@1
|
2606 break;
|
rlm@1
|
2607 case 2:
|
rlm@1
|
2608 ifbFunction = SmartIB32;
|
rlm@1
|
2609 break;
|
rlm@1
|
2610 }
|
rlm@1
|
2611 } else
|
rlm@1
|
2612 ifbFunction = NULL;
|
rlm@1
|
2613
|
rlm@1
|
2614 if(delta == NULL) {
|
rlm@1
|
2615 delta = (u8*)malloc(322*242*4);
|
rlm@1
|
2616 memset(delta, 255, 322*242*4);
|
rlm@1
|
2617 }
|
rlm@1
|
2618
|
rlm@1
|
2619 if(!soundOffFlag)
|
rlm@1
|
2620 soundInit();
|
rlm@1
|
2621
|
rlm@1
|
2622 autoFrameSkipLastTime = throttleLastTime = systemGetClock();
|
rlm@39
|
2623 //printf("RLM: and now for the movie part!\n");
|
rlm@1
|
2624
|
rlm@1
|
2625 switch(useMovie)
|
rlm@1
|
2626 {
|
rlm@1
|
2627 case 1: // --recordMovie
|
rlm@1
|
2628 VBAMovieCreate(movieFileName,
|
rlm@1
|
2629 /*authorInfo*/"",
|
rlm@1
|
2630 /*startFlags*/0,
|
rlm@1
|
2631 /*controllerFlags*/MOVIE_CONTROLLER(0),
|
rlm@1
|
2632 /*typeFlags*/(systemCartridgeType==IMAGE_GBA)?(MOVIE_TYPE_GBA):(GBC_CAPABLE?MOVIE_TYPE_GBC:MOVIE_TYPE_SGB));
|
rlm@1
|
2633 break;
|
rlm@1
|
2634 case 2: // --playMovie
|
rlm@1
|
2635 VBAMovieOpen(movieFileName, false);
|
rlm@1
|
2636 break;
|
rlm@1
|
2637 case 3: // --watchMovie
|
rlm@1
|
2638 VBAMovieOpen(movieFileName, true);
|
rlm@1
|
2639 break;
|
rlm@1
|
2640 default:
|
rlm@1
|
2641 sdlReadBattery();
|
rlm@1
|
2642 break;
|
rlm@1
|
2643 }
|
rlm@39
|
2644 //printf("RLM: still alive after movie switch\n");
|
rlm@1
|
2645 SDL_WM_SetCaption("VisualBoyAdvance", NULL);
|
rlm@1
|
2646
|
rlm@1
|
2647 char *moviefile = getenv("AUTODEMO");
|
rlm@33
|
2648 fprintf (stderr, "Checking for AUTODEMO...\n");
|
rlm@1
|
2649 if (moviefile)
|
rlm@1
|
2650 {
|
rlm@33
|
2651 fprintf (stderr, "I got a filename OMG!\nCalling VBAMovieOpen...\n");
|
rlm@1
|
2652 VBAMovieOpen(moviefile, true);
|
rlm@1
|
2653 }
|
rlm@1
|
2654
|
rlm@1
|
2655 while(emulating) {
|
rlm@1
|
2656 if(!paused && active) {
|
rlm@1
|
2657 if(debugger && theEmulator.emuHasDebugger)
|
rlm@1
|
2658 dbgMain();
|
rlm@1
|
2659 else {
|
rlm@39
|
2660 //printf("RLM: emulator main\n");
|
rlm@33
|
2661 theEmulator.emuMain(theEmulator.emuCount);
|
rlm@39
|
2662 //printf("RLM: emulator main called\n");
|
rlm@1
|
2663 if(rewindSaveNeeded && rewindMemory && theEmulator.emuWriteMemState) {
|
rlm@1
|
2664 rewindCount++;
|
rlm@1
|
2665 if(rewindCount > 8)
|
rlm@1
|
2666 rewindCount = 8;
|
rlm@1
|
2667 if(theEmulator.emuWriteMemState &&
|
rlm@1
|
2668 theEmulator.emuWriteMemState(&rewindMemory[rewindPos*REWIND_SIZE],
|
rlm@1
|
2669 REWIND_SIZE)) {
|
rlm@1
|
2670 rewindPos = ++rewindPos & 7;
|
rlm@1
|
2671 if(rewindCount == 8)
|
rlm@1
|
2672 rewindTopPos = ++rewindTopPos & 7;
|
rlm@1
|
2673 }
|
rlm@1
|
2674 }
|
rlm@1
|
2675
|
rlm@1
|
2676 rewindSaveNeeded = false;
|
rlm@1
|
2677 }
|
rlm@1
|
2678 } else {
|
rlm@1
|
2679 SDL_Delay(500);
|
rlm@1
|
2680 }
|
rlm@1
|
2681 sdlPollEvents();
|
rlm@1
|
2682 if(mouseCounter) {
|
rlm@1
|
2683 mouseCounter--;
|
rlm@1
|
2684 if(mouseCounter == 0)
|
rlm@1
|
2685 SDL_ShowCursor(SDL_DISABLE);
|
rlm@1
|
2686 }
|
rlm@1
|
2687 }
|
rlm@1
|
2688
|
rlm@1
|
2689 emulating = 0;
|
rlm@1
|
2690 fprintf(stderr,"Shutting down\n");
|
rlm@1
|
2691 remoteCleanUp();
|
rlm@1
|
2692 soundShutdown();
|
rlm@1
|
2693
|
rlm@1
|
2694 if(gbRom != NULL || rom != NULL) {
|
rlm@1
|
2695 sdlWriteBattery();
|
rlm@1
|
2696 theEmulator.emuCleanUp();
|
rlm@1
|
2697 }
|
rlm@1
|
2698
|
rlm@1
|
2699 if(delta) {
|
rlm@1
|
2700 free(delta);
|
rlm@1
|
2701 delta = NULL;
|
rlm@1
|
2702 }
|
rlm@1
|
2703
|
rlm@1
|
2704 SDL_Quit();
|
rlm@1
|
2705 return 0;
|
rlm@1
|
2706 }
|
rlm@1
|
2707
|
rlm@1
|
2708 void systemMessage(int num, const char *msg, ...)
|
rlm@1
|
2709 {
|
rlm@1
|
2710 char buffer[2048];
|
rlm@1
|
2711 va_list valist;
|
rlm@1
|
2712
|
rlm@1
|
2713 va_start(valist, msg);
|
rlm@1
|
2714 vsprintf(buffer, msg, valist);
|
rlm@1
|
2715
|
rlm@1
|
2716 fprintf(stderr, "%s\n", buffer);
|
rlm@1
|
2717 va_end(valist);
|
rlm@1
|
2718 }
|
rlm@1
|
2719
|
rlm@1
|
2720 //On WIN32, this function messages requesting
|
rlm@1
|
2721 //the window to be redrawn. Can this be ignored here?
|
rlm@1
|
2722 void systemRefreshScreen(){}
|
rlm@1
|
2723
|
rlm@1
|
2724 void systemRenderFrame()
|
rlm@1
|
2725 {
|
rlm@1
|
2726 renderedFrames++;
|
rlm@1
|
2727 VBAUpdateFrameCountDisplay();
|
rlm@1
|
2728 VBAUpdateButtonPressDisplay();
|
rlm@1
|
2729
|
rlm@1
|
2730 if(yuv) {
|
rlm@1
|
2731 Draw_Overlay(surface, sizeOption+1);
|
rlm@1
|
2732 return;
|
rlm@1
|
2733 }
|
rlm@1
|
2734
|
rlm@1
|
2735 SDL_LockSurface(surface);
|
rlm@1
|
2736
|
rlm@1
|
2737 for(int slot = 0 ; slot < 8 ; slot++)
|
rlm@1
|
2738 {
|
rlm@1
|
2739 if(screenMessage[slot]) {
|
rlm@1
|
2740 if(systemCartridgeType == 1 && gbBorderOn) {
|
rlm@1
|
2741 gbSgbRenderBorder();
|
rlm@1
|
2742 }
|
rlm@1
|
2743 if(((systemGetClock() - screenMessageTime[slot]) < screenMessageDuration[slot]) &&
|
rlm@1
|
2744 !disableStatusMessages) {
|
rlm@1
|
2745 drawText(pix, srcPitch, 10, srcHeight - 20*(slot+1),
|
rlm@1
|
2746 screenMessageBuffer[slot]);
|
rlm@1
|
2747 } else {
|
rlm@1
|
2748 screenMessage[slot] = false;
|
rlm@1
|
2749 }
|
rlm@1
|
2750 }
|
rlm@1
|
2751 }
|
rlm@1
|
2752
|
rlm@1
|
2753 if(ifbFunction) {
|
rlm@1
|
2754 if(systemColorDepth == 16)
|
rlm@1
|
2755 ifbFunction(pix+destWidth+4, destWidth+4, srcWidth, srcHeight);
|
rlm@1
|
2756 else
|
rlm@1
|
2757 ifbFunction(pix+destWidth*2+4, destWidth*2+4, srcWidth, srcHeight);
|
rlm@1
|
2758 }
|
rlm@1
|
2759
|
rlm@1
|
2760 if(filterFunction) {
|
rlm@1
|
2761 if(systemColorDepth == 16)
|
rlm@1
|
2762 filterFunction(pix+destWidth+4,destWidth+4, delta,
|
rlm@1
|
2763 (u8*)surface->pixels,surface->pitch,
|
rlm@1
|
2764 srcWidth,
|
rlm@1
|
2765 srcHeight);
|
rlm@1
|
2766 else
|
rlm@1
|
2767 filterFunction(pix+destWidth*2+4,
|
rlm@1
|
2768 destWidth*2+4,
|
rlm@1
|
2769 delta,
|
rlm@1
|
2770 (u8*)surface->pixels,
|
rlm@1
|
2771 surface->pitch,
|
rlm@1
|
2772 srcWidth,
|
rlm@1
|
2773 srcHeight);
|
rlm@1
|
2774 } else {
|
rlm@1
|
2775 int destPitch = surface->pitch;
|
rlm@1
|
2776 u8 *src = pix;
|
rlm@1
|
2777 u8 *dest = (u8*)surface->pixels;
|
rlm@1
|
2778 int i;
|
rlm@1
|
2779 u32 *stretcher = (u32 *)sdlStretcher;
|
rlm@1
|
2780 if(systemColorDepth == 16)
|
rlm@1
|
2781 src += srcPitch;
|
rlm@1
|
2782 int option = sizeOption;
|
rlm@1
|
2783 if(yuv)
|
rlm@1
|
2784 option = 0;
|
rlm@1
|
2785 switch(sizeOption) {
|
rlm@1
|
2786 case 0:
|
rlm@1
|
2787 for(i = 0; i < srcHeight; i++) {
|
rlm@1
|
2788 SDL_CALL_STRETCHER;
|
rlm@1
|
2789 src += srcPitch;
|
rlm@1
|
2790 dest += destPitch;
|
rlm@1
|
2791 }
|
rlm@1
|
2792 break;
|
rlm@1
|
2793 case 1:
|
rlm@1
|
2794 for(i = 0; i < srcHeight; i++) {
|
rlm@1
|
2795 SDL_CALL_STRETCHER;
|
rlm@1
|
2796 dest += destPitch;
|
rlm@1
|
2797 SDL_CALL_STRETCHER;
|
rlm@1
|
2798 src += srcPitch;
|
rlm@1
|
2799 dest += destPitch;
|
rlm@1
|
2800 }
|
rlm@1
|
2801 break;
|
rlm@1
|
2802 case 2:
|
rlm@1
|
2803 for(i = 0; i < srcHeight; i++) {
|
rlm@1
|
2804 SDL_CALL_STRETCHER;
|
rlm@1
|
2805 dest += destPitch;
|
rlm@1
|
2806 SDL_CALL_STRETCHER;
|
rlm@1
|
2807 dest += destPitch;
|
rlm@1
|
2808 SDL_CALL_STRETCHER;
|
rlm@1
|
2809 src += srcPitch;
|
rlm@1
|
2810 dest += destPitch;
|
rlm@1
|
2811 }
|
rlm@1
|
2812 break;
|
rlm@1
|
2813 case 3:
|
rlm@1
|
2814 for(i = 0; i < srcHeight; i++) {
|
rlm@1
|
2815 SDL_CALL_STRETCHER;
|
rlm@1
|
2816 dest += destPitch;
|
rlm@1
|
2817 SDL_CALL_STRETCHER;
|
rlm@1
|
2818 dest += destPitch;
|
rlm@1
|
2819 SDL_CALL_STRETCHER;
|
rlm@1
|
2820 dest += destPitch;
|
rlm@1
|
2821 SDL_CALL_STRETCHER;
|
rlm@1
|
2822 src += srcPitch;
|
rlm@1
|
2823 dest += destPitch;
|
rlm@1
|
2824 }
|
rlm@1
|
2825 break;
|
rlm@1
|
2826 }
|
rlm@1
|
2827 }
|
rlm@1
|
2828
|
rlm@1
|
2829 if(showSpeed && fullscreen) {
|
rlm@1
|
2830 char buffer[50];
|
rlm@1
|
2831 if(showSpeed == 1)
|
rlm@1
|
2832 sprintf(buffer, "%d%%", systemSpeed);
|
rlm@1
|
2833 else
|
rlm@1
|
2834 sprintf(buffer, "%3d%%(%d, %d fps)", systemSpeed,
|
rlm@1
|
2835 systemFrameSkip,
|
rlm@1
|
2836 showRenderedFrames);
|
rlm@1
|
2837 if(showSpeedTransparent)
|
rlm@1
|
2838 drawTextTransp((u8*)surface->pixels,
|
rlm@1
|
2839 surface->pitch,
|
rlm@1
|
2840 10,
|
rlm@1
|
2841 surface->h-20,
|
rlm@1
|
2842 buffer);
|
rlm@1
|
2843 else
|
rlm@1
|
2844 drawText((u8*)surface->pixels,
|
rlm@1
|
2845 surface->pitch,
|
rlm@1
|
2846 10,
|
rlm@1
|
2847 surface->h-20,
|
rlm@1
|
2848 buffer);
|
rlm@1
|
2849 }
|
rlm@1
|
2850
|
rlm@1
|
2851 SDL_UnlockSurface(surface);
|
rlm@1
|
2852 // SDL_UpdateRect(surface, 0, 0, destWidth, destHeight);
|
rlm@1
|
2853 SDL_Flip(surface);
|
rlm@1
|
2854 }
|
rlm@1
|
2855
|
rlm@1
|
2856 bool systemReadJoypads()
|
rlm@1
|
2857 {
|
rlm@1
|
2858 return true;
|
rlm@1
|
2859 }
|
rlm@1
|
2860
|
rlm@1
|
2861 // Kludge to make Lua call the right function.
|
rlm@1
|
2862 u32 systemGetOriginalJoypad(int which, bool sensor){
|
rlm@1
|
2863 return systemGetJoypad(which,sensor);
|
rlm@1
|
2864 }
|
rlm@1
|
2865
|
rlm@1
|
2866 u32 systemGetJoypad(int which, bool sensor)
|
rlm@1
|
2867 {
|
rlm@1
|
2868 sensorOn = sensor;
|
rlm@1
|
2869 if(which < 0 || which > 3)
|
rlm@1
|
2870 which = sdlDefaultJoypad;
|
rlm@1
|
2871
|
rlm@1
|
2872 //VBAMovieUpdate(which);
|
rlm@1
|
2873 //VBAMovieUpdateState();
|
rlm@1
|
2874 u32 res = 0;
|
rlm@1
|
2875
|
rlm@1
|
2876 //----------------------------//
|
rlm@1
|
2877 if (VBAMoviePlaying()){
|
rlm@1
|
2878 // VBAMovieRead() overwrites currentButtons[i]
|
rlm@1
|
2879 VBAMovieRead(which, sensor);
|
rlm@1
|
2880 res = currentButtons[which];
|
rlm@1
|
2881 return res;
|
rlm@1
|
2882 }
|
rlm@1
|
2883 //---------------------------//
|
rlm@1
|
2884 //Temporary implementation, not sure if it's correct --Felipe
|
rlm@1
|
2885
|
rlm@1
|
2886 /*
|
rlm@1
|
2887 if(sdlButtons[which][KEY_BUTTON_A])
|
rlm@1
|
2888 res |= BUTTON_MASK_A;
|
rlm@1
|
2889 if(sdlButtons[which][KEY_BUTTON_B])
|
rlm@1
|
2890 res |= BUTTON_MASK_B;
|
rlm@1
|
2891 if(sdlButtons[which][KEY_BUTTON_SELECT])
|
rlm@1
|
2892 res |= BUTTON_MASK_SELECT;
|
rlm@1
|
2893 if(sdlButtons[which][KEY_BUTTON_START])
|
rlm@1
|
2894 res |= BUTTON_MASK_START;
|
rlm@1
|
2895 if(sdlButtons[which][KEY_RIGHT])
|
rlm@1
|
2896 res |= BUTTON_MASK_RIGHT;
|
rlm@1
|
2897 if(sdlButtons[which][KEY_LEFT])
|
rlm@1
|
2898 res |= BUTTON_MASK_LEFT;
|
rlm@1
|
2899 if(sdlButtons[which][KEY_UP])
|
rlm@1
|
2900 res |= BUTTON_MASK_UP;
|
rlm@1
|
2901 if(sdlButtons[which][KEY_DOWN])
|
rlm@1
|
2902 res |= BUTTON_MASK_DOWN;
|
rlm@1
|
2903 if(sdlButtons[which][KEY_BUTTON_R])
|
rlm@1
|
2904 res |= BUTTON_MASK_R;
|
rlm@1
|
2905 if(sdlButtons[which][KEY_BUTTON_L])
|
rlm@1
|
2906 res |= BUTTON_MASK_L;
|
rlm@1
|
2907 */
|
rlm@1
|
2908 /*
|
rlm@1
|
2909 // disallow L+R or U+D of being pressed at the same time
|
rlm@1
|
2910 if((res & 48) == 48)
|
rlm@1
|
2911 res &= ~16;
|
rlm@1
|
2912 if((res & 192) == 192)
|
rlm@1
|
2913 res &= ~128;
|
rlm@1
|
2914 */
|
rlm@1
|
2915 /*
|
rlm@1
|
2916 if(sdlbuttons[which][KEY_BUTTON_SPEED])
|
rlm@1
|
2917 res |= 1024;
|
rlm@1
|
2918 if(sdlButtons[which][KEY_BUTTON_CAPTURE])
|
rlm@1
|
2919 res |= 2048;
|
rlm@1
|
2920 */
|
rlm@1
|
2921 res = currentButtons[which];
|
rlm@1
|
2922
|
rlm@1
|
2923 if(autoFire) {
|
rlm@1
|
2924 res &= (~autoFire);
|
rlm@1
|
2925 if(autoFireToggle)
|
rlm@1
|
2926 res |= autoFire;
|
rlm@1
|
2927 autoFireToggle = !autoFireToggle;
|
rlm@1
|
2928 }
|
rlm@1
|
2929
|
rlm@1
|
2930 //if (res) fprintf(stdout,"%x\n",res);
|
rlm@1
|
2931
|
rlm@1
|
2932 return res;
|
rlm@1
|
2933 }
|
rlm@1
|
2934
|
rlm@1
|
2935 void systemSetJoypad(int which, u32 buttons)
|
rlm@1
|
2936 {
|
rlm@1
|
2937 if(which < 0 || which > 3)
|
rlm@1
|
2938 which = sdlDefaultJoypad;
|
rlm@1
|
2939 /*
|
rlm@1
|
2940 sdlButtons[which][KEY_BUTTON_A] = (buttons & 1) != 0;
|
rlm@1
|
2941 sdlButtons[which][KEY_BUTTON_B] = (buttons & 2) != 0;
|
rlm@1
|
2942 sdlButtons[which][KEY_BUTTON_SELECT] = (buttons & 4) != 0;
|
rlm@1
|
2943 sdlButtons[which][KEY_BUTTON_START] = (buttons & 8) != 0;
|
rlm@1
|
2944 sdlButtons[which][KEY_RIGHT] = (buttons & 16) != 0;
|
rlm@1
|
2945 sdlButtons[which][KEY_LEFT] = (buttons & 32) != 0;
|
rlm@1
|
2946 sdlButtons[which][KEY_UP] = (buttons & 64) != 0;
|
rlm@1
|
2947 sdlButtons[which][KEY_DOWN] = (buttons & 128) != 0;
|
rlm@1
|
2948 sdlButtons[which][KEY_BUTTON_R] = (buttons & 256) != 0;
|
rlm@1
|
2949 sdlButtons[which][KEY_BUTTON_L] = (buttons & 512) != 0;
|
rlm@1
|
2950 */
|
rlm@1
|
2951 currentButtons[which]= buttons & 0x3ff;
|
rlm@1
|
2952 }
|
rlm@1
|
2953
|
rlm@1
|
2954 void systemClearJoypads()
|
rlm@1
|
2955 {
|
rlm@1
|
2956 for (int i = 0; i < 4; ++i)
|
rlm@1
|
2957 currentButtons[i] = 0;
|
rlm@1
|
2958
|
rlm@1
|
2959 //lastKeys = 0;
|
rlm@1
|
2960 }
|
rlm@1
|
2961
|
rlm@1
|
2962 void systemSetTitle(const char *title)
|
rlm@1
|
2963 {
|
rlm@1
|
2964 SDL_WM_SetCaption(title, NULL);
|
rlm@1
|
2965 }
|
rlm@1
|
2966
|
rlm@1
|
2967 void systemShowSpeed(int speed)
|
rlm@1
|
2968 {
|
rlm@1
|
2969 systemSpeed = speed;
|
rlm@1
|
2970
|
rlm@1
|
2971 showRenderedFrames = renderedFrames;
|
rlm@1
|
2972 renderedFrames = 0;
|
rlm@1
|
2973
|
rlm@1
|
2974 if(!fullscreen && showSpeed) {
|
rlm@1
|
2975 char buffer[80];
|
rlm@1
|
2976 if(showSpeed == 1)
|
rlm@1
|
2977 sprintf(buffer, "VisualBoyAdvance-%3d%%", systemSpeed);
|
rlm@1
|
2978 else
|
rlm@1
|
2979 sprintf(buffer, "VisualBoyAdvance-%3d%%(%d, %d fps)", systemSpeed,
|
rlm@1
|
2980 systemFrameSkip,
|
rlm@1
|
2981 showRenderedFrames);
|
rlm@1
|
2982
|
rlm@1
|
2983 systemSetTitle(buffer);
|
rlm@1
|
2984 }
|
rlm@1
|
2985 }
|
rlm@1
|
2986
|
rlm@1
|
2987 // FIXME: the timing
|
rlm@1
|
2988 void systemFrame(/*int rate*/) //Looking at System.cpp, it looks like rate should be 600
|
rlm@1
|
2989 {
|
rlm@1
|
2990 u32 time = systemGetClock();
|
rlm@1
|
2991 if(!wasPaused && autoFrameSkip && !throttle) {
|
rlm@1
|
2992 u32 diff = time - autoFrameSkipLastTime;
|
rlm@1
|
2993 int speed = 100;
|
rlm@1
|
2994
|
rlm@1
|
2995 if(diff)
|
rlm@1
|
2996 speed = (1000000/600)/diff;
|
rlm@1
|
2997
|
rlm@1
|
2998 if(speed >= 98) {
|
rlm@1
|
2999 frameskipadjust++;
|
rlm@1
|
3000
|
rlm@1
|
3001 if(frameskipadjust >= 3) {
|
rlm@1
|
3002 frameskipadjust=0;
|
rlm@1
|
3003 if(systemFrameSkip > 0)
|
rlm@1
|
3004 systemFrameSkip--;
|
rlm@1
|
3005 }
|
rlm@1
|
3006 } else {
|
rlm@1
|
3007 if(speed < 80)
|
rlm@1
|
3008 frameskipadjust -= (90 - speed)/5;
|
rlm@1
|
3009 else if(systemFrameSkip < 9)
|
rlm@1
|
3010 frameskipadjust--;
|
rlm@1
|
3011
|
rlm@1
|
3012 if(frameskipadjust <= -2) {
|
rlm@1
|
3013 frameskipadjust += 2;
|
rlm@1
|
3014 if(systemFrameSkip < 9)
|
rlm@1
|
3015 systemFrameSkip++;
|
rlm@1
|
3016 }
|
rlm@1
|
3017 }
|
rlm@1
|
3018 }
|
rlm@1
|
3019 if(!wasPaused && throttle) {
|
rlm@1
|
3020 /*if(!speedup) {
|
rlm@1
|
3021 u32 diff = time - throttleLastTime;
|
rlm@1
|
3022
|
rlm@1
|
3023 int target = (1000000.0/(600*throttle));
|
rlm@1
|
3024 int d = (target - diff);
|
rlm@1
|
3025
|
rlm@1
|
3026 if(d > 0) {
|
rlm@1
|
3027 SDL_Delay(d);
|
rlm@1
|
3028 }
|
rlm@1
|
3029 }
|
rlm@1
|
3030 throttleLastTime = systemGetClock();
|
rlm@1
|
3031 */
|
rlm@1
|
3032 }
|
rlm@1
|
3033 if(rewindMemory) {
|
rlm@1
|
3034 if(++rewindCounter >= rewindTimer) {
|
rlm@1
|
3035 rewindSaveNeeded = true;
|
rlm@1
|
3036 rewindCounter = 0;
|
rlm@1
|
3037 }
|
rlm@1
|
3038 }
|
rlm@1
|
3039
|
rlm@1
|
3040 if(systemSaveUpdateCounter) {
|
rlm@1
|
3041 if(--systemSaveUpdateCounter <= SYSTEM_SAVE_NOT_UPDATED) {
|
rlm@1
|
3042 sdlWriteBattery();
|
rlm@1
|
3043 systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
rlm@1
|
3044 }
|
rlm@1
|
3045 }
|
rlm@1
|
3046
|
rlm@1
|
3047 wasPaused = false;
|
rlm@1
|
3048 autoFrameSkipLastTime = time;
|
rlm@1
|
3049 }
|
rlm@1
|
3050
|
rlm@1
|
3051 int systemFramesToSkip(){
|
rlm@1
|
3052 return systemFrameSkip;
|
rlm@1
|
3053 }
|
rlm@1
|
3054
|
rlm@1
|
3055 int systemScreenCapture(int a)
|
rlm@1
|
3056 {
|
rlm@1
|
3057 char buffer[2048];
|
rlm@1
|
3058
|
rlm@1
|
3059 if(captureFormat) {
|
rlm@1
|
3060 if(captureDir[0])
|
rlm@1
|
3061 sprintf(buffer, "%s/%s%02d.bmp", captureDir, sdlGetFilename(filename), a);
|
rlm@1
|
3062 else
|
rlm@1
|
3063 sprintf(buffer, "%s%02d.bmp", filename, a);
|
rlm@1
|
3064
|
rlm@1
|
3065 theEmulator.emuWriteBMP(buffer);
|
rlm@1
|
3066 } else {
|
rlm@1
|
3067 if(captureDir[0])
|
rlm@1
|
3068 sprintf(buffer, "%s/%s%02d.png", captureDir, sdlGetFilename(filename), a);
|
rlm@1
|
3069 else
|
rlm@1
|
3070 sprintf(buffer, "%s%02d.png", filename, a);
|
rlm@1
|
3071 theEmulator.emuWritePNG(buffer);
|
rlm@1
|
3072 }
|
rlm@1
|
3073
|
rlm@1
|
3074 systemScreenMessage("Screen capture");
|
rlm@1
|
3075 return a;
|
rlm@1
|
3076 }
|
rlm@1
|
3077
|
rlm@1
|
3078 void soundCallback(void *,u8 *stream,int len){}
|
rlm@1
|
3079
|
rlm@1
|
3080 void systemSoundWriteToBuffer(){
|
rlm@1
|
3081 soundDriver->write(soundFinalWave, soundBufferLen);
|
rlm@1
|
3082 }
|
rlm@1
|
3083
|
rlm@1
|
3084 void systemSoundClearBuffer()
|
rlm@1
|
3085 {
|
rlm@1
|
3086 SDL_mutexP(mutex);
|
rlm@1
|
3087 memset(sdlBuffer,0,soundBufferTotalLen);
|
rlm@1
|
3088 sdlSoundLen=0;
|
rlm@1
|
3089 printf("Hi\n");
|
rlm@1
|
3090 SDL_mutexV(mutex);
|
rlm@1
|
3091 }
|
rlm@1
|
3092
|
rlm@1
|
3093 bool systemSoundInit(){
|
rlm@1
|
3094 systemSoundShutdown();
|
rlm@1
|
3095 soundDriver = new SoundSDL();
|
rlm@1
|
3096 if ( !soundDriver )
|
rlm@1
|
3097 return false;
|
rlm@1
|
3098
|
rlm@1
|
3099 if (!soundDriver->init()) //<-- sound sample rate
|
rlm@1
|
3100 return false;
|
rlm@1
|
3101
|
rlm@1
|
3102 if (!(soundDriver->setThrottle(throttle))){
|
rlm@1
|
3103 fprintf(stderr,"Failed to set desired throttle, defaulting to 100 %%.\n");
|
rlm@1
|
3104 if (!soundDriver->setThrottle(100)) return false;
|
rlm@1
|
3105 }
|
rlm@1
|
3106 soundPaused = true;
|
rlm@1
|
3107 systemSoundOn = true;
|
rlm@1
|
3108 return true;
|
rlm@1
|
3109 }
|
rlm@1
|
3110
|
rlm@1
|
3111 void systemSoundShutdown(){
|
rlm@1
|
3112 if (soundDriver)
|
rlm@1
|
3113 {
|
rlm@1
|
3114 delete soundDriver;
|
rlm@1
|
3115 soundDriver = 0;
|
rlm@1
|
3116 }
|
rlm@1
|
3117 }
|
rlm@1
|
3118
|
rlm@1
|
3119 void systemSoundPause()
|
rlm@1
|
3120 {
|
rlm@1
|
3121 SDL_PauseAudio(1);
|
rlm@1
|
3122 }
|
rlm@1
|
3123
|
rlm@1
|
3124 void systemSoundResume()
|
rlm@1
|
3125 {
|
rlm@1
|
3126 SDL_PauseAudio(0);
|
rlm@1
|
3127 }
|
rlm@1
|
3128
|
rlm@1
|
3129 void systemSoundReset()
|
rlm@1
|
3130 {
|
rlm@1
|
3131 }
|
rlm@1
|
3132
|
rlm@1
|
3133 u32 systemGetClock()
|
rlm@1
|
3134 {
|
rlm@1
|
3135 return SDL_GetTicks();
|
rlm@1
|
3136 }
|
rlm@1
|
3137
|
rlm@1
|
3138 void systemUpdateMotionSensor()
|
rlm@1
|
3139 {
|
rlm@1
|
3140 if(sdlMotionButtons[KEY_LEFT]) {
|
rlm@1
|
3141 sensorX += 3;
|
rlm@1
|
3142 if(sensorX > 2197)
|
rlm@1
|
3143 sensorX = 2197;
|
rlm@1
|
3144 if(sensorX < 2047)
|
rlm@1
|
3145 sensorX = 2057;
|
rlm@1
|
3146 } else if(sdlMotionButtons[KEY_RIGHT]) {
|
rlm@1
|
3147 sensorX -= 3;
|
rlm@1
|
3148 if(sensorX < 1897)
|
rlm@1
|
3149 sensorX = 1897;
|
rlm@1
|
3150 if(sensorX > 2047)
|
rlm@1
|
3151 sensorX = 2037;
|
rlm@1
|
3152 } else if(sensorX > 2047) {
|
rlm@1
|
3153 sensorX -= 2;
|
rlm@1
|
3154 if(sensorX < 2047)
|
rlm@1
|
3155 sensorX = 2047;
|
rlm@1
|
3156 } else {
|
rlm@1
|
3157 sensorX += 2;
|
rlm@1
|
3158 if(sensorX > 2047)
|
rlm@1
|
3159 sensorX = 2047;
|
rlm@1
|
3160 }
|
rlm@1
|
3161
|
rlm@1
|
3162 if(sdlMotionButtons[KEY_UP]) {
|
rlm@1
|
3163 sensorY += 3;
|
rlm@1
|
3164 if(sensorY > 2197)
|
rlm@1
|
3165 sensorY = 2197;
|
rlm@1
|
3166 if(sensorY < 2047)
|
rlm@1
|
3167 sensorY = 2057;
|
rlm@1
|
3168 } else if(sdlMotionButtons[KEY_DOWN]) {
|
rlm@1
|
3169 sensorY -= 3;
|
rlm@1
|
3170 if(sensorY < 1897)
|
rlm@1
|
3171 sensorY = 1897;
|
rlm@1
|
3172 if(sensorY > 2047)
|
rlm@1
|
3173 sensorY = 2037;
|
rlm@1
|
3174 } else if(sensorY > 2047) {
|
rlm@1
|
3175 sensorY -= 2;
|
rlm@1
|
3176 if(sensorY < 2047)
|
rlm@1
|
3177 sensorY = 2047;
|
rlm@1
|
3178 } else {
|
rlm@1
|
3179 sensorY += 2;
|
rlm@1
|
3180 if(sensorY > 2047)
|
rlm@1
|
3181 sensorY = 2047;
|
rlm@1
|
3182 }
|
rlm@1
|
3183 }
|
rlm@1
|
3184
|
rlm@1
|
3185 void systemResetSensor()
|
rlm@1
|
3186 {
|
rlm@1
|
3187 sensorX = sensorY = INITIAL_SENSOR_VALUE;
|
rlm@1
|
3188 }
|
rlm@1
|
3189
|
rlm@1
|
3190 int systemGetSensorX()
|
rlm@1
|
3191 {
|
rlm@1
|
3192 return sensorX;
|
rlm@1
|
3193 }
|
rlm@1
|
3194
|
rlm@1
|
3195 int systemGetSensorY()
|
rlm@1
|
3196 {
|
rlm@1
|
3197 return sensorY;
|
rlm@1
|
3198 }
|
rlm@1
|
3199
|
rlm@1
|
3200 void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast)
|
rlm@1
|
3201 {
|
rlm@1
|
3202 }
|
rlm@1
|
3203
|
rlm@1
|
3204 void systemScreenMessage(const char *msg, int slot, int duration, const char *colorList)
|
rlm@1
|
3205 {
|
rlm@1
|
3206 screenMessage[slot] = true;
|
rlm@1
|
3207 screenMessageTime[slot] = systemGetClock();
|
rlm@1
|
3208 screenMessageDuration[slot] = duration;
|
rlm@1
|
3209 if(strlen(msg) > 20) {
|
rlm@1
|
3210 strncpy(screenMessageBuffer[slot], msg, 20);
|
rlm@1
|
3211 screenMessageBuffer[slot][20] = 0;
|
rlm@1
|
3212 } else
|
rlm@1
|
3213 strcpy(screenMessageBuffer[slot], msg);
|
rlm@1
|
3214 }
|
rlm@1
|
3215
|
rlm@1
|
3216 bool systemSoundCanChangeQuality()
|
rlm@1
|
3217 {
|
rlm@1
|
3218 return false;
|
rlm@1
|
3219 }
|
rlm@1
|
3220
|
rlm@1
|
3221 bool systemSoundSetQuality(int quality)
|
rlm@1
|
3222 {
|
rlm@1
|
3223 if (systemCartridgeType == 0)
|
rlm@1
|
3224 soundSetQuality(quality);
|
rlm@1
|
3225 else
|
rlm@1
|
3226 gbSoundSetQuality(quality);
|
rlm@1
|
3227
|
rlm@1
|
3228 return true;
|
rlm@1
|
3229 }
|
rlm@1
|
3230
|
rlm@1
|
3231 bool systemPauseOnFrame()
|
rlm@1
|
3232 {
|
rlm@1
|
3233 if(pauseNextFrame) {
|
rlm@1
|
3234 paused = true;
|
rlm@1
|
3235 pauseNextFrame = false;
|
rlm@1
|
3236 return true;
|
rlm@1
|
3237 }
|
rlm@1
|
3238 return false;
|
rlm@1
|
3239 }
|
rlm@1
|
3240
|
rlm@1
|
3241 // Code donated by Niels Wagenaar (BoycottAdvance)
|
rlm@1
|
3242
|
rlm@1
|
3243 // GBA screensize.
|
rlm@1
|
3244 #define GBA_WIDTH 240
|
rlm@1
|
3245 #define GBA_HEIGHT 160
|
rlm@1
|
3246
|
rlm@1
|
3247 void Init_Overlay(SDL_Surface *gbascreen, int overlaytype)
|
rlm@1
|
3248 {
|
rlm@1
|
3249
|
rlm@1
|
3250 overlay = SDL_CreateYUVOverlay( GBA_WIDTH,
|
rlm@1
|
3251 GBA_HEIGHT,
|
rlm@1
|
3252 overlaytype, gbascreen);
|
rlm@1
|
3253 fprintf(stderr, "Created %dx%dx%d %s %s overlay\n",
|
rlm@1
|
3254 overlay->w,overlay->h,overlay->planes,
|
rlm@1
|
3255 overlay->hw_overlay?"hardware":"software",
|
rlm@1
|
3256 overlay->format==SDL_YV12_OVERLAY?"YV12":
|
rlm@1
|
3257 overlay->format==SDL_IYUV_OVERLAY?"IYUV":
|
rlm@1
|
3258 overlay->format==SDL_YUY2_OVERLAY?"YUY2":
|
rlm@1
|
3259 overlay->format==SDL_UYVY_OVERLAY?"UYVY":
|
rlm@1
|
3260 overlay->format==SDL_YVYU_OVERLAY?"YVYU":
|
rlm@1
|
3261 "Unknown");
|
rlm@1
|
3262 }
|
rlm@1
|
3263
|
rlm@1
|
3264 void Quit_Overlay(void)
|
rlm@1
|
3265 {
|
rlm@1
|
3266
|
rlm@1
|
3267 SDL_FreeYUVOverlay(overlay);
|
rlm@1
|
3268 }
|
rlm@1
|
3269
|
rlm@1
|
3270 /* NOTE: These RGB conversion functions are not intended for speed,
|
rlm@1
|
3271 only as examples.
|
rlm@1
|
3272 */
|
rlm@1
|
3273 inline void RGBtoYUV(Uint8 *rgb, int *yuv)
|
rlm@1
|
3274 {
|
rlm@1
|
3275 yuv[0] = (int)((0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16);
|
rlm@1
|
3276 yuv[1] = (int)(128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]));
|
rlm@1
|
3277 yuv[2] = (int)(128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]));
|
rlm@1
|
3278 }
|
rlm@1
|
3279
|
rlm@1
|
3280 inline void ConvertRGBtoYV12(SDL_Overlay *o)
|
rlm@1
|
3281 {
|
rlm@1
|
3282 int x,y;
|
rlm@1
|
3283 int yuv[3];
|
rlm@1
|
3284 Uint8 *p,*op[3];
|
rlm@1
|
3285
|
rlm@1
|
3286 SDL_LockYUVOverlay(o);
|
rlm@1
|
3287
|
rlm@1
|
3288 /* Black initialization */
|
rlm@1
|
3289 /*
|
rlm@1
|
3290 memset(o->pixels[0],0,o->pitches[0]*o->h);
|
rlm@1
|
3291 memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2));
|
rlm@1
|
3292 memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2));
|
rlm@1
|
3293 */
|
rlm@1
|
3294
|
rlm@1
|
3295 /* Convert */
|
rlm@1
|
3296 for(y=0; y<160 && y<o->h; y++) {
|
rlm@1
|
3297 p=(Uint8 *)pix+srcPitch*y;
|
rlm@1
|
3298 op[0]=o->pixels[0]+o->pitches[0]*y;
|
rlm@1
|
3299 op[1]=o->pixels[1]+o->pitches[1]*(y/2);
|
rlm@1
|
3300 op[2]=o->pixels[2]+o->pitches[2]*(y/2);
|
rlm@1
|
3301 for(x=0; x<240 && x<o->w; x++) {
|
rlm@1
|
3302 RGBtoYUV(p,yuv);
|
rlm@1
|
3303 *(op[0]++)=yuv[0];
|
rlm@1
|
3304 if(x%2==0 && y%2==0) {
|
rlm@1
|
3305 *(op[1]++)=yuv[2];
|
rlm@1
|
3306 *(op[2]++)=yuv[1];
|
rlm@1
|
3307 }
|
rlm@1
|
3308 p+=4;//s->format->BytesPerPixel;
|
rlm@1
|
3309 }
|
rlm@1
|
3310 }
|
rlm@1
|
3311
|
rlm@1
|
3312 SDL_UnlockYUVOverlay(o);
|
rlm@1
|
3313 }
|
rlm@1
|
3314
|
rlm@1
|
3315 inline void ConvertRGBtoIYUV(SDL_Overlay *o)
|
rlm@1
|
3316 {
|
rlm@1
|
3317 int x,y;
|
rlm@1
|
3318 int yuv[3];
|
rlm@1
|
3319 Uint8 *p,*op[3];
|
rlm@1
|
3320
|
rlm@1
|
3321 SDL_LockYUVOverlay(o);
|
rlm@1
|
3322
|
rlm@1
|
3323 /* Black initialization */
|
rlm@1
|
3324 /*
|
rlm@1
|
3325 memset(o->pixels[0],0,o->pitches[0]*o->h);
|
rlm@1
|
3326 memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2));
|
rlm@1
|
3327 memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2));
|
rlm@1
|
3328 */
|
rlm@1
|
3329
|
rlm@1
|
3330 /* Convert */
|
rlm@1
|
3331 for(y=0; y<160 && y<o->h; y++) {
|
rlm@1
|
3332 p=(Uint8 *)pix+srcPitch*y;
|
rlm@1
|
3333 op[0]=o->pixels[0]+o->pitches[0]*y;
|
rlm@1
|
3334 op[1]=o->pixels[1]+o->pitches[1]*(y/2);
|
rlm@1
|
3335 op[2]=o->pixels[2]+o->pitches[2]*(y/2);
|
rlm@1
|
3336 for(x=0; x<240 && x<o->w; x++) {
|
rlm@1
|
3337 RGBtoYUV(p,yuv);
|
rlm@1
|
3338 *(op[0]++)=yuv[0];
|
rlm@1
|
3339 if(x%2==0 && y%2==0) {
|
rlm@1
|
3340 *(op[1]++)=yuv[1];
|
rlm@1
|
3341 *(op[2]++)=yuv[2];
|
rlm@1
|
3342 }
|
rlm@1
|
3343 p+=4; //s->format->BytesPerPixel;
|
rlm@1
|
3344 }
|
rlm@1
|
3345 }
|
rlm@1
|
3346
|
rlm@1
|
3347 SDL_UnlockYUVOverlay(o);
|
rlm@1
|
3348 }
|
rlm@1
|
3349
|
rlm@1
|
3350 inline void ConvertRGBtoUYVY(SDL_Overlay *o)
|
rlm@1
|
3351 {
|
rlm@1
|
3352 int x,y;
|
rlm@1
|
3353 int yuv[3];
|
rlm@1
|
3354 Uint8 *p,*op;
|
rlm@1
|
3355
|
rlm@1
|
3356 SDL_LockYUVOverlay(o);
|
rlm@1
|
3357
|
rlm@1
|
3358 for(y=0; y<160 && y<o->h; y++) {
|
rlm@1
|
3359 p=(Uint8 *)pix+srcPitch*y;
|
rlm@1
|
3360 op=o->pixels[0]+o->pitches[0]*y;
|
rlm@1
|
3361 for(x=0; x<240 && x<o->w; x++) {
|
rlm@1
|
3362 RGBtoYUV(p,yuv);
|
rlm@1
|
3363 if(x%2==0) {
|
rlm@1
|
3364 *(op++)=yuv[1];
|
rlm@1
|
3365 *(op++)=yuv[0];
|
rlm@1
|
3366 *(op++)=yuv[2];
|
rlm@1
|
3367 } else
|
rlm@1
|
3368 *(op++)=yuv[0];
|
rlm@1
|
3369
|
rlm@1
|
3370 p+=4; //s->format->BytesPerPixel;
|
rlm@1
|
3371 }
|
rlm@1
|
3372 }
|
rlm@1
|
3373
|
rlm@1
|
3374 SDL_UnlockYUVOverlay(o);
|
rlm@1
|
3375 }
|
rlm@1
|
3376
|
rlm@1
|
3377 inline void ConvertRGBtoYVYU(SDL_Overlay *o)
|
rlm@1
|
3378 {
|
rlm@1
|
3379 int x,y;
|
rlm@1
|
3380 int yuv[3];
|
rlm@1
|
3381 Uint8 *p,*op;
|
rlm@1
|
3382
|
rlm@1
|
3383 SDL_LockYUVOverlay(o);
|
rlm@1
|
3384
|
rlm@1
|
3385 for(y=0; y<160 && y<o->h; y++) {
|
rlm@1
|
3386 p=(Uint8 *)pix+srcPitch*y;
|
rlm@1
|
3387 op=o->pixels[0]+o->pitches[0]*y;
|
rlm@1
|
3388 for(x=0; x<240 && x<o->w; x++) {
|
rlm@1
|
3389 RGBtoYUV(p,yuv);
|
rlm@1
|
3390 if(x%2==0) {
|
rlm@1
|
3391 *(op++)=yuv[0];
|
rlm@1
|
3392 *(op++)=yuv[2];
|
rlm@1
|
3393 op[1]=yuv[1];
|
rlm@1
|
3394 } else {
|
rlm@1
|
3395 *op=yuv[0];
|
rlm@1
|
3396 op+=2;
|
rlm@1
|
3397 }
|
rlm@1
|
3398
|
rlm@1
|
3399 p+=4; //s->format->BytesPerPixel;
|
rlm@1
|
3400 }
|
rlm@1
|
3401 }
|
rlm@1
|
3402
|
rlm@1
|
3403 SDL_UnlockYUVOverlay(o);
|
rlm@1
|
3404 }
|
rlm@1
|
3405
|
rlm@1
|
3406 inline void ConvertRGBtoYUY2(SDL_Overlay *o)
|
rlm@1
|
3407 {
|
rlm@1
|
3408 int x,y;
|
rlm@1
|
3409 int yuv[3];
|
rlm@1
|
3410 Uint8 *p,*op;
|
rlm@1
|
3411
|
rlm@1
|
3412 SDL_LockYUVOverlay(o);
|
rlm@1
|
3413
|
rlm@1
|
3414 for(y=0; y<160 && y<o->h; y++) {
|
rlm@1
|
3415 p=(Uint8 *)pix+srcPitch*y;
|
rlm@1
|
3416 op=o->pixels[0]+o->pitches[0]*y;
|
rlm@1
|
3417 for(x=0; x<240 && x<o->w; x++) {
|
rlm@1
|
3418 RGBtoYUV(p,yuv);
|
rlm@1
|
3419 if(x%2==0) {
|
rlm@1
|
3420 *(op++)=yuv[0];
|
rlm@1
|
3421 *(op++)=yuv[1];
|
rlm@1
|
3422 op[1]=yuv[2];
|
rlm@1
|
3423 } else {
|
rlm@1
|
3424 *op=yuv[0];
|
rlm@1
|
3425 op+=2;
|
rlm@1
|
3426 }
|
rlm@1
|
3427
|
rlm@1
|
3428 p+=4; //s->format->BytesPerPixel;
|
rlm@1
|
3429 }
|
rlm@1
|
3430 }
|
rlm@1
|
3431
|
rlm@1
|
3432 SDL_UnlockYUVOverlay(o);
|
rlm@1
|
3433 }
|
rlm@1
|
3434
|
rlm@1
|
3435 inline void Convert32bit(SDL_Surface *display)
|
rlm@1
|
3436 {
|
rlm@1
|
3437 switch(overlay->format) {
|
rlm@1
|
3438 case SDL_YV12_OVERLAY:
|
rlm@1
|
3439 ConvertRGBtoYV12(overlay);
|
rlm@1
|
3440 break;
|
rlm@1
|
3441 case SDL_UYVY_OVERLAY:
|
rlm@1
|
3442 ConvertRGBtoUYVY(overlay);
|
rlm@1
|
3443 break;
|
rlm@1
|
3444 case SDL_YVYU_OVERLAY:
|
rlm@1
|
3445 ConvertRGBtoYVYU(overlay);
|
rlm@1
|
3446 break;
|
rlm@1
|
3447 case SDL_YUY2_OVERLAY:
|
rlm@1
|
3448 ConvertRGBtoYUY2(overlay);
|
rlm@1
|
3449 break;
|
rlm@1
|
3450 case SDL_IYUV_OVERLAY:
|
rlm@1
|
3451 ConvertRGBtoIYUV(overlay);
|
rlm@1
|
3452 break;
|
rlm@1
|
3453 default:
|
rlm@1
|
3454 fprintf(stderr, "cannot convert RGB picture to obtained YUV format!\n");
|
rlm@1
|
3455 exit(1);
|
rlm@1
|
3456 break;
|
rlm@1
|
3457 }
|
rlm@1
|
3458
|
rlm@1
|
3459 }
|
rlm@1
|
3460
|
rlm@1
|
3461
|
rlm@1
|
3462 inline void Draw_Overlay(SDL_Surface *display, int size)
|
rlm@1
|
3463 {
|
rlm@1
|
3464 SDL_LockYUVOverlay(overlay);
|
rlm@1
|
3465
|
rlm@1
|
3466 Convert32bit(display);
|
rlm@1
|
3467
|
rlm@1
|
3468 overlay_rect.x = 0;
|
rlm@1
|
3469 overlay_rect.y = 0;
|
rlm@1
|
3470 overlay_rect.w = GBA_WIDTH * size;
|
rlm@1
|
3471 overlay_rect.h = GBA_HEIGHT * size;
|
rlm@1
|
3472
|
rlm@1
|
3473 SDL_DisplayYUVOverlay(overlay, &overlay_rect);
|
rlm@1
|
3474 SDL_UnlockYUVOverlay(overlay);
|
rlm@1
|
3475 }
|
rlm@1
|
3476
|
rlm@1
|
3477 bool systemIsEmulating()
|
rlm@1
|
3478 {
|
rlm@1
|
3479 return emulating != 0;
|
rlm@1
|
3480 }
|
rlm@1
|
3481
|
rlm@1
|
3482 void systemGbBorderOn()
|
rlm@1
|
3483 {
|
rlm@1
|
3484 srcWidth = 256;
|
rlm@1
|
3485 srcHeight = 224;
|
rlm@1
|
3486 gbBorderLineSkip = 256;
|
rlm@1
|
3487 gbBorderColumnSkip = 48;
|
rlm@1
|
3488 gbBorderRowSkip = 40;
|
rlm@1
|
3489
|
rlm@1
|
3490 destWidth = (sizeOption+1)*srcWidth;
|
rlm@1
|
3491 destHeight = (sizeOption+1)*srcHeight;
|
rlm@1
|
3492
|
rlm@1
|
3493 surface = SDL_SetVideoMode(destWidth, destHeight, 16,
|
rlm@1
|
3494 SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF|
|
rlm@1
|
3495 (fullscreen ? SDL_FULLSCREEN : 0));
|
rlm@1
|
3496 #ifndef C_CORE
|
rlm@1
|
3497 sdlMakeStretcher(srcWidth);
|
rlm@1
|
3498 #else
|
rlm@1
|
3499 switch(systemColorDepth) {
|
rlm@1
|
3500 case 16:
|
rlm@1
|
3501 sdlStretcher = sdlStretcher16[sizeOption];
|
rlm@1
|
3502 break;
|
rlm@1
|
3503 case 24:
|
rlm@1
|
3504 sdlStretcher = sdlStretcher24[sizeOption];
|
rlm@1
|
3505 break;
|
rlm@1
|
3506 case 32:
|
rlm@1
|
3507 sdlStretcher = sdlStretcher32[sizeOption];
|
rlm@1
|
3508 break;
|
rlm@1
|
3509 default:
|
rlm@1
|
3510 fprintf(stderr, "Unsupported resolution: %d\n", systemColorDepth);
|
rlm@1
|
3511 exit(-1);
|
rlm@1
|
3512 }
|
rlm@1
|
3513 #endif
|
rlm@1
|
3514
|
rlm@1
|
3515 if(systemColorDepth == 16) {
|
rlm@1
|
3516 if(sdlCalculateMaskWidth(surface->format->Gmask) == 6) {
|
rlm@1
|
3517 Init_2xSaI(565);
|
rlm@1
|
3518 RGB_LOW_BITS_MASK = 0x821;
|
rlm@1
|
3519 } else {
|
rlm@1
|
3520 Init_2xSaI(555);
|
rlm@1
|
3521 RGB_LOW_BITS_MASK = 0x421;
|
rlm@1
|
3522 }
|
rlm@1
|
3523 if(systemCartridgeType == 2) {
|
rlm@1
|
3524 for(int i = 0; i < 0x10000; i++) {
|
rlm@1
|
3525 systemColorMap16[i] = (((i >> 1) & 0x1f) << systemBlueShift) |
|
rlm@1
|
3526 (((i & 0x7c0) >> 6) << systemGreenShift) |
|
rlm@1
|
3527 (((i & 0xf800) >> 11) << systemRedShift);
|
rlm@1
|
3528 }
|
rlm@1
|
3529 } else {
|
rlm@1
|
3530 for(int i = 0; i < 0x10000; i++) {
|
rlm@1
|
3531 systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
|
rlm@1
|
3532 (((i & 0x3e0) >> 5) << systemGreenShift) |
|
rlm@1
|
3533 (((i & 0x7c00) >> 10) << systemBlueShift);
|
rlm@1
|
3534 }
|
rlm@1
|
3535 }
|
rlm@1
|
3536 srcPitch = srcWidth * 2+4;
|
rlm@1
|
3537 } else {
|
rlm@1
|
3538 if(systemColorDepth != 32)
|
rlm@1
|
3539 filterFunction = NULL;
|
rlm@1
|
3540 RGB_LOW_BITS_MASK = 0x010101;
|
rlm@1
|
3541 if(systemColorDepth == 32) {
|
rlm@1
|
3542 Init_2xSaI(32);
|
rlm@1
|
3543 }
|
rlm@1
|
3544 for(int i = 0; i < 0x10000; i++) {
|
rlm@1
|
3545 systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
|
rlm@1
|
3546 (((i & 0x3e0) >> 5) << systemGreenShift) |
|
rlm@1
|
3547 (((i & 0x7c00) >> 10) << systemBlueShift);
|
rlm@1
|
3548 }
|
rlm@1
|
3549 if(systemColorDepth == 32)
|
rlm@1
|
3550 srcPitch = srcWidth*4 + 4;
|
rlm@1
|
3551 else
|
rlm@1
|
3552 srcPitch = srcWidth*3;
|
rlm@1
|
3553 }
|
rlm@1
|
3554 }
|
rlm@1
|
3555
|
rlm@1
|
3556 bool systemIsRunningGBA()
|
rlm@1
|
3557 {
|
rlm@1
|
3558 return (rom != NULL);
|
rlm@1
|
3559 }
|
rlm@1
|
3560
|
rlm@1
|
3561 int systemGetDefaultJoypad()
|
rlm@1
|
3562 {
|
rlm@1
|
3563 return sdlDefaultJoypad;
|
rlm@1
|
3564 }
|
rlm@1
|
3565
|
rlm@1
|
3566 bool systemIsPaused()
|
rlm@1
|
3567 {
|
rlm@1
|
3568 return paused;
|
rlm@1
|
3569 }
|
rlm@1
|
3570
|
rlm@1
|
3571 void systemSetPause(bool pause)
|
rlm@1
|
3572 {
|
rlm@1
|
3573 paused = pause;
|
rlm@1
|
3574 if (pause)
|
rlm@1
|
3575 systemSoundPause();
|
rlm@1
|
3576 else
|
rlm@1
|
3577 systemSoundResume();
|
rlm@1
|
3578 }
|
rlm@1
|
3579
|
rlm@1
|
3580 u16 checksumBIOS()
|
rlm@1
|
3581 {
|
rlm@1
|
3582 bool hasBIOS = false;
|
rlm@1
|
3583 u8 * tempBIOS;
|
rlm@1
|
3584 if(useBios)
|
rlm@1
|
3585 {
|
rlm@1
|
3586 tempBIOS = (u8 *)malloc(0x4000);
|
rlm@1
|
3587 int size = 0x4000;
|
rlm@1
|
3588 if(utilLoad(biosFileName,
|
rlm@1
|
3589 utilIsGBABios,
|
rlm@1
|
3590 tempBIOS,
|
rlm@1
|
3591 size)) {
|
rlm@1
|
3592 if(size == 0x4000)
|
rlm@1
|
3593 hasBIOS = true;
|
rlm@1
|
3594 }
|
rlm@1
|
3595 }
|
rlm@1
|
3596
|
rlm@1
|
3597 u16 biosCheck = 0;
|
rlm@1
|
3598 if(hasBIOS) {
|
rlm@1
|
3599 for(int i = 0; i < 0x4000; i += 4)
|
rlm@1
|
3600 biosCheck += *((u32 *)&tempBIOS[i]);
|
rlm@1
|
3601 free(tempBIOS);
|
rlm@1
|
3602 }
|
rlm@1
|
3603
|
rlm@1
|
3604 return biosCheck;
|
rlm@1
|
3605 }
|
rlm@1
|
3606
|
rlm@1
|
3607 EmulatedSystemCounters systemCounters = {
|
rlm@1
|
3608 0, //framecount
|
rlm@1
|
3609 0, //lagcount
|
rlm@1
|
3610 0, //extracount
|
rlm@1
|
3611 true, //lagged
|
rlm@1
|
3612 true //laggedLast
|
rlm@1
|
3613 };
|
rlm@1
|
3614
|
rlm@1
|
3615 void VBAOnEnteringFrameBoundary()
|
rlm@1
|
3616 {
|
rlm@39
|
3617 //printf("RLM: Entering Frame Boundary\n");
|
rlm@33
|
3618 CallRegisteredLuaFunctions(LUACALL_AFTEREMULATION);
|
rlm@33
|
3619
|
rlm@33
|
3620 if (VBALuaRunning())
|
rlm@33
|
3621 {
|
rlm@33
|
3622 VBALuaFrameBoundary();
|
rlm@33
|
3623 }
|
rlm@33
|
3624
|
rlm@39
|
3625 //printf("RLM: Movie state update pending\n");
|
rlm@33
|
3626 VBAMovieUpdateState();
|
rlm@39
|
3627 //printf("RLM: Movie state updated\n");
|
rlm@1
|
3628 }
|
rlm@1
|
3629
|
rlm@1
|
3630 void VBAOnExitingFrameBoundary()
|
rlm@1
|
3631 {
|
rlm@1
|
3632 ;
|
rlm@1
|
3633 }
|
rlm@1
|
3634
|
rlm@1
|
3635
|