Mercurial > vba-linux
changeset 24:59790d015f25 works-incomplete
checkpoint
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sun, 04 Mar 2012 17:50:56 -0600 |
parents | bf9169ad4222 |
children | bacd824b9e27 |
files | src/common/Makefile.am src/common/lua-engine.cpp |
diffstat | 2 files changed, 4400 insertions(+), 4402 deletions(-) [+] |
line wrap: on
line diff
1.1 --- a/src/common/Makefile.am Sun Mar 04 17:38:32 2012 -0600 1.2 +++ b/src/common/Makefile.am Sun Mar 04 17:50:56 2012 -0600 1.3 @@ -5,7 +5,6 @@ 1.4 inputGlobal.h \ 1.5 memgzio.h \ 1.6 movie.h \ 1.7 - nesvideos-piece.h \ 1.8 System.h \ 1.9 Text.h \ 1.10 unzip.h \ 1.11 @@ -16,7 +15,6 @@ 1.12 lua-engine.cpp \ 1.13 memgzio.c \ 1.14 movie.cpp \ 1.15 - nesvideos-piece.cpp \ 1.16 Text.cpp \ 1.17 unzip.cpp \ 1.18 Util.cpp
2.1 --- a/src/common/lua-engine.cpp Sun Mar 04 17:38:32 2012 -0600 2.2 +++ b/src/common/lua-engine.cpp Sun Mar 04 17:50:56 2012 -0600 2.3 @@ -15,20 +15,20 @@ 2.4 using namespace std; 2.5 2.6 #ifdef __linux 2.7 - #include <unistd.h> // for unlink 2.8 - #include <sys/types.h> 2.9 - #include <sys/wait.h> 2.10 +#include <unistd.h> // for unlink 2.11 +#include <sys/types.h> 2.12 +#include <sys/wait.h> 2.13 #endif 2.14 #if (defined(WIN32) && !defined(SDL)) 2.15 - #include <direct.h> 2.16 - #include "../win32/stdafx.h" 2.17 - #include "../win32/Input.h" 2.18 - #include "../win32/MainWnd.h" 2.19 - #include "../win32/VBA.h" 2.20 - #include "../win32/LuaOpenDialog.h" 2.21 +#include <direct.h> 2.22 +#include "../win32/stdafx.h" 2.23 +#include "../win32/Input.h" 2.24 +#include "../win32/MainWnd.h" 2.25 +#include "../win32/VBA.h" 2.26 +#include "../win32/LuaOpenDialog.h" 2.27 #else 2.28 - #define stricmp strcasecmp 2.29 - #define strnicmp strncasecmp 2.30 +#define stricmp strcasecmp 2.31 +#define strnicmp strncasecmp 2.32 #endif 2.33 2.34 #include "../Port.h" 2.35 @@ -64,7 +64,7 @@ 2.36 static int info_uid; 2.37 2.38 #ifndef countof 2.39 - #define countof(a) (sizeof(a) / sizeof(a[0])) 2.40 +#define countof(a) (sizeof(a) / sizeof(a[0])) 2.41 #endif 2.42 2.43 static lua_State *LUA; 2.44 @@ -114,37 +114,37 @@ 2.45 2.46 // Look in inputglobal.h for macros named like BUTTON_MASK_UP to determine the order. 2.47 static const char *button_mappings[] = { 2.48 - "A", "B", "select", "start", "right", "left", "up", "down", "R", "L" 2.49 + "A", "B", "select", "start", "right", "left", "up", "down", "R", "L" 2.50 }; 2.51 2.52 #ifdef _MSC_VER 2.53 - #define snprintf _snprintf 2.54 - #define vscprintf _vscprintf 2.55 +#define snprintf _snprintf 2.56 +#define vscprintf _vscprintf 2.57 #else 2.58 - #define stricmp strcasecmp 2.59 - #define strnicmp strncasecmp 2.60 - #define __forceinline __attribute__((always_inline)) 2.61 +#define stricmp strcasecmp 2.62 +#define strnicmp strncasecmp 2.63 +#define __forceinline __attribute__((always_inline)) 2.64 #endif 2.65 2.66 static const char *luaCallIDStrings[] = 2.67 -{ 2.68 - "CALL_BEFOREEMULATION", 2.69 - "CALL_AFTEREMULATION", 2.70 - "CALL_BEFOREEXIT" 2.71 -}; 2.72 + { 2.73 + "CALL_BEFOREEMULATION", 2.74 + "CALL_AFTEREMULATION", 2.75 + "CALL_BEFOREEXIT" 2.76 + }; 2.77 2.78 //make sure we have the right number of strings 2.79 CTASSERT(sizeof(luaCallIDStrings) / sizeof(*luaCallIDStrings) == LUACALL_COUNT) 2.80 2.81 static const char *luaMemHookTypeStrings [] = 2.82 { 2.83 - "MEMHOOK_WRITE", 2.84 - "MEMHOOK_READ", 2.85 - "MEMHOOK_EXEC", 2.86 - 2.87 - "MEMHOOK_WRITE_SUB", 2.88 - "MEMHOOK_READ_SUB", 2.89 - "MEMHOOK_EXEC_SUB", 2.90 + "MEMHOOK_WRITE", 2.91 + "MEMHOOK_READ", 2.92 + "MEMHOOK_EXEC", 2.93 + 2.94 + "MEMHOOK_WRITE_SUB", 2.95 + "MEMHOOK_READ_SUB", 2.96 + "MEMHOOK_EXEC_SUB", 2.97 }; 2.98 2.99 //make sure we have the right number of strings 2.100 @@ -156,88 +156,88 @@ 2.101 // GBA memory I/O functions copied from win32/MemoryViewerDlg.cpp 2.102 static inline u8 CPUReadByteQuick(u32 addr) 2.103 { 2.104 - return ::map[addr >> 24].address[addr & ::map[addr >> 24].mask]; 2.105 + return ::map[addr >> 24].address[addr & ::map[addr >> 24].mask]; 2.106 } 2.107 2.108 static inline void CPUWriteByteQuick(u32 addr, u8 b) 2.109 { 2.110 - ::map[addr >> 24].address[addr & ::map[addr >> 24].mask] = b; 2.111 + ::map[addr >> 24].address[addr & ::map[addr >> 24].mask] = b; 2.112 } 2.113 2.114 static inline u16 CPUReadHalfWordQuick(u32 addr) 2.115 { 2.116 - return *((u16 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]); 2.117 + return *((u16 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]); 2.118 } 2.119 2.120 static inline void CPUWriteHalfWordQuick(u32 addr, u16 b) 2.121 { 2.122 - *((u16 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]) = b; 2.123 + *((u16 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]) = b; 2.124 } 2.125 2.126 static inline u32 CPUReadMemoryQuick(u32 addr) 2.127 { 2.128 - return *((u32 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]); 2.129 + return *((u32 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]); 2.130 } 2.131 2.132 static inline void CPUWriteMemoryQuick(u32 addr, u32 b) 2.133 { 2.134 - *((u32 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]) = b; 2.135 + *((u32 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]) = b; 2.136 } 2.137 2.138 // GB 2.139 static inline u8 gbReadMemoryQuick8(u16 addr) 2.140 { 2.141 - return gbReadMemoryQuick(addr); 2.142 + return gbReadMemoryQuick(addr); 2.143 } 2.144 2.145 static inline void gbWriteMemoryQuick8(u16 addr, u8 b) 2.146 { 2.147 - gbWriteMemoryQuick(addr, b); 2.148 + gbWriteMemoryQuick(addr, b); 2.149 } 2.150 2.151 static inline u16 gbReadMemoryQuick16(u16 addr) 2.152 { 2.153 - return (gbReadMemoryQuick(addr + 1) << 8) | gbReadMemoryQuick(addr); 2.154 + return (gbReadMemoryQuick(addr + 1) << 8) | gbReadMemoryQuick(addr); 2.155 } 2.156 2.157 static inline void gbWriteMemoryQuick16(u16 addr, u16 b) 2.158 { 2.159 - gbWriteMemoryQuick(addr, b & 0xff); 2.160 - gbWriteMemoryQuick(addr + 1, (b >> 8) & 0xff); 2.161 + gbWriteMemoryQuick(addr, b & 0xff); 2.162 + gbWriteMemoryQuick(addr + 1, (b >> 8) & 0xff); 2.163 } 2.164 2.165 static inline u32 gbReadMemoryQuick32(u16 addr) 2.166 { 2.167 - return (gbReadMemoryQuick(addr + 3) << 24) | 2.168 - (gbReadMemoryQuick(addr + 2) << 16) | 2.169 - (gbReadMemoryQuick(addr + 1) << 8) | 2.170 - gbReadMemoryQuick(addr); 2.171 + return (gbReadMemoryQuick(addr + 3) << 24) | 2.172 + (gbReadMemoryQuick(addr + 2) << 16) | 2.173 + (gbReadMemoryQuick(addr + 1) << 8) | 2.174 + gbReadMemoryQuick(addr); 2.175 } 2.176 2.177 static inline void gbWriteMemoryQuick32(u16 addr, u32 b) 2.178 { 2.179 - gbWriteMemoryQuick(addr, b & 0xff); 2.180 - gbWriteMemoryQuick(addr + 1, (b >> 8) & 0xff); 2.181 - gbWriteMemoryQuick(addr + 2, (b >> 16) & 0xff); 2.182 - gbWriteMemoryQuick(addr + 1, (b >> 24) & 0xff); 2.183 + gbWriteMemoryQuick(addr, b & 0xff); 2.184 + gbWriteMemoryQuick(addr + 1, (b >> 8) & 0xff); 2.185 + gbWriteMemoryQuick(addr + 2, (b >> 16) & 0xff); 2.186 + gbWriteMemoryQuick(addr + 1, (b >> 24) & 0xff); 2.187 } 2.188 2.189 static inline u8 gbReadROMQuick8(u32 addr) 2.190 { 2.191 - return gbReadROMQuick(addr & gbRomSizeMask); 2.192 + return gbReadROMQuick(addr & gbRomSizeMask); 2.193 } 2.194 2.195 static inline u8 gbReadROMQuick16(u32 addr) 2.196 { 2.197 - return (gbReadROMQuick(addr+1 & gbRomSizeMask) << 8) | gbReadROMQuick(addr & gbRomSizeMask); 2.198 + return (gbReadROMQuick(addr+1 & gbRomSizeMask) << 8) | gbReadROMQuick(addr & gbRomSizeMask); 2.199 } 2.200 2.201 static inline u8 gbReadROMQuick32(u32 addr) 2.202 { 2.203 - return (gbReadROMQuick(addr+3 & gbRomSizeMask) << 24) | 2.204 - (gbReadROMQuick(addr+2 & gbRomSizeMask) << 16) | 2.205 - (gbReadROMQuick(addr+1 & gbRomSizeMask) << 8) | 2.206 - gbReadROMQuick(addr & gbRomSizeMask); 2.207 + return (gbReadROMQuick(addr+3 & gbRomSizeMask) << 24) | 2.208 + (gbReadROMQuick(addr+2 & gbRomSizeMask) << 16) | 2.209 + (gbReadROMQuick(addr+1 & gbRomSizeMask) << 8) | 2.210 + gbReadROMQuick(addr & gbRomSizeMask); 2.211 } 2.212 2.213 typedef void (*GetColorFunc)(const uint8 *, uint8 *, uint8 *, uint8 *); 2.214 @@ -245,81 +245,81 @@ 2.215 2.216 static void getColor16(const uint8 *s, uint8 *r, uint8 *g, uint8 *b) 2.217 { 2.218 - u16 v = *(const uint16 *)s; 2.219 - *r = ((v >> systemBlueShift) & 0x001f) << 3; 2.220 - *g = ((v >> systemGreenShift) & 0x001f) << 3; 2.221 - *b = ((v >> systemRedShift) & 0x001f) << 3; 2.222 + u16 v = *(const uint16 *)s; 2.223 + *r = ((v >> systemBlueShift) & 0x001f) << 3; 2.224 + *g = ((v >> systemGreenShift) & 0x001f) << 3; 2.225 + *b = ((v >> systemRedShift) & 0x001f) << 3; 2.226 } 2.227 2.228 static void getColor24(const uint8 *s, uint8 *r, uint8 *g, uint8 *b) 2.229 { 2.230 - if (systemRedShift > systemBlueShift) 2.231 - *b = s[0], *g = s[1], *r = s[2]; 2.232 - else 2.233 - *r = s[0], *g = s[1], *b = s[2]; 2.234 + if (systemRedShift > systemBlueShift) 2.235 + *b = s[0], *g = s[1], *r = s[2]; 2.236 + else 2.237 + *r = s[0], *g = s[1], *b = s[2]; 2.238 } 2.239 2.240 static void getColor32(const uint8 *s, uint8 *r, uint8 *g, uint8 *b) 2.241 { 2.242 - u32 v = *(const uint32 *)s; 2.243 - *b = ((v >> systemBlueShift) & 0x001f) << 3; 2.244 - *g = ((v >> systemGreenShift) & 0x001f) << 3; 2.245 - *r = ((v >> systemRedShift) & 0x001f) << 3; 2.246 + u32 v = *(const uint32 *)s; 2.247 + *b = ((v >> systemBlueShift) & 0x001f) << 3; 2.248 + *g = ((v >> systemGreenShift) & 0x001f) << 3; 2.249 + *r = ((v >> systemRedShift) & 0x001f) << 3; 2.250 } 2.251 2.252 static void setColor16(uint8 *s, uint8 r, uint8 g, uint8 b) 2.253 { 2.254 - *(uint16 *)s = ((b >> 3) & 0x01f) << 2.255 - systemBlueShift | 2.256 - ((g >> 3) & 0x01f) << 2.257 - systemGreenShift | 2.258 - ((r >> 3) & 0x01f) << 2.259 - systemRedShift; 2.260 + *(uint16 *)s = ((b >> 3) & 0x01f) << 2.261 + systemBlueShift | 2.262 + ((g >> 3) & 0x01f) << 2.263 + systemGreenShift | 2.264 + ((r >> 3) & 0x01f) << 2.265 + systemRedShift; 2.266 } 2.267 2.268 static void setColor24(uint8 *s, uint8 r, uint8 g, uint8 b) 2.269 { 2.270 - if (systemRedShift > systemBlueShift) 2.271 - s[0] = b, s[1] = g, s[2] = r; 2.272 - else 2.273 - s[0] = r, s[1] = g, s[2] = b; 2.274 + if (systemRedShift > systemBlueShift) 2.275 + s[0] = b, s[1] = g, s[2] = r; 2.276 + else 2.277 + s[0] = r, s[1] = g, s[2] = b; 2.278 } 2.279 2.280 static void setColor32(uint8 *s, uint8 r, uint8 g, uint8 b) 2.281 { 2.282 - *(uint32 *)s = ((b >> 3) & 0x01f) << 2.283 - systemBlueShift | 2.284 - ((g >> 3) & 0x01f) << 2.285 - systemGreenShift | 2.286 - ((r >> 3) & 0x01f) << 2.287 - systemRedShift; 2.288 + *(uint32 *)s = ((b >> 3) & 0x01f) << 2.289 + systemBlueShift | 2.290 + ((g >> 3) & 0x01f) << 2.291 + systemGreenShift | 2.292 + ((r >> 3) & 0x01f) << 2.293 + systemRedShift; 2.294 } 2.295 2.296 static bool getColorIOFunc(int depth, GetColorFunc *getColor, SetColorFunc *setColor) 2.297 { 2.298 - switch (depth) 2.299 - { 2.300 - case 16: 2.301 - if (getColor) 2.302 - *getColor = getColor16; 2.303 - if (setColor) 2.304 - *setColor = setColor16; 2.305 - return true; 2.306 - case 24: 2.307 - if (getColor) 2.308 - *getColor = getColor24; 2.309 - if (setColor) 2.310 - *setColor = setColor24; 2.311 - return true; 2.312 - case 32: 2.313 - if (getColor) 2.314 - *getColor = getColor32; 2.315 - if (setColor) 2.316 - *setColor = setColor32; 2.317 - return true; 2.318 - default: 2.319 - return false; 2.320 - } 2.321 + switch (depth) 2.322 + { 2.323 + case 16: 2.324 + if (getColor) 2.325 + *getColor = getColor16; 2.326 + if (setColor) 2.327 + *setColor = setColor16; 2.328 + return true; 2.329 + case 24: 2.330 + if (getColor) 2.331 + *getColor = getColor24; 2.332 + if (setColor) 2.333 + *setColor = setColor24; 2.334 + return true; 2.335 + case 32: 2.336 + if (getColor) 2.337 + *getColor = getColor32; 2.338 + if (setColor) 2.339 + *setColor = setColor32; 2.340 + return true; 2.341 + default: 2.342 + return false; 2.343 + } 2.344 } 2.345 2.346 /** 2.347 @@ -327,11 +327,11 @@ 2.348 */ 2.349 static void VBALuaOnStop(void) 2.350 { 2.351 - luaRunning = false; 2.352 - lua_joypads_used = 0; 2.353 - gui_used = false; 2.354 - //if (wasPaused) 2.355 - // systemSetPause(true); 2.356 + luaRunning = false; 2.357 + lua_joypads_used = 0; 2.358 + gui_used = false; 2.359 + //if (wasPaused) 2.360 + // systemSetPause(true); 2.361 } 2.362 2.363 /** 2.364 @@ -342,41 +342,41 @@ 2.365 */ 2.366 int VBALuaSpeed(void) 2.367 { 2.368 - if (!LUA || !luaRunning) 2.369 - return 0; 2.370 - 2.371 - //printf("%d\n", speedmode); 2.372 - switch (speedmode) 2.373 - { 2.374 - /* 2.375 - case SPEED_NORMAL: 2.376 - return 0; 2.377 - case SPEED_NOTHROTTLE: 2.378 - IPPU.RenderThisFrame = true; 2.379 - return 1; 2.380 - 2.381 - case SPEED_TURBO: 2.382 - IPPU.SkippedFrames++; 2.383 - if (IPPU.SkippedFrames >= 40) { 2.384 - IPPU.SkippedFrames = 0; 2.385 - IPPU.RenderThisFrame = true; 2.386 - } 2.387 - else 2.388 - IPPU.RenderThisFrame = false; 2.389 - return 1; 2.390 - 2.391 - // In mode 3, SkippedFrames is set to zero so that the frame 2.392 - // skipping code doesn't try anything funny. 2.393 - case SPEED_MAXIMUM: 2.394 - IPPU.SkippedFrames=0; 2.395 - IPPU.RenderThisFrame = false; 2.396 - return 1; 2.397 - */ 2.398 - case 0: // FIXME: to get rid of the warning 2.399 - default: 2.400 - assert(false); 2.401 - return 0; 2.402 + if (!LUA || !luaRunning) 2.403 + return 0; 2.404 + 2.405 + //printf("%d\n", speedmode); 2.406 + switch (speedmode) 2.407 + { 2.408 + /* 2.409 + case SPEED_NORMAL: 2.410 + return 0; 2.411 + case SPEED_NOTHROTTLE: 2.412 + IPPU.RenderThisFrame = true; 2.413 + return 1; 2.414 + 2.415 + case SPEED_TURBO: 2.416 + IPPU.SkippedFrames++; 2.417 + if (IPPU.SkippedFrames >= 40) { 2.418 + IPPU.SkippedFrames = 0; 2.419 + IPPU.RenderThisFrame = true; 2.420 } 2.421 + else 2.422 + IPPU.RenderThisFrame = false; 2.423 + return 1; 2.424 + 2.425 + // In mode 3, SkippedFrames is set to zero so that the frame 2.426 + // skipping code doesn't try anything funny. 2.427 + case SPEED_MAXIMUM: 2.428 + IPPU.SkippedFrames=0; 2.429 + IPPU.RenderThisFrame = false; 2.430 + return 1; 2.431 + */ 2.432 + case 0: // FIXME: to get rid of the warning 2.433 + default: 2.434 + assert(false); 2.435 + return 0; 2.436 + } 2.437 } 2.438 2.439 /////////////////////////// 2.440 @@ -390,29 +390,29 @@ 2.441 // maximum renders no frames 2.442 static int vba_speedmode(lua_State *L) 2.443 { 2.444 - const char *mode = luaL_checkstring(L, 1); 2.445 - 2.446 - if (strcasecmp(mode, "normal") == 0) 2.447 - { 2.448 - speedmode = SPEED_NORMAL; 2.449 - } 2.450 - else if (strcasecmp(mode, "nothrottle") == 0) 2.451 - { 2.452 - speedmode = SPEED_NOTHROTTLE; 2.453 - } 2.454 - else if (strcasecmp(mode, "turbo") == 0) 2.455 - { 2.456 - speedmode = SPEED_TURBO; 2.457 - } 2.458 - else if (strcasecmp(mode, "maximum") == 0) 2.459 - { 2.460 - speedmode = SPEED_MAXIMUM; 2.461 - } 2.462 - else 2.463 - luaL_error(L, "Invalid mode %s to vba.speedmode", mode); 2.464 - 2.465 - //printf("new speed mode: %d\n", speedmode); 2.466 - return 0; 2.467 + const char *mode = luaL_checkstring(L, 1); 2.468 + 2.469 + if (strcasecmp(mode, "normal") == 0) 2.470 + { 2.471 + speedmode = SPEED_NORMAL; 2.472 + } 2.473 + else if (strcasecmp(mode, "nothrottle") == 0) 2.474 + { 2.475 + speedmode = SPEED_NOTHROTTLE; 2.476 + } 2.477 + else if (strcasecmp(mode, "turbo") == 0) 2.478 + { 2.479 + speedmode = SPEED_TURBO; 2.480 + } 2.481 + else if (strcasecmp(mode, "maximum") == 0) 2.482 + { 2.483 + speedmode = SPEED_MAXIMUM; 2.484 + } 2.485 + else 2.486 + luaL_error(L, "Invalid mode %s to vba.speedmode", mode); 2.487 + 2.488 + //printf("new speed mode: %d\n", speedmode); 2.489 + return 0; 2.490 } 2.491 2.492 // vba.frameadvnace() 2.493 @@ -422,18 +422,18 @@ 2.494 // when we break out. 2.495 static int vba_frameadvance(lua_State *L) 2.496 { 2.497 - // We're going to sleep for a frame-advance. Take notes. 2.498 - if (frameAdvanceWaiting) 2.499 - return luaL_error(L, "can't call vba.frameadvance() from here"); 2.500 - 2.501 - frameAdvanceWaiting = true; 2.502 - 2.503 - // Don't do this! The user won't like us sending their emulator out of control! 2.504 - // Settings.FrameAdvance = true; 2.505 - // Now we can yield to the main 2.506 - return lua_yield(L, 0); 2.507 - 2.508 - // It's actually rather disappointing... 2.509 + // We're going to sleep for a frame-advance. Take notes. 2.510 + if (frameAdvanceWaiting) 2.511 + return luaL_error(L, "can't call vba.frameadvance() from here"); 2.512 + 2.513 + frameAdvanceWaiting = true; 2.514 + 2.515 + // Don't do this! The user won't like us sending their emulator out of control! 2.516 + // Settings.FrameAdvance = true; 2.517 + // Now we can yield to the main 2.518 + return lua_yield(L, 0); 2.519 + 2.520 + // It's actually rather disappointing... 2.521 } 2.522 2.523 // vba.pause() 2.524 @@ -444,62 +444,62 @@ 2.525 // finishes executing anwyays. In this case, the function returns immediately. 2.526 static int vba_pause(lua_State *L) 2.527 { 2.528 - systemSetPause(true); 2.529 - speedmode = SPEED_NORMAL; 2.530 - 2.531 - // Return control if we're midway through a frame. We can't pause here. 2.532 - if (frameAdvanceWaiting) 2.533 - { 2.534 - return 0; 2.535 - } 2.536 - 2.537 - // If it's on a frame boundary, we also yield. 2.538 - frameAdvanceWaiting = true; 2.539 - return lua_yield(L, 0); 2.540 + systemSetPause(true); 2.541 + speedmode = SPEED_NORMAL; 2.542 + 2.543 + // Return control if we're midway through a frame. We can't pause here. 2.544 + if (frameAdvanceWaiting) 2.545 + { 2.546 + return 0; 2.547 + } 2.548 + 2.549 + // If it's on a frame boundary, we also yield. 2.550 + frameAdvanceWaiting = true; 2.551 + return lua_yield(L, 0); 2.552 } 2.553 2.554 static int vba_registerbefore(lua_State *L) 2.555 { 2.556 - if (!lua_isnil(L, 1)) 2.557 - luaL_checktype(L, 1, LUA_TFUNCTION); 2.558 - lua_settop(L, 1); 2.559 - lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEMULATION]); 2.560 - lua_insert(L, 1); 2.561 - lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEMULATION]); 2.562 - 2.563 - //StopScriptIfFinished(luaStateToUIDMap[L]); 2.564 - return 1; 2.565 + if (!lua_isnil(L, 1)) 2.566 + luaL_checktype(L, 1, LUA_TFUNCTION); 2.567 + lua_settop(L, 1); 2.568 + lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEMULATION]); 2.569 + lua_insert(L, 1); 2.570 + lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEMULATION]); 2.571 + 2.572 + //StopScriptIfFinished(luaStateToUIDMap[L]); 2.573 + return 1; 2.574 } 2.575 2.576 static int vba_registerafter(lua_State *L) 2.577 { 2.578 - if (!lua_isnil(L, 1)) 2.579 - luaL_checktype(L, 1, LUA_TFUNCTION); 2.580 - lua_settop(L, 1); 2.581 - lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_AFTEREMULATION]); 2.582 - lua_insert(L, 1); 2.583 - lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_AFTEREMULATION]); 2.584 - 2.585 - //StopScriptIfFinished(luaStateToUIDMap[L]); 2.586 - return 1; 2.587 + if (!lua_isnil(L, 1)) 2.588 + luaL_checktype(L, 1, LUA_TFUNCTION); 2.589 + lua_settop(L, 1); 2.590 + lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_AFTEREMULATION]); 2.591 + lua_insert(L, 1); 2.592 + lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_AFTEREMULATION]); 2.593 + 2.594 + //StopScriptIfFinished(luaStateToUIDMap[L]); 2.595 + return 1; 2.596 } 2.597 2.598 static int vba_registerexit(lua_State *L) 2.599 { 2.600 - if (!lua_isnil(L, 1)) 2.601 - luaL_checktype(L, 1, LUA_TFUNCTION); 2.602 - lua_settop(L, 1); 2.603 - lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEXIT]); 2.604 - lua_insert(L, 1); 2.605 - lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEXIT]); 2.606 - 2.607 - //StopScriptIfFinished(luaStateToUIDMap[L]); 2.608 - return 1; 2.609 + if (!lua_isnil(L, 1)) 2.610 + luaL_checktype(L, 1, LUA_TFUNCTION); 2.611 + lua_settop(L, 1); 2.612 + lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEXIT]); 2.613 + lua_insert(L, 1); 2.614 + lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEXIT]); 2.615 + 2.616 + //StopScriptIfFinished(luaStateToUIDMap[L]); 2.617 + return 1; 2.618 } 2.619 2.620 static inline bool isalphaorunderscore(char c) 2.621 { 2.622 - return isalpha(c) || c == '_'; 2.623 + return isalpha(c) || c == '_'; 2.624 } 2.625 2.626 static std::vector<const void *> s_tableAddressStack; // prevents infinite recursion of a table within a table (when cycle is 2.627 @@ -512,541 +512,541 @@ 2.628 #define END ); if (_n >= 0) { ptr += _n; remaining -= _n; } else { remaining = 0; } } 2.629 static void toCStringConverter(lua_State *L, int i, char * &ptr, int &remaining) 2.630 { 2.631 - if (remaining <= 0) 2.632 - return; 2.633 - 2.634 - const char *str = ptr; // for debugging 2.635 - 2.636 - // if there is a __tostring metamethod then call it 2.637 - int usedMeta = luaL_callmeta(L, i, "__tostring"); 2.638 - if (usedMeta) 2.639 + if (remaining <= 0) 2.640 + return; 2.641 + 2.642 + const char *str = ptr; // for debugging 2.643 + 2.644 + // if there is a __tostring metamethod then call it 2.645 + int usedMeta = luaL_callmeta(L, i, "__tostring"); 2.646 + if (usedMeta) 2.647 { 2.648 - std::vector<const void *>::const_iterator foundCycleIter = std::find(s_metacallStack.begin(), s_metacallStack.end(), lua_topointer(L, i)); 2.649 - if (foundCycleIter != s_metacallStack.end()) 2.650 + std::vector<const void *>::const_iterator foundCycleIter = std::find(s_metacallStack.begin(), s_metacallStack.end(), lua_topointer(L, i)); 2.651 + if (foundCycleIter != s_metacallStack.end()) 2.652 { 2.653 - lua_pop(L, 1); 2.654 - usedMeta = false; 2.655 - } 2.656 - else 2.657 + lua_pop(L, 1); 2.658 + usedMeta = false; 2.659 + } 2.660 + else 2.661 { 2.662 - s_metacallStack.push_back(lua_topointer(L, i)); 2.663 - i = lua_gettop(L); 2.664 - } 2.665 + s_metacallStack.push_back(lua_topointer(L, i)); 2.666 + i = lua_gettop(L); 2.667 } 2.668 - 2.669 - switch (lua_type(L, i)) 2.670 + } 2.671 + 2.672 + switch (lua_type(L, i)) 2.673 { 2.674 - case LUA_TNONE: 2.675 - break; 2.676 - case LUA_TNIL: 2.677 - APPENDPRINT "nil" END break; 2.678 - case LUA_TBOOLEAN: 2.679 - APPENDPRINT lua_toboolean(L, i) ? "true" : "false" END break; 2.680 - case LUA_TSTRING : APPENDPRINT "%s", lua_tostring(L, i) END break; 2.681 - case LUA_TNUMBER: 2.682 - APPENDPRINT "%.12Lg", lua_tonumber(L, i) END break; 2.683 - case LUA_TFUNCTION: 2.684 - if ((L->base + i - 1)->value.gc->cl.c.isC) 2.685 - { 2.686 - //lua_CFunction func = lua_tocfunction(L, i); 2.687 - //std::map<lua_CFunction, const char*>::iterator iter = s_cFuncInfoMap.find(func); 2.688 - //if(iter == s_cFuncInfoMap.end()) 2.689 - goto defcase; 2.690 - //APPENDPRINT "function(%s)", iter->second END 2.691 - } 2.692 + case LUA_TNONE: 2.693 + break; 2.694 + case LUA_TNIL: 2.695 + APPENDPRINT "nil" END break; 2.696 + case LUA_TBOOLEAN: 2.697 + APPENDPRINT lua_toboolean(L, i) ? "true" : "false" END break; 2.698 + case LUA_TSTRING : APPENDPRINT "%s", lua_tostring(L, i) END break; 2.699 + case LUA_TNUMBER: 2.700 + APPENDPRINT "%.12Lg", lua_tonumber(L, i) END break; 2.701 + case LUA_TFUNCTION: 2.702 + if ((L->base + i - 1)->value.gc->cl.c.isC) 2.703 + { 2.704 + //lua_CFunction func = lua_tocfunction(L, i); 2.705 + //std::map<lua_CFunction, const char*>::iterator iter = s_cFuncInfoMap.find(func); 2.706 + //if(iter == s_cFuncInfoMap.end()) 2.707 + goto defcase; 2.708 + //APPENDPRINT "function(%s)", iter->second END 2.709 + } 2.710 + else 2.711 + { 2.712 + APPENDPRINT "function(" END 2.713 + Proto * p = (L->base + i - 1)->value.gc->cl.l.p; 2.714 + int numParams = p->numparams + (p->is_vararg ? 1 : 0); 2.715 + for (int n = 0; n < p->numparams; n++) 2.716 + { 2.717 + APPENDPRINT "%s", getstr(p->locvars[n].varname) END 2.718 + if (n != numParams - 1) 2.719 + APPENDPRINT "," END 2.720 + } 2.721 + if (p->is_vararg) 2.722 + APPENDPRINT "..." END 2.723 + APPENDPRINT ")" END 2.724 + } 2.725 + break; 2.726 + defcase: default: 2.727 + APPENDPRINT "%s:%p", luaL_typename(L, i), lua_topointer(L, i) END break; 2.728 + case LUA_TTABLE: 2.729 + { 2.730 + // first make sure there's enough stack space 2.731 + if (!lua_checkstack(L, 4)) 2.732 + { 2.733 + // note that even if lua_checkstack never returns false, 2.734 + // that doesn't mean we didn't need to call it, 2.735 + // because calling it retrieves stack space past LUA_MINSTACK 2.736 + goto defcase; 2.737 + } 2.738 + 2.739 + std::vector<const void *>::const_iterator foundCycleIter = 2.740 + std::find(s_tableAddressStack.begin(), s_tableAddressStack.end(), lua_topointer(L, i)); 2.741 + if (foundCycleIter != s_tableAddressStack.end()) 2.742 + { 2.743 + int parentNum = s_tableAddressStack.end() - foundCycleIter; 2.744 + if (parentNum > 1) 2.745 + APPENDPRINT "%s:parent^%d", luaL_typename(L, i), parentNum END 2.746 + else 2.747 + APPENDPRINT "%s:parent", luaL_typename(L, i) END 2.748 + } 2.749 + else 2.750 + { 2.751 + s_tableAddressStack.push_back(lua_topointer(L, i)); 2.752 + struct Scope { ~Scope(){ s_tableAddressStack. pop_back(); } } scope; 2.753 + 2.754 + APPENDPRINT "{" END 2.755 + 2.756 + lua_pushnil(L); // first key 2.757 + int keyIndex = lua_gettop(L); 2.758 + int valueIndex = keyIndex + 1; 2.759 + bool first = true; 2.760 + bool skipKey = true; // true if we're still in the "array part" of the table 2.761 + lua_Number arrayIndex = (lua_Number)0; 2.762 + while (lua_next(L, i)) 2.763 + { 2.764 + if (first) 2.765 + first = false; 2.766 else 2.767 - { 2.768 - APPENDPRINT "function(" END 2.769 - Proto * p = (L->base + i - 1)->value.gc->cl.l.p; 2.770 - int numParams = p->numparams + (p->is_vararg ? 1 : 0); 2.771 - for (int n = 0; n < p->numparams; n++) 2.772 - { 2.773 - APPENDPRINT "%s", getstr(p->locvars[n].varname) END 2.774 - if (n != numParams - 1) 2.775 - APPENDPRINT "," END 2.776 - } 2.777 - if (p->is_vararg) 2.778 - APPENDPRINT "..." END 2.779 - APPENDPRINT ")" END 2.780 - } 2.781 - break; 2.782 -defcase: default: 2.783 - APPENDPRINT "%s:%p", luaL_typename(L, i), lua_topointer(L, i) END break; 2.784 - case LUA_TTABLE: 2.785 - { 2.786 - // first make sure there's enough stack space 2.787 - if (!lua_checkstack(L, 4)) 2.788 - { 2.789 - // note that even if lua_checkstack never returns false, 2.790 - // that doesn't mean we didn't need to call it, 2.791 - // because calling it retrieves stack space past LUA_MINSTACK 2.792 - goto defcase; 2.793 - } 2.794 - 2.795 - std::vector<const void *>::const_iterator foundCycleIter = 2.796 - std::find(s_tableAddressStack.begin(), s_tableAddressStack.end(), lua_topointer(L, i)); 2.797 - if (foundCycleIter != s_tableAddressStack.end()) 2.798 - { 2.799 - int parentNum = s_tableAddressStack.end() - foundCycleIter; 2.800 - if (parentNum > 1) 2.801 - APPENDPRINT "%s:parent^%d", luaL_typename(L, i), parentNum END 2.802 - else 2.803 - APPENDPRINT "%s:parent", luaL_typename(L, i) END 2.804 - } 2.805 - else 2.806 - { 2.807 - s_tableAddressStack.push_back(lua_topointer(L, i)); 2.808 - struct Scope { ~Scope(){ s_tableAddressStack. pop_back(); } } scope; 2.809 - 2.810 - APPENDPRINT "{" END 2.811 - 2.812 - lua_pushnil(L); // first key 2.813 - int keyIndex = lua_gettop(L); 2.814 - int valueIndex = keyIndex + 1; 2.815 - bool first = true; 2.816 - bool skipKey = true; // true if we're still in the "array part" of the table 2.817 - lua_Number arrayIndex = (lua_Number)0; 2.818 - while (lua_next(L, i)) 2.819 - { 2.820 - if (first) 2.821 - first = false; 2.822 - else 2.823 - APPENDPRINT ", " END 2.824 - if (skipKey) 2.825 - { 2.826 - arrayIndex += (lua_Number)1; 2.827 - bool keyIsNumber = (lua_type(L, keyIndex) == LUA_TNUMBER); 2.828 - skipKey = keyIsNumber && (lua_tonumber(L, keyIndex) == arrayIndex); 2.829 - } 2.830 - if (!skipKey) 2.831 - { 2.832 - bool keyIsString = (lua_type(L, keyIndex) == LUA_TSTRING); 2.833 - bool invalidLuaIdentifier = (!keyIsString || !isalphaorunderscore(*lua_tostring(L, keyIndex))); 2.834 - if (invalidLuaIdentifier) 2.835 - if (keyIsString) 2.836 - APPENDPRINT "['" END 2.837 - else 2.838 - APPENDPRINT "[" END 2.839 - 2.840 - toCStringConverter(L, keyIndex, ptr, remaining); 2.841 - // key 2.842 - 2.843 - if (invalidLuaIdentifier) 2.844 - if (keyIsString) 2.845 - APPENDPRINT "']=" END 2.846 - else 2.847 - APPENDPRINT "]=" END 2.848 - else 2.849 - APPENDPRINT "=" END 2.850 - } 2.851 - 2.852 - bool valueIsString = (lua_type(L, valueIndex) == LUA_TSTRING); 2.853 - if (valueIsString) 2.854 - APPENDPRINT "'" END 2.855 - 2.856 - toCStringConverter(L, valueIndex, ptr, remaining); // value 2.857 - 2.858 - if (valueIsString) 2.859 - APPENDPRINT "'" END 2.860 - 2.861 - lua_pop(L, 1); 2.862 - 2.863 - if (remaining <= 0) 2.864 - { 2.865 - lua_settop(L, keyIndex - 1); // stack might not be clean yet if we're breaking 2.866 - // early 2.867 - break; 2.868 - } 2.869 - } 2.870 - APPENDPRINT "}" END 2.871 - } 2.872 - } 2.873 - break; 2.874 - } 2.875 - 2.876 - if (usedMeta) 2.877 - { 2.878 - s_metacallStack.pop_back(); 2.879 - lua_pop(L, 1); 2.880 - } 2.881 - } 2.882 - 2.883 - static const int s_tempStrMaxLen = 64 * 1024; 2.884 - static char s_tempStr [s_tempStrMaxLen]; 2.885 - 2.886 - static char *rawToCString(lua_State *L, int idx) 2.887 - { 2.888 - int a = idx > 0 ? idx : 1; 2.889 - int n = idx > 0 ? idx : lua_gettop(L); 2.890 - 2.891 - char *ptr = s_tempStr; 2.892 - *ptr = 0; 2.893 - 2.894 - int remaining = s_tempStrMaxLen; 2.895 - for (int i = a; i <= n; i++) 2.896 - { 2.897 - toCStringConverter(L, i, ptr, remaining); 2.898 - if (i != n) 2.899 - APPENDPRINT " " END 2.900 - } 2.901 - 2.902 - if (remaining < 3) 2.903 - { 2.904 - while (remaining < 6) 2.905 - remaining++, ptr--; 2.906 - APPENDPRINT "..." END 2.907 - } 2.908 - APPENDPRINT "\r\n" END 2.909 - // the trailing newline is so print() can avoid having to do wasteful things to print its newline 2.910 - // (string copying would be wasteful and calling info.print() twice can be extremely slow) 2.911 - // at the cost of functions that don't want the newline needing to trim off the last two characters 2.912 - // (which is a very fast operation and thus acceptable in this case) 2.913 - 2.914 - return s_tempStr; 2.915 - } 2.916 + APPENDPRINT ", " END 2.917 + if (skipKey) 2.918 + { 2.919 + arrayIndex += (lua_Number)1; 2.920 + bool keyIsNumber = (lua_type(L, keyIndex) == LUA_TNUMBER); 2.921 + skipKey = keyIsNumber && (lua_tonumber(L, keyIndex) == arrayIndex); 2.922 + } 2.923 + if (!skipKey) 2.924 + { 2.925 + bool keyIsString = (lua_type(L, keyIndex) == LUA_TSTRING); 2.926 + bool invalidLuaIdentifier = (!keyIsString || !isalphaorunderscore(*lua_tostring(L, keyIndex))); 2.927 + if (invalidLuaIdentifier) 2.928 + if (keyIsString) 2.929 + APPENDPRINT "['" END 2.930 + else 2.931 + APPENDPRINT "[" END 2.932 + 2.933 + toCStringConverter(L, keyIndex, ptr, remaining); 2.934 + // key 2.935 + 2.936 + if (invalidLuaIdentifier) 2.937 + if (keyIsString) 2.938 + APPENDPRINT "']=" END 2.939 + else 2.940 + APPENDPRINT "]=" END 2.941 + else 2.942 + APPENDPRINT "=" END 2.943 + } 2.944 + 2.945 + bool valueIsString = (lua_type(L, valueIndex) == LUA_TSTRING); 2.946 + if (valueIsString) 2.947 + APPENDPRINT "'" END 2.948 + 2.949 + toCStringConverter(L, valueIndex, ptr, remaining); // value 2.950 + 2.951 + if (valueIsString) 2.952 + APPENDPRINT "'" END 2.953 + 2.954 + lua_pop(L, 1); 2.955 + 2.956 + if (remaining <= 0) 2.957 + { 2.958 + lua_settop(L, keyIndex - 1); // stack might not be clean yet if we're breaking 2.959 + // early 2.960 + break; 2.961 + } 2.962 + } 2.963 + APPENDPRINT "}" END 2.964 + } 2.965 + } 2.966 + break; 2.967 + } 2.968 + 2.969 + if (usedMeta) 2.970 + { 2.971 + s_metacallStack.pop_back(); 2.972 + lua_pop(L, 1); 2.973 + } 2.974 +} 2.975 + 2.976 +static const int s_tempStrMaxLen = 64 * 1024; 2.977 +static char s_tempStr [s_tempStrMaxLen]; 2.978 + 2.979 +static char *rawToCString(lua_State *L, int idx) 2.980 +{ 2.981 + int a = idx > 0 ? idx : 1; 2.982 + int n = idx > 0 ? idx : lua_gettop(L); 2.983 + 2.984 + char *ptr = s_tempStr; 2.985 + *ptr = 0; 2.986 + 2.987 + int remaining = s_tempStrMaxLen; 2.988 + for (int i = a; i <= n; i++) 2.989 + { 2.990 + toCStringConverter(L, i, ptr, remaining); 2.991 + if (i != n) 2.992 + APPENDPRINT " " END 2.993 + } 2.994 + 2.995 + if (remaining < 3) 2.996 + { 2.997 + while (remaining < 6) 2.998 + remaining++, ptr--; 2.999 + APPENDPRINT "..." END 2.1000 + } 2.1001 + APPENDPRINT "\r\n" END 2.1002 + // the trailing newline is so print() can avoid having to do wasteful things to print its newline 2.1003 + // (string copying would be wasteful and calling info.print() twice can be extremely slow) 2.1004 + // at the cost of functions that don't want the newline needing to trim off the last two characters 2.1005 + // (which is a very fast operation and thus acceptable in this case) 2.1006 + 2.1007 + return s_tempStr; 2.1008 +} 2.1009 #undef APPENDPRINT 2.1010 #undef END 2.1011 2.1012 // replacement for luaB_tostring() that is able to show the contents of tables (and formats numbers better, and show function 2.1013 // prototypes) 2.1014 // can be called directly from lua via tostring(), assuming tostring hasn't been reassigned 2.1015 - static int tostring(lua_State *L) 2.1016 - { 2.1017 - char *str = rawToCString(L); 2.1018 - str[strlen(str) - 2] = 0; // hack: trim off the \r\n (which is there to simplify the print function's 2.1019 - // task) 2.1020 - lua_pushstring(L, str); 2.1021 - return 1; 2.1022 - } 2.1023 +static int tostring(lua_State *L) 2.1024 +{ 2.1025 + char *str = rawToCString(L); 2.1026 + str[strlen(str) - 2] = 0; // hack: trim off the \r\n (which is there to simplify the print function's 2.1027 + // task) 2.1028 + lua_pushstring(L, str); 2.1029 + return 1; 2.1030 +} 2.1031 2.1032 // like rawToCString, but will check if the global Lua function tostring() 2.1033 // has been replaced with a custom function, and call that instead if so 2.1034 - static const char *toCString(lua_State *L, int idx) 2.1035 - { 2.1036 - int a = idx > 0 ? idx : 1; 2.1037 - int n = idx > 0 ? idx : lua_gettop(L); 2.1038 - lua_getglobal(L, "tostring"); 2.1039 - lua_CFunction cf = lua_tocfunction(L, -1); 2.1040 - if (cf == tostring || lua_isnil(L, -1)) // optimization: if using our own C tostring function, we can 2.1041 - // bypass the call through Lua and all the string object 2.1042 - // allocation that would entail 2.1043 - { 2.1044 - lua_pop(L, 1); 2.1045 - return rawToCString(L, idx); 2.1046 - } 2.1047 - else // if the user overrided the tostring function, we have to actually call it and store the 2.1048 - // temporarily allocated string it returns 2.1049 - { 2.1050 - lua_pushstring(L, ""); 2.1051 - for (int i = a; i <= n; i++) 2.1052 - { 2.1053 - lua_pushvalue(L, -2); // function to be called 2.1054 - lua_pushvalue(L, i); // value to print 2.1055 - lua_call(L, 1, 1); 2.1056 - if (lua_tostring(L, -1) == NULL) 2.1057 - luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("print")); 2.1058 - lua_pushstring(L, (i < n) ? " " : "\r\n"); 2.1059 - lua_concat(L, 3); 2.1060 - } 2.1061 - const char *str = lua_tostring(L, -1); 2.1062 - strncpy(s_tempStr, str, s_tempStrMaxLen); 2.1063 - s_tempStr[s_tempStrMaxLen - 1] = 0; 2.1064 - lua_pop(L, 2); 2.1065 - return s_tempStr; 2.1066 - } 2.1067 - } 2.1068 +static const char *toCString(lua_State *L, int idx) 2.1069 +{ 2.1070 + int a = idx > 0 ? idx : 1; 2.1071 + int n = idx > 0 ? idx : lua_gettop(L); 2.1072 + lua_getglobal(L, "tostring"); 2.1073 + lua_CFunction cf = lua_tocfunction(L, -1); 2.1074 + if (cf == tostring || lua_isnil(L, -1)) // optimization: if using our own C tostring function, we can 2.1075 + // bypass the call through Lua and all the string object 2.1076 + // allocation that would entail 2.1077 + { 2.1078 + lua_pop(L, 1); 2.1079 + return rawToCString(L, idx); 2.1080 + } 2.1081 + else // if the user overrided the tostring function, we have to actually call it and store the 2.1082 + // temporarily allocated string it returns 2.1083 + { 2.1084 + lua_pushstring(L, ""); 2.1085 + for (int i = a; i <= n; i++) 2.1086 + { 2.1087 + lua_pushvalue(L, -2); // function to be called 2.1088 + lua_pushvalue(L, i); // value to print 2.1089 + lua_call(L, 1, 1); 2.1090 + if (lua_tostring(L, -1) == NULL) 2.1091 + luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("print")); 2.1092 + lua_pushstring(L, (i < n) ? " " : "\r\n"); 2.1093 + lua_concat(L, 3); 2.1094 + } 2.1095 + const char *str = lua_tostring(L, -1); 2.1096 + strncpy(s_tempStr, str, s_tempStrMaxLen); 2.1097 + s_tempStr[s_tempStrMaxLen - 1] = 0; 2.1098 + lua_pop(L, 2); 2.1099 + return s_tempStr; 2.1100 + } 2.1101 +} 2.1102 2.1103 // replacement for luaB_print() that goes to the appropriate textbox instead of stdout 2.1104 - static int print(lua_State *L) 2.1105 - { 2.1106 - const char *str = toCString(L); 2.1107 - 2.1108 - int uid = info_uid; //luaStateToUIDMap[L->l_G->mainthread]; 2.1109 - //LuaContextInfo& info = GetCurrentInfo(); 2.1110 - 2.1111 - if (info_print) 2.1112 - info_print(uid, str); 2.1113 - else 2.1114 - puts(str); 2.1115 - 2.1116 - //worry(L, 100); 2.1117 - return 0; 2.1118 - } 2.1119 - 2.1120 - static int printerror(lua_State *L, int idx) 2.1121 - { 2.1122 - lua_checkstack(L, lua_gettop(L) + 4); 2.1123 - 2.1124 - if (idx < 0) 2.1125 - idx = lua_gettop(L) + 1 + idx; 2.1126 - 2.1127 - const char *str = rawToCString(L, idx); 2.1128 - 2.1129 - int uid = info_uid; //luaStateToUIDMap[L->l_G->mainthread]; 2.1130 - //LuaContextInfo& info = GetCurrentInfo(); 2.1131 - 2.1132 - if (info_print) 2.1133 - info_print(uid, str); 2.1134 - else 2.1135 - fputs(str, stderr); 2.1136 - 2.1137 - //worry(L, 100); 2.1138 - return 0; 2.1139 - } 2.1140 +static int print(lua_State *L) 2.1141 +{ 2.1142 + const char *str = toCString(L); 2.1143 + 2.1144 + int uid = info_uid; //luaStateToUIDMap[L->l_G->mainthread]; 2.1145 + //LuaContextInfo& info = GetCurrentInfo(); 2.1146 + 2.1147 + if (info_print) 2.1148 + info_print(uid, str); 2.1149 + else 2.1150 + puts(str); 2.1151 + 2.1152 + //worry(L, 100); 2.1153 + return 0; 2.1154 +} 2.1155 + 2.1156 +static int printerror(lua_State *L, int idx) 2.1157 +{ 2.1158 + lua_checkstack(L, lua_gettop(L) + 4); 2.1159 + 2.1160 + if (idx < 0) 2.1161 + idx = lua_gettop(L) + 1 + idx; 2.1162 + 2.1163 + const char *str = rawToCString(L, idx); 2.1164 + 2.1165 + int uid = info_uid; //luaStateToUIDMap[L->l_G->mainthread]; 2.1166 + //LuaContextInfo& info = GetCurrentInfo(); 2.1167 + 2.1168 + if (info_print) 2.1169 + info_print(uid, str); 2.1170 + else 2.1171 + fputs(str, stderr); 2.1172 + 2.1173 + //worry(L, 100); 2.1174 + return 0; 2.1175 +} 2.1176 2.1177 // vba.message(string msg) 2.1178 // 2.1179 // Displays the given message on the screen. 2.1180 - static int vba_message(lua_State *L) 2.1181 - { 2.1182 - const char *msg = luaL_checkstring(L, 1); 2.1183 - systemScreenMessage(msg); 2.1184 - 2.1185 - return 0; 2.1186 - } 2.1187 +static int vba_message(lua_State *L) 2.1188 +{ 2.1189 + const char *msg = luaL_checkstring(L, 1); 2.1190 + systemScreenMessage(msg); 2.1191 + 2.1192 + return 0; 2.1193 +} 2.1194 2.1195 // provides an easy way to copy a table from Lua 2.1196 // (simple assignment only makes an alias, but sometimes an independent table is desired) 2.1197 // currently this function only performs a shallow copy, 2.1198 // but I think it should be changed to do a deep copy (possibly of configurable depth?) 2.1199 // that maintains the internal table reference structure 2.1200 - static int copytable(lua_State *L) 2.1201 - { 2.1202 - int origIndex = 1; // we only care about the first argument 2.1203 - int origType = lua_type(L, origIndex); 2.1204 - if (origType == LUA_TNIL) 2.1205 - { 2.1206 - lua_pushnil(L); 2.1207 - return 1; 2.1208 - } 2.1209 - if (origType != LUA_TTABLE) 2.1210 - { 2.1211 - luaL_typerror(L, 1, lua_typename(L, LUA_TTABLE)); 2.1212 - lua_pushnil(L); 2.1213 - return 1; 2.1214 - } 2.1215 - 2.1216 - lua_createtable(L, lua_objlen(L, 1), 0); 2.1217 - int copyIndex = lua_gettop(L); 2.1218 - 2.1219 - lua_pushnil(L); // first key 2.1220 - int keyIndex = lua_gettop(L); 2.1221 - int valueIndex = keyIndex + 1; 2.1222 - 2.1223 - while (lua_next(L, origIndex)) 2.1224 - { 2.1225 - lua_pushvalue(L, keyIndex); 2.1226 - lua_pushvalue(L, valueIndex); 2.1227 - lua_rawset(L, copyIndex); // copytable[key] = value 2.1228 - lua_pop(L, 1); 2.1229 - } 2.1230 - 2.1231 - // copy the reference to the metatable as well, if any 2.1232 - if (lua_getmetatable(L, origIndex)) 2.1233 - lua_setmetatable(L, copyIndex); 2.1234 - 2.1235 - return 1; // return the new table 2.1236 - } 2.1237 +static int copytable(lua_State *L) 2.1238 +{ 2.1239 + int origIndex = 1; // we only care about the first argument 2.1240 + int origType = lua_type(L, origIndex); 2.1241 + if (origType == LUA_TNIL) 2.1242 + { 2.1243 + lua_pushnil(L); 2.1244 + return 1; 2.1245 + } 2.1246 + if (origType != LUA_TTABLE) 2.1247 + { 2.1248 + luaL_typerror(L, 1, lua_typename(L, LUA_TTABLE)); 2.1249 + lua_pushnil(L); 2.1250 + return 1; 2.1251 + } 2.1252 + 2.1253 + lua_createtable(L, lua_objlen(L, 1), 0); 2.1254 + int copyIndex = lua_gettop(L); 2.1255 + 2.1256 + lua_pushnil(L); // first key 2.1257 + int keyIndex = lua_gettop(L); 2.1258 + int valueIndex = keyIndex + 1; 2.1259 + 2.1260 + while (lua_next(L, origIndex)) 2.1261 + { 2.1262 + lua_pushvalue(L, keyIndex); 2.1263 + lua_pushvalue(L, valueIndex); 2.1264 + lua_rawset(L, copyIndex); // copytable[key] = value 2.1265 + lua_pop(L, 1); 2.1266 + } 2.1267 + 2.1268 + // copy the reference to the metatable as well, if any 2.1269 + if (lua_getmetatable(L, origIndex)) 2.1270 + lua_setmetatable(L, copyIndex); 2.1271 + 2.1272 + return 1; // return the new table 2.1273 +} 2.1274 2.1275 // because print traditionally shows the address of tables, 2.1276 // and the print function I provide instead shows the contents of tables, 2.1277 // I also provide this function 2.1278 // (otherwise there would be no way to see a table's address, AFAICT) 2.1279 - static int addressof(lua_State *L) 2.1280 - { 2.1281 - const void *ptr = lua_topointer(L, -1); 2.1282 - lua_pushinteger(L, (lua_Integer)ptr); 2.1283 - return 1; 2.1284 - } 2.1285 - 2.1286 - struct registerPointerMap 2.1287 - { 2.1288 - const char * registerName; 2.1289 - unsigned int *pointer; 2.1290 - int dataSize; 2.1291 - }; 2.1292 - 2.1293 -#define RPM_ENTRY(name, var) \ 2.1294 - { name, (unsigned int *)&var, sizeof(var) \ 2.1295 - } \ 2.1296 - , 2.1297 - 2.1298 - extern gbRegister AF; 2.1299 - extern gbRegister BC; 2.1300 - extern gbRegister DE; 2.1301 - extern gbRegister HL; 2.1302 - extern gbRegister SP; 2.1303 - extern gbRegister PC; 2.1304 - extern u16 IFF; 2.1305 - 2.1306 - registerPointerMap regPointerMap [] = { 2.1307 - // gba registers 2.1308 - RPM_ENTRY("r0", reg[0].I) 2.1309 - RPM_ENTRY("r1", reg[1].I) 2.1310 - RPM_ENTRY("r2", reg[2].I) 2.1311 - RPM_ENTRY("r3", reg[3].I) 2.1312 - RPM_ENTRY("r4", reg[4].I) 2.1313 - RPM_ENTRY("r5", reg[5].I) 2.1314 - RPM_ENTRY("r6", reg[6].I) 2.1315 - RPM_ENTRY("r7", reg[7].I) 2.1316 - RPM_ENTRY("r8", reg[8].I) 2.1317 - RPM_ENTRY("r9", reg[9].I) 2.1318 - RPM_ENTRY("r10", reg[10].I) 2.1319 - RPM_ENTRY("r11", reg[11].I) 2.1320 - RPM_ENTRY("r12", reg[12].I) 2.1321 - RPM_ENTRY("r13", reg[13].I) 2.1322 - RPM_ENTRY("r14", reg[14].I) 2.1323 - RPM_ENTRY("r15", reg[15].I) 2.1324 - RPM_ENTRY("cpsr", reg[16].I) 2.1325 - RPM_ENTRY("spsr", reg[17].I) 2.1326 - // gb registers 2.1327 - RPM_ENTRY("a", AF.B.B1) 2.1328 - RPM_ENTRY("f", AF.B.B0) 2.1329 - RPM_ENTRY("b", BC.B.B1) 2.1330 - RPM_ENTRY("c", BC.B.B0) 2.1331 - RPM_ENTRY("d", DE.B.B1) 2.1332 - RPM_ENTRY("e", DE.B.B0) 2.1333 - RPM_ENTRY("h", HL.B.B1) 2.1334 - RPM_ENTRY("l", HL.B.B0) 2.1335 - RPM_ENTRY("af", AF.W) 2.1336 - RPM_ENTRY("bc", BC.W) 2.1337 - RPM_ENTRY("de", DE.W) 2.1338 - RPM_ENTRY("hl", HL.W) 2.1339 - RPM_ENTRY("sp", SP.W) 2.1340 - RPM_ENTRY("pc", PC.W) 2.1341 - {} 2.1342 - }; 2.1343 - 2.1344 - struct cpuToRegisterMap 2.1345 - { 2.1346 - const char *cpuName; 2.1347 - registerPointerMap *rpmap; 2.1348 - } 2.1349 - cpuToRegisterMaps [] = 2.1350 - { 2.1351 - { "", regPointerMap }, 2.1352 - }; 2.1353 +static int addressof(lua_State *L) 2.1354 +{ 2.1355 + const void *ptr = lua_topointer(L, -1); 2.1356 + lua_pushinteger(L, (lua_Integer)ptr); 2.1357 + return 1; 2.1358 +} 2.1359 + 2.1360 +struct registerPointerMap 2.1361 +{ 2.1362 + const char * registerName; 2.1363 + unsigned int *pointer; 2.1364 + int dataSize; 2.1365 +}; 2.1366 + 2.1367 +#define RPM_ENTRY(name, var) \ 2.1368 + { name, (unsigned int *)&var, sizeof(var) \ 2.1369 + } \ 2.1370 + , 2.1371 + 2.1372 +extern gbRegister AF; 2.1373 +extern gbRegister BC; 2.1374 +extern gbRegister DE; 2.1375 +extern gbRegister HL; 2.1376 +extern gbRegister SP; 2.1377 +extern gbRegister PC; 2.1378 +extern u16 IFF; 2.1379 + 2.1380 +registerPointerMap regPointerMap [] = { 2.1381 + // gba registers 2.1382 + RPM_ENTRY("r0", reg[0].I) 2.1383 + RPM_ENTRY("r1", reg[1].I) 2.1384 + RPM_ENTRY("r2", reg[2].I) 2.1385 + RPM_ENTRY("r3", reg[3].I) 2.1386 + RPM_ENTRY("r4", reg[4].I) 2.1387 + RPM_ENTRY("r5", reg[5].I) 2.1388 + RPM_ENTRY("r6", reg[6].I) 2.1389 + RPM_ENTRY("r7", reg[7].I) 2.1390 + RPM_ENTRY("r8", reg[8].I) 2.1391 + RPM_ENTRY("r9", reg[9].I) 2.1392 + RPM_ENTRY("r10", reg[10].I) 2.1393 + RPM_ENTRY("r11", reg[11].I) 2.1394 + RPM_ENTRY("r12", reg[12].I) 2.1395 + RPM_ENTRY("r13", reg[13].I) 2.1396 + RPM_ENTRY("r14", reg[14].I) 2.1397 + RPM_ENTRY("r15", reg[15].I) 2.1398 + RPM_ENTRY("cpsr", reg[16].I) 2.1399 + RPM_ENTRY("spsr", reg[17].I) 2.1400 + // gb registers 2.1401 + RPM_ENTRY("a", AF.B.B1) 2.1402 + RPM_ENTRY("f", AF.B.B0) 2.1403 + RPM_ENTRY("b", BC.B.B1) 2.1404 + RPM_ENTRY("c", BC.B.B0) 2.1405 + RPM_ENTRY("d", DE.B.B1) 2.1406 + RPM_ENTRY("e", DE.B.B0) 2.1407 + RPM_ENTRY("h", HL.B.B1) 2.1408 + RPM_ENTRY("l", HL.B.B0) 2.1409 + RPM_ENTRY("af", AF.W) 2.1410 + RPM_ENTRY("bc", BC.W) 2.1411 + RPM_ENTRY("de", DE.W) 2.1412 + RPM_ENTRY("hl", HL.W) 2.1413 + RPM_ENTRY("sp", SP.W) 2.1414 + RPM_ENTRY("pc", PC.W) 2.1415 + {} 2.1416 +}; 2.1417 + 2.1418 +struct cpuToRegisterMap 2.1419 +{ 2.1420 + const char *cpuName; 2.1421 + registerPointerMap *rpmap; 2.1422 +} 2.1423 + cpuToRegisterMaps [] = 2.1424 + { 2.1425 + { "", regPointerMap }, 2.1426 + }; 2.1427 2.1428 //DEFINE_LUA_FUNCTION(memory_getregister, "cpu_dot_registername_string") 2.1429 - static int memory_getregister(lua_State *L) 2.1430 - { 2.1431 - const char *qualifiedRegisterName = luaL_checkstring(L, 1); 2.1432 - lua_settop(L, 0); 2.1433 - for (int cpu = 0; cpu < sizeof(cpuToRegisterMaps) / sizeof(*cpuToRegisterMaps); cpu++) 2.1434 - { 2.1435 - cpuToRegisterMap ctrm = cpuToRegisterMaps[cpu]; 2.1436 - int cpuNameLen = strlen(ctrm.cpuName); 2.1437 - if (!strnicmp(qualifiedRegisterName, ctrm.cpuName, cpuNameLen)) 2.1438 - { 2.1439 - qualifiedRegisterName += cpuNameLen; 2.1440 - for (int reg = 0; ctrm.rpmap[reg].dataSize; reg++) 2.1441 - { 2.1442 - registerPointerMap rpm = ctrm.rpmap[reg]; 2.1443 - if (!stricmp(qualifiedRegisterName, rpm.registerName)) 2.1444 - { 2.1445 - switch (rpm.dataSize) 2.1446 - { 2.1447 - default: 2.1448 - case 1: 2.1449 - lua_pushinteger(L, *(unsigned char *)rpm.pointer); break; 2.1450 - case 2: 2.1451 - lua_pushinteger(L, *(unsigned short *)rpm.pointer); break; 2.1452 - case 4: 2.1453 - lua_pushinteger(L, *(unsigned long *)rpm.pointer); break; 2.1454 - } 2.1455 - return 1; 2.1456 - } 2.1457 - } 2.1458 - lua_pushnil(L); 2.1459 - return 1; 2.1460 - } 2.1461 - } 2.1462 - lua_pushnil(L); 2.1463 - return 1; 2.1464 - } 2.1465 +static int memory_getregister(lua_State *L) 2.1466 +{ 2.1467 + const char *qualifiedRegisterName = luaL_checkstring(L, 1); 2.1468 + lua_settop(L, 0); 2.1469 + for (int cpu = 0; cpu < sizeof(cpuToRegisterMaps) / sizeof(*cpuToRegisterMaps); cpu++) 2.1470 + { 2.1471 + cpuToRegisterMap ctrm = cpuToRegisterMaps[cpu]; 2.1472 + int cpuNameLen = strlen(ctrm.cpuName); 2.1473 + if (!strnicmp(qualifiedRegisterName, ctrm.cpuName, cpuNameLen)) 2.1474 + { 2.1475 + qualifiedRegisterName += cpuNameLen; 2.1476 + for (int reg = 0; ctrm.rpmap[reg].dataSize; reg++) 2.1477 + { 2.1478 + registerPointerMap rpm = ctrm.rpmap[reg]; 2.1479 + if (!stricmp(qualifiedRegisterName, rpm.registerName)) 2.1480 + { 2.1481 + switch (rpm.dataSize) 2.1482 + { 2.1483 + default: 2.1484 + case 1: 2.1485 + lua_pushinteger(L, *(unsigned char *)rpm.pointer); break; 2.1486 + case 2: 2.1487 + lua_pushinteger(L, *(unsigned short *)rpm.pointer); break; 2.1488 + case 4: 2.1489 + lua_pushinteger(L, *(unsigned long *)rpm.pointer); break; 2.1490 + } 2.1491 + return 1; 2.1492 + } 2.1493 + } 2.1494 + lua_pushnil(L); 2.1495 + return 1; 2.1496 + } 2.1497 + } 2.1498 + lua_pushnil(L); 2.1499 + return 1; 2.1500 +} 2.1501 2.1502 //DEFINE_LUA_FUNCTION(memory_setregister, "cpu_dot_registername_string,value") 2.1503 - static int memory_setregister(lua_State *L) 2.1504 - { 2.1505 - const char * qualifiedRegisterName = luaL_checkstring(L, 1); 2.1506 - unsigned long value = (unsigned long)(luaL_checkinteger(L, 2)); 2.1507 - lua_settop(L, 0); 2.1508 - for (int cpu = 0; cpu < sizeof(cpuToRegisterMaps) / sizeof(*cpuToRegisterMaps); cpu++) 2.1509 - { 2.1510 - cpuToRegisterMap ctrm = cpuToRegisterMaps[cpu]; 2.1511 - int cpuNameLen = strlen(ctrm.cpuName); 2.1512 - if (!strnicmp(qualifiedRegisterName, ctrm.cpuName, cpuNameLen)) 2.1513 - { 2.1514 - qualifiedRegisterName += cpuNameLen; 2.1515 - for (int reg = 0; ctrm.rpmap[reg].dataSize; reg++) 2.1516 - { 2.1517 - registerPointerMap rpm = ctrm.rpmap[reg]; 2.1518 - if (!stricmp(qualifiedRegisterName, rpm.registerName)) 2.1519 - { 2.1520 - switch (rpm.dataSize) 2.1521 - { 2.1522 - default: 2.1523 - case 1: 2.1524 - *(unsigned char *)rpm.pointer = (unsigned char)(value & 0xFF); break; 2.1525 - case 2: 2.1526 - *(unsigned short *)rpm.pointer = (unsigned short)(value & 0xFFFF); break; 2.1527 - case 4: 2.1528 - *(unsigned long *)rpm.pointer = value; break; 2.1529 - } 2.1530 - return 0; 2.1531 - } 2.1532 - } 2.1533 - return 0; 2.1534 - } 2.1535 - } 2.1536 - return 0; 2.1537 - } 2.1538 - 2.1539 - void HandleCallbackError(lua_State *L) 2.1540 - { 2.1541 - if (L->errfunc || L->errorJmp) 2.1542 - luaL_error(L, "%s", lua_tostring(L, -1)); 2.1543 - else 2.1544 - { 2.1545 - lua_pushnil(LUA); 2.1546 - lua_setfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 2.1547 - 2.1548 - // Error? 2.1549 -//#if (defined(WIN32) && !defined(SDL)) 2.1550 -// info_print(info_uid, lua_tostring(LUA, -1)); //Clear_Sound_Buffer(); 2.1551 -// AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(LUA, -1), "Lua run error", MB_OK | MB_ICONSTOP); 2.1552 -//#else 2.1553 -// fprintf(stderr, "Lua thread bombed out: %s\n", lua_tostring(LUA, -1)); 2.1554 -//#endif 2.1555 - printerror(LUA, -1); 2.1556 - VBALuaStop(); 2.1557 - } 2.1558 - } 2.1559 - 2.1560 - void CallRegisteredLuaFunctions(LuaCallID calltype) 2.1561 - { 2.1562 - assert((unsigned int)calltype < (unsigned int)LUACALL_COUNT); 2.1563 - 2.1564 - const char *idstring = luaCallIDStrings[calltype]; 2.1565 - 2.1566 - if (!LUA) 2.1567 - return; 2.1568 - 2.1569 - lua_settop(LUA, 0); 2.1570 - lua_getfield(LUA, LUA_REGISTRYINDEX, idstring); 2.1571 - 2.1572 - int errorcode = 0; 2.1573 - if (lua_isfunction(LUA, -1)) 2.1574 - { 2.1575 - errorcode = lua_pcall(LUA, 0, 0, 0); 2.1576 - if (errorcode) 2.1577 - HandleCallbackError(LUA); 2.1578 - } 2.1579 - else 2.1580 - { 2.1581 - lua_pop(LUA, 1); 2.1582 - } 2.1583 - } 2.1584 +static int memory_setregister(lua_State *L) 2.1585 +{ 2.1586 + const char * qualifiedRegisterName = luaL_checkstring(L, 1); 2.1587 + unsigned long value = (unsigned long)(luaL_checkinteger(L, 2)); 2.1588 + lua_settop(L, 0); 2.1589 + for (int cpu = 0; cpu < sizeof(cpuToRegisterMaps) / sizeof(*cpuToRegisterMaps); cpu++) 2.1590 + { 2.1591 + cpuToRegisterMap ctrm = cpuToRegisterMaps[cpu]; 2.1592 + int cpuNameLen = strlen(ctrm.cpuName); 2.1593 + if (!strnicmp(qualifiedRegisterName, ctrm.cpuName, cpuNameLen)) 2.1594 + { 2.1595 + qualifiedRegisterName += cpuNameLen; 2.1596 + for (int reg = 0; ctrm.rpmap[reg].dataSize; reg++) 2.1597 + { 2.1598 + registerPointerMap rpm = ctrm.rpmap[reg]; 2.1599 + if (!stricmp(qualifiedRegisterName, rpm.registerName)) 2.1600 + { 2.1601 + switch (rpm.dataSize) 2.1602 + { 2.1603 + default: 2.1604 + case 1: 2.1605 + *(unsigned char *)rpm.pointer = (unsigned char)(value & 0xFF); break; 2.1606 + case 2: 2.1607 + *(unsigned short *)rpm.pointer = (unsigned short)(value & 0xFFFF); break; 2.1608 + case 4: 2.1609 + *(unsigned long *)rpm.pointer = value; break; 2.1610 + } 2.1611 + return 0; 2.1612 + } 2.1613 + } 2.1614 + return 0; 2.1615 + } 2.1616 + } 2.1617 + return 0; 2.1618 +} 2.1619 + 2.1620 +void HandleCallbackError(lua_State *L) 2.1621 +{ 2.1622 + if (L->errfunc || L->errorJmp) 2.1623 + luaL_error(L, "%s", lua_tostring(L, -1)); 2.1624 + else 2.1625 + { 2.1626 + lua_pushnil(LUA); 2.1627 + lua_setfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 2.1628 + 2.1629 + // Error? 2.1630 + //#if (defined(WIN32) && !defined(SDL)) 2.1631 + // info_print(info_uid, lua_tostring(LUA, -1)); //Clear_Sound_Buffer(); 2.1632 + // AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(LUA, -1), "Lua run error", MB_OK | MB_ICONSTOP); 2.1633 + //#else 2.1634 + // fprintf(stderr, "Lua thread bombed out: %s\n", lua_tostring(LUA, -1)); 2.1635 + //#endif 2.1636 + printerror(LUA, -1); 2.1637 + VBALuaStop(); 2.1638 + } 2.1639 +} 2.1640 + 2.1641 +void CallRegisteredLuaFunctions(LuaCallID calltype) 2.1642 +{ 2.1643 + assert((unsigned int)calltype < (unsigned int)LUACALL_COUNT); 2.1644 + 2.1645 + const char *idstring = luaCallIDStrings[calltype]; 2.1646 + 2.1647 + if (!LUA) 2.1648 + return; 2.1649 + 2.1650 + lua_settop(LUA, 0); 2.1651 + lua_getfield(LUA, LUA_REGISTRYINDEX, idstring); 2.1652 + 2.1653 + int errorcode = 0; 2.1654 + if (lua_isfunction(LUA, -1)) 2.1655 + { 2.1656 + errorcode = lua_pcall(LUA, 0, 0, 0); 2.1657 + if (errorcode) 2.1658 + HandleCallbackError(LUA); 2.1659 + } 2.1660 + else 2.1661 + { 2.1662 + lua_pop(LUA, 1); 2.1663 + } 2.1664 +} 2.1665 2.1666 // the purpose of this structure is to provide a way of 2.1667 // QUICKLY determining whether a memory address range has a hook associated with it, 2.1668 @@ -1055,778 +1055,778 @@ 2.1669 // otherwise it would definitely be too slow.) 2.1670 // calculating the regions when a hook is added/removed may be slow, 2.1671 // but this is an intentional tradeoff to obtain a high speed of checking during later execution 2.1672 - struct TieredRegion 2.1673 - { 2.1674 - template<unsigned int maxGap> 2.1675 - struct Region 2.1676 - { 2.1677 - struct Island 2.1678 - { 2.1679 - unsigned int start; 2.1680 - unsigned int end; 2.1681 - __forceinline bool Contains(unsigned int address, int size) const { return address < end && address + size > start; } 2.1682 - }; 2.1683 - std::vector<Island> islands; 2.1684 - 2.1685 - void Calculate(const std::vector<unsigned int> &bytes) 2.1686 - { 2.1687 - islands. clear(); 2.1688 - 2.1689 - unsigned int lastEnd = ~0; 2.1690 - 2.1691 - std::vector<unsigned int>::const_iterator iter = bytes.begin(); 2.1692 - std::vector<unsigned int>::const_iterator end = bytes.end(); 2.1693 - for (; iter != end; ++iter) 2.1694 - { 2.1695 - unsigned int addr = *iter; 2.1696 - if (addr < lastEnd || addr > lastEnd + (long long)maxGap) 2.1697 - { 2.1698 - islands. push_back(Island()); 2.1699 - islands. back().start = addr; 2.1700 - } 2.1701 - islands.back(). end = addr + 1; 2.1702 - lastEnd = addr + 1; 2.1703 - } 2.1704 - } 2.1705 - 2.1706 - bool Contains(unsigned int address, int size) const 2.1707 - { 2.1708 - for (size_t i = 0; i != islands.size(); ++i) 2.1709 - { 2.1710 - if (islands[i].Contains(address, size)) 2.1711 - return true; 2.1712 - } 2.1713 - return false; 2.1714 - } 2.1715 - }; 2.1716 - 2.1717 - Region<0xFFFFFFFF> broad; 2.1718 - Region<0x1000> mid; 2.1719 - Region<0> narrow; 2.1720 - 2.1721 - void Calculate(std::vector<unsigned int> &bytes) 2.1722 - { 2.1723 - std:: sort(bytes.begin(), bytes.end()); 2.1724 - 2.1725 - broad. Calculate(bytes); 2.1726 - mid. Calculate(bytes); 2.1727 - narrow. Calculate(bytes); 2.1728 - } 2.1729 - 2.1730 - TieredRegion() 2.1731 - { 2.1732 - std::vector <unsigned int> temp; 2.1733 - Calculate(temp); 2.1734 - } 2.1735 - 2.1736 - __forceinline int NotEmpty() 2.1737 - { 2.1738 - return broad.islands.size(); 2.1739 - } 2.1740 - 2.1741 - // note: it is illegal to call this if NotEmpty() returns 0 2.1742 - __forceinline bool Contains(unsigned int address, int size) 2.1743 - { 2.1744 - return broad.islands[0].Contains(address, size) && 2.1745 - mid.Contains(address, size) && 2.1746 - narrow.Contains(address, size); 2.1747 - } 2.1748 - }; 2.1749 - TieredRegion hookedRegions [LUAMEMHOOK_COUNT]; 2.1750 - 2.1751 - static void CalculateMemHookRegions(LuaMemHookType hookType) 2.1752 - { 2.1753 - std::vector<unsigned int> hookedBytes; 2.1754 -// std::map<int, LuaContextInfo*>::iterator iter = luaContextInfo.begin(); 2.1755 -// std::map<int, LuaContextInfo*>::iterator end = luaContextInfo.end(); 2.1756 -// while(iter != end) 2.1757 -// { 2.1758 -// LuaContextInfo& info = *iter->second; 2.1759 - if (/*info.*/ numMemHooks) 2.1760 - { 2.1761 - lua_State *L = LUA /*info.L*/; 2.1762 - if (L) 2.1763 - { 2.1764 - lua_settop(L, 0); 2.1765 - lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]); 2.1766 - lua_pushnil(L); 2.1767 - while (lua_next(L, -2)) 2.1768 - { 2.1769 - if (lua_isfunction(L, -1)) 2.1770 - { 2.1771 - unsigned int addr = lua_tointeger(L, -2); 2.1772 - hookedBytes.push_back(addr); 2.1773 - } 2.1774 - lua_pop(L, 1); 2.1775 - } 2.1776 - lua_settop(L, 0); 2.1777 - } 2.1778 - } 2.1779 -// ++iter; 2.1780 -// } 2.1781 - hookedRegions[hookType].Calculate(hookedBytes); 2.1782 - } 2.1783 - 2.1784 - static void CallRegisteredLuaMemHook_LuaMatch(unsigned int address, int size, unsigned int value, LuaMemHookType hookType) 2.1785 - { 2.1786 -// std::map<int, LuaContextInfo*>::iterator iter = luaContextInfo.begin(); 2.1787 -// std::map<int, LuaContextInfo*>::iterator end = luaContextInfo.end(); 2.1788 -// while(iter != end) 2.1789 -// { 2.1790 -// LuaContextInfo& info = *iter->second; 2.1791 - if (/*info.*/ numMemHooks) 2.1792 - { 2.1793 - lua_State *L = LUA /*info.L*/; 2.1794 - if (L /* && !info.panic*/) 2.1795 - { 2.1796 +struct TieredRegion 2.1797 +{ 2.1798 + template<unsigned int maxGap> 2.1799 + struct Region 2.1800 + { 2.1801 + struct Island 2.1802 + { 2.1803 + unsigned int start; 2.1804 + unsigned int end; 2.1805 + __forceinline bool Contains(unsigned int address, int size) const { return address < end && address + size > start; } 2.1806 + }; 2.1807 + std::vector<Island> islands; 2.1808 + 2.1809 + void Calculate(const std::vector<unsigned int> &bytes) 2.1810 + { 2.1811 + islands. clear(); 2.1812 + 2.1813 + unsigned int lastEnd = ~0; 2.1814 + 2.1815 + std::vector<unsigned int>::const_iterator iter = bytes.begin(); 2.1816 + std::vector<unsigned int>::const_iterator end = bytes.end(); 2.1817 + for (; iter != end; ++iter) 2.1818 + { 2.1819 + unsigned int addr = *iter; 2.1820 + if (addr < lastEnd || addr > lastEnd + (long long)maxGap) 2.1821 + { 2.1822 + islands. push_back(Island()); 2.1823 + islands. back().start = addr; 2.1824 + } 2.1825 + islands.back(). end = addr + 1; 2.1826 + lastEnd = addr + 1; 2.1827 + } 2.1828 + } 2.1829 + 2.1830 + bool Contains(unsigned int address, int size) const 2.1831 + { 2.1832 + for (size_t i = 0; i != islands.size(); ++i) 2.1833 + { 2.1834 + if (islands[i].Contains(address, size)) 2.1835 + return true; 2.1836 + } 2.1837 + return false; 2.1838 + } 2.1839 + }; 2.1840 + 2.1841 + Region<0xFFFFFFFF> broad; 2.1842 + Region<0x1000> mid; 2.1843 + Region<0> narrow; 2.1844 + 2.1845 + void Calculate(std::vector<unsigned int> &bytes) 2.1846 + { 2.1847 + std:: sort(bytes.begin(), bytes.end()); 2.1848 + 2.1849 + broad. Calculate(bytes); 2.1850 + mid. Calculate(bytes); 2.1851 + narrow. Calculate(bytes); 2.1852 + } 2.1853 + 2.1854 + TieredRegion() 2.1855 + { 2.1856 + std::vector <unsigned int> temp; 2.1857 + Calculate(temp); 2.1858 + } 2.1859 + 2.1860 + __forceinline int NotEmpty() 2.1861 + { 2.1862 + return broad.islands.size(); 2.1863 + } 2.1864 + 2.1865 + // note: it is illegal to call this if NotEmpty() returns 0 2.1866 + __forceinline bool Contains(unsigned int address, int size) 2.1867 + { 2.1868 + return broad.islands[0].Contains(address, size) && 2.1869 + mid.Contains(address, size) && 2.1870 + narrow.Contains(address, size); 2.1871 + } 2.1872 +}; 2.1873 +TieredRegion hookedRegions [LUAMEMHOOK_COUNT]; 2.1874 + 2.1875 +static void CalculateMemHookRegions(LuaMemHookType hookType) 2.1876 +{ 2.1877 + std::vector<unsigned int> hookedBytes; 2.1878 + // std::map<int, LuaContextInfo*>::iterator iter = luaContextInfo.begin(); 2.1879 + // std::map<int, LuaContextInfo*>::iterator end = luaContextInfo.end(); 2.1880 + // while(iter != end) 2.1881 + // { 2.1882 + // LuaContextInfo& info = *iter->second; 2.1883 + if (/*info.*/ numMemHooks) 2.1884 + { 2.1885 + lua_State *L = LUA /*info.L*/; 2.1886 + if (L) 2.1887 + { 2.1888 + lua_settop(L, 0); 2.1889 + lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]); 2.1890 + lua_pushnil(L); 2.1891 + while (lua_next(L, -2)) 2.1892 + { 2.1893 + if (lua_isfunction(L, -1)) 2.1894 + { 2.1895 + unsigned int addr = lua_tointeger(L, -2); 2.1896 + hookedBytes.push_back(addr); 2.1897 + } 2.1898 + lua_pop(L, 1); 2.1899 + } 2.1900 + lua_settop(L, 0); 2.1901 + } 2.1902 + } 2.1903 + // ++iter; 2.1904 + // } 2.1905 + hookedRegions[hookType].Calculate(hookedBytes); 2.1906 +} 2.1907 + 2.1908 +static void CallRegisteredLuaMemHook_LuaMatch(unsigned int address, int size, unsigned int value, LuaMemHookType hookType) 2.1909 +{ 2.1910 + // std::map<int, LuaContextInfo*>::iterator iter = luaContextInfo.begin(); 2.1911 + // std::map<int, LuaContextInfo*>::iterator end = luaContextInfo.end(); 2.1912 + // while(iter != end) 2.1913 + // { 2.1914 + // LuaContextInfo& info = *iter->second; 2.1915 + if (/*info.*/ numMemHooks) 2.1916 + { 2.1917 + lua_State *L = LUA /*info.L*/; 2.1918 + if (L /* && !info.panic*/) 2.1919 + { 2.1920 #ifdef USE_INFO_STACK 2.1921 - infoStack.insert(infoStack.begin(), &info); 2.1922 - struct Scope { ~Scope(){ infoStack. erase(infoStack.begin()); } } scope; 2.1923 + infoStack.insert(infoStack.begin(), &info); 2.1924 + struct Scope { ~Scope(){ infoStack. erase(infoStack.begin()); } } scope; 2.1925 #endif 2.1926 - lua_settop(L, 0); 2.1927 - lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]); 2.1928 - for (int i = address; i != address + size; i++) 2.1929 - { 2.1930 - lua_rawgeti(L, -1, i); 2.1931 - if (lua_isfunction(L, -1)) 2.1932 - { 2.1933 - bool wasRunning = (luaRunning != 0) /*info.running*/; 2.1934 - luaRunning /*info.running*/ = true; 2.1935 - //RefreshScriptSpeedStatus(); 2.1936 - lua_pushinteger(L, address); 2.1937 - lua_pushinteger(L, size); 2.1938 - int errorcode = lua_pcall(L, 2, 0, 0); 2.1939 - luaRunning /*info.running*/ = wasRunning; 2.1940 - //RefreshScriptSpeedStatus(); 2.1941 - if (errorcode) 2.1942 - { 2.1943 - HandleCallbackError(L); 2.1944 - //int uid = iter->first; 2.1945 - //HandleCallbackError(L,info,uid,true); 2.1946 - } 2.1947 - break; 2.1948 - } 2.1949 - else 2.1950 - { 2.1951 - lua_pop(L, 1); 2.1952 - } 2.1953 - } 2.1954 - lua_settop(L, 0); 2.1955 - } 2.1956 - } 2.1957 -// ++iter; 2.1958 -// } 2.1959 - } 2.1960 - 2.1961 - void CallRegisteredLuaMemHook(unsigned int address, int size, unsigned int value, LuaMemHookType hookType) 2.1962 - { 2.1963 - // performance critical! (called VERY frequently) 2.1964 - // I suggest timing a large number of calls to this function in Release if you change anything in here, 2.1965 - // before and after, because even the most innocent change can make it become 30% to 400% slower. 2.1966 - // a good amount to test is: 100000000 calls with no hook set, and another 100000000 with a hook set. 2.1967 - // (on my system that consistently took 200 ms total in the former case and 350 ms total in the latter 2.1968 - // case) 2.1969 - if (hookedRegions[hookType].NotEmpty()) 2.1970 - { 2.1971 - //if((hookType <= LUAMEMHOOK_EXEC) && (address >= 0xE00000)) 2.1972 - // address |= 0xFF0000; // account for mirroring of RAM 2.1973 - if (hookedRegions[hookType].Contains(address, size)) 2.1974 - CallRegisteredLuaMemHook_LuaMatch(address, size, value, hookType); // something has hooked this 2.1975 - // specific address 2.1976 - } 2.1977 - } 2.1978 - 2.1979 - static int memory_registerHook(lua_State *L, LuaMemHookType hookType, int defaultSize) 2.1980 - { 2.1981 - // get first argument: address 2.1982 - unsigned int addr = luaL_checkinteger(L, 1); 2.1983 - //if((addr & ~0xFFFFFF) == ~0xFFFFFF) 2.1984 - // addr &= 0xFFFFFF; 2.1985 - 2.1986 - // get optional second argument: size 2.1987 - int size = defaultSize; 2.1988 - int funcIdx = 2; 2.1989 - if (lua_isnumber(L, 2)) 2.1990 - { 2.1991 - size = luaL_checkinteger(L, 2); 2.1992 - if (size < 0) 2.1993 - { 2.1994 - size = -size; 2.1995 - addr -= size; 2.1996 - } 2.1997 - funcIdx++; 2.1998 - } 2.1999 - 2.2000 - // check last argument: callback function 2.2001 - bool clearing = lua_isnil(L, funcIdx); 2.2002 - if (!clearing) 2.2003 - luaL_checktype(L, funcIdx, LUA_TFUNCTION); 2.2004 - lua_settop(L, funcIdx); 2.2005 - 2.2006 - // get the address-to-callback table for this hook type of the current script 2.2007 - lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]); 2.2008 - 2.2009 - // count how many callback functions we'll be displacing 2.2010 - int numFuncsAfter = clearing ? 0 : size; 2.2011 - int numFuncsBefore = 0; 2.2012 - for (unsigned int i = addr; i != addr + size; i++) 2.2013 - { 2.2014 - lua_rawgeti(L, -1, i); 2.2015 - if (lua_isfunction(L, -1)) 2.2016 - numFuncsBefore++; 2.2017 - lua_pop(L, 1); 2.2018 - } 2.2019 - 2.2020 - // put the callback function in the address slots 2.2021 - for (unsigned int i = addr; i != addr + size; i++) 2.2022 - { 2.2023 - lua_pushvalue(L, -2); 2.2024 - lua_rawseti(L, -2, i); 2.2025 - } 2.2026 - 2.2027 - // adjust the count of active hooks 2.2028 - //LuaContextInfo& info = GetCurrentInfo(); 2.2029 - /*info.*/ numMemHooks += numFuncsAfter - numFuncsBefore; 2.2030 - 2.2031 - // re-cache regions of hooked memory across all scripts 2.2032 - CalculateMemHookRegions(hookType); 2.2033 - 2.2034 - //StopScriptIfFinished(luaStateToUIDMap[L]); 2.2035 - return 0; 2.2036 - } 2.2037 - 2.2038 - LuaMemHookType MatchHookTypeToCPU(lua_State *L, LuaMemHookType hookType) 2.2039 - { 2.2040 - int cpuID = 0; 2.2041 - 2.2042 - int cpunameIndex = 0; 2.2043 - if (lua_type(L, 2) == LUA_TSTRING) 2.2044 - cpunameIndex = 2; 2.2045 - else if (lua_type(L, 3) == LUA_TSTRING) 2.2046 - cpunameIndex = 3; 2.2047 - 2.2048 - if (cpunameIndex) 2.2049 - { 2.2050 - const char *cpuName = lua_tostring(L, cpunameIndex); 2.2051 - if (!stricmp(cpuName, "sub")) 2.2052 - cpuID = 1; 2.2053 - lua_remove(L, cpunameIndex); 2.2054 - } 2.2055 - 2.2056 - switch (cpuID) 2.2057 - { 2.2058 - case 0: 2.2059 - return hookType; 2.2060 - 2.2061 - case 1: 2.2062 - switch (hookType) 2.2063 - { 2.2064 - case LUAMEMHOOK_WRITE: 2.2065 - return LUAMEMHOOK_WRITE_SUB; 2.2066 - case LUAMEMHOOK_READ: 2.2067 - return LUAMEMHOOK_READ_SUB; 2.2068 - case LUAMEMHOOK_EXEC: 2.2069 - return LUAMEMHOOK_EXEC_SUB; 2.2070 - } 2.2071 - } 2.2072 - return hookType; 2.2073 - } 2.2074 - 2.2075 - static int memory_registerwrite(lua_State *L) 2.2076 - { 2.2077 - return memory_registerHook(L, MatchHookTypeToCPU(L, LUAMEMHOOK_WRITE), 1); 2.2078 - } 2.2079 - 2.2080 - static int memory_registerread(lua_State *L) 2.2081 - { 2.2082 - return memory_registerHook(L, MatchHookTypeToCPU(L, LUAMEMHOOK_READ), 1); 2.2083 - } 2.2084 - 2.2085 - static int memory_registerexec(lua_State *L) 2.2086 - { 2.2087 - return memory_registerHook(L, MatchHookTypeToCPU(L, LUAMEMHOOK_EXEC), 1); 2.2088 - } 2.2089 + lua_settop(L, 0); 2.2090 + lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]); 2.2091 + for (int i = address; i != address + size; i++) 2.2092 + { 2.2093 + lua_rawgeti(L, -1, i); 2.2094 + if (lua_isfunction(L, -1)) 2.2095 + { 2.2096 + bool wasRunning = (luaRunning != 0) /*info.running*/; 2.2097 + luaRunning /*info.running*/ = true; 2.2098 + //RefreshScriptSpeedStatus(); 2.2099 + lua_pushinteger(L, address); 2.2100 + lua_pushinteger(L, size); 2.2101 + int errorcode = lua_pcall(L, 2, 0, 0); 2.2102 + luaRunning /*info.running*/ = wasRunning; 2.2103 + //RefreshScriptSpeedStatus(); 2.2104 + if (errorcode) 2.2105 + { 2.2106 + HandleCallbackError(L); 2.2107 + //int uid = iter->first; 2.2108 + //HandleCallbackError(L,info,uid,true); 2.2109 + } 2.2110 + break; 2.2111 + } 2.2112 + else 2.2113 + { 2.2114 + lua_pop(L, 1); 2.2115 + } 2.2116 + } 2.2117 + lua_settop(L, 0); 2.2118 + } 2.2119 + } 2.2120 + // ++iter; 2.2121 + // } 2.2122 +} 2.2123 + 2.2124 +void CallRegisteredLuaMemHook(unsigned int address, int size, unsigned int value, LuaMemHookType hookType) 2.2125 +{ 2.2126 + // performance critical! (called VERY frequently) 2.2127 + // I suggest timing a large number of calls to this function in Release if you change anything in here, 2.2128 + // before and after, because even the most innocent change can make it become 30% to 400% slower. 2.2129 + // a good amount to test is: 100000000 calls with no hook set, and another 100000000 with a hook set. 2.2130 + // (on my system that consistently took 200 ms total in the former case and 350 ms total in the latter 2.2131 + // case) 2.2132 + if (hookedRegions[hookType].NotEmpty()) 2.2133 + { 2.2134 + //if((hookType <= LUAMEMHOOK_EXEC) && (address >= 0xE00000)) 2.2135 + // address |= 0xFF0000; // account for mirroring of RAM 2.2136 + if (hookedRegions[hookType].Contains(address, size)) 2.2137 + CallRegisteredLuaMemHook_LuaMatch(address, size, value, hookType); // something has hooked this 2.2138 + // specific address 2.2139 + } 2.2140 +} 2.2141 + 2.2142 +static int memory_registerHook(lua_State *L, LuaMemHookType hookType, int defaultSize) 2.2143 +{ 2.2144 + // get first argument: address 2.2145 + unsigned int addr = luaL_checkinteger(L, 1); 2.2146 + //if((addr & ~0xFFFFFF) == ~0xFFFFFF) 2.2147 + // addr &= 0xFFFFFF; 2.2148 + 2.2149 + // get optional second argument: size 2.2150 + int size = defaultSize; 2.2151 + int funcIdx = 2; 2.2152 + if (lua_isnumber(L, 2)) 2.2153 + { 2.2154 + size = luaL_checkinteger(L, 2); 2.2155 + if (size < 0) 2.2156 + { 2.2157 + size = -size; 2.2158 + addr -= size; 2.2159 + } 2.2160 + funcIdx++; 2.2161 + } 2.2162 + 2.2163 + // check last argument: callback function 2.2164 + bool clearing = lua_isnil(L, funcIdx); 2.2165 + if (!clearing) 2.2166 + luaL_checktype(L, funcIdx, LUA_TFUNCTION); 2.2167 + lua_settop(L, funcIdx); 2.2168 + 2.2169 + // get the address-to-callback table for this hook type of the current script 2.2170 + lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]); 2.2171 + 2.2172 + // count how many callback functions we'll be displacing 2.2173 + int numFuncsAfter = clearing ? 0 : size; 2.2174 + int numFuncsBefore = 0; 2.2175 + for (unsigned int i = addr; i != addr + size; i++) 2.2176 + { 2.2177 + lua_rawgeti(L, -1, i); 2.2178 + if (lua_isfunction(L, -1)) 2.2179 + numFuncsBefore++; 2.2180 + lua_pop(L, 1); 2.2181 + } 2.2182 + 2.2183 + // put the callback function in the address slots 2.2184 + for (unsigned int i = addr; i != addr + size; i++) 2.2185 + { 2.2186 + lua_pushvalue(L, -2); 2.2187 + lua_rawseti(L, -2, i); 2.2188 + } 2.2189 + 2.2190 + // adjust the count of active hooks 2.2191 + //LuaContextInfo& info = GetCurrentInfo(); 2.2192 + /*info.*/ numMemHooks += numFuncsAfter - numFuncsBefore; 2.2193 + 2.2194 + // re-cache regions of hooked memory across all scripts 2.2195 + CalculateMemHookRegions(hookType); 2.2196 + 2.2197 + //StopScriptIfFinished(luaStateToUIDMap[L]); 2.2198 + return 0; 2.2199 +} 2.2200 + 2.2201 +LuaMemHookType MatchHookTypeToCPU(lua_State *L, LuaMemHookType hookType) 2.2202 +{ 2.2203 + int cpuID = 0; 2.2204 + 2.2205 + int cpunameIndex = 0; 2.2206 + if (lua_type(L, 2) == LUA_TSTRING) 2.2207 + cpunameIndex = 2; 2.2208 + else if (lua_type(L, 3) == LUA_TSTRING) 2.2209 + cpunameIndex = 3; 2.2210 + 2.2211 + if (cpunameIndex) 2.2212 + { 2.2213 + const char *cpuName = lua_tostring(L, cpunameIndex); 2.2214 + if (!stricmp(cpuName, "sub")) 2.2215 + cpuID = 1; 2.2216 + lua_remove(L, cpunameIndex); 2.2217 + } 2.2218 + 2.2219 + switch (cpuID) 2.2220 + { 2.2221 + case 0: 2.2222 + return hookType; 2.2223 + 2.2224 + case 1: 2.2225 + switch (hookType) 2.2226 + { 2.2227 + case LUAMEMHOOK_WRITE: 2.2228 + return LUAMEMHOOK_WRITE_SUB; 2.2229 + case LUAMEMHOOK_READ: 2.2230 + return LUAMEMHOOK_READ_SUB; 2.2231 + case LUAMEMHOOK_EXEC: 2.2232 + return LUAMEMHOOK_EXEC_SUB; 2.2233 + } 2.2234 + } 2.2235 + return hookType; 2.2236 +} 2.2237 + 2.2238 +static int memory_registerwrite(lua_State *L) 2.2239 +{ 2.2240 + return memory_registerHook(L, MatchHookTypeToCPU(L, LUAMEMHOOK_WRITE), 1); 2.2241 +} 2.2242 + 2.2243 +static int memory_registerread(lua_State *L) 2.2244 +{ 2.2245 + return memory_registerHook(L, MatchHookTypeToCPU(L, LUAMEMHOOK_READ), 1); 2.2246 +} 2.2247 + 2.2248 +static int memory_registerexec(lua_State *L) 2.2249 +{ 2.2250 + return memory_registerHook(L, MatchHookTypeToCPU(L, LUAMEMHOOK_EXEC), 1); 2.2251 +} 2.2252 2.2253 //int vba.lagcount 2.2254 // 2.2255 2.2256 //Returns the lagcounter variable 2.2257 - static int vba_getlagcount(lua_State *L) 2.2258 - { 2.2259 - lua_pushinteger(L, systemCounters.lagCount); 2.2260 - return 1; 2.2261 - } 2.2262 +static int vba_getlagcount(lua_State *L) 2.2263 +{ 2.2264 + lua_pushinteger(L, systemCounters.lagCount); 2.2265 + return 1; 2.2266 +} 2.2267 2.2268 //int vba.lagged 2.2269 // 2.2270 //Returns true if the current frame is a lag frame 2.2271 - static int vba_lagged(lua_State *L) 2.2272 - { 2.2273 - lua_pushboolean(L, systemCounters.laggedLast); 2.2274 - return 1; 2.2275 - } 2.2276 +static int vba_lagged(lua_State *L) 2.2277 +{ 2.2278 + lua_pushboolean(L, systemCounters.laggedLast); 2.2279 + return 1; 2.2280 +} 2.2281 2.2282 // boolean vba.emulating() 2.2283 - int vba_emulating(lua_State *L) 2.2284 - { 2.2285 - lua_pushboolean(L, systemIsEmulating()); 2.2286 - return 1; 2.2287 - } 2.2288 - 2.2289 - int movie_isactive(lua_State *L) 2.2290 - { 2.2291 - lua_pushboolean(L, VBAMovieActive()); 2.2292 - return 1; 2.2293 - } 2.2294 - 2.2295 - int movie_isrecording(lua_State *L) 2.2296 - { 2.2297 - lua_pushboolean(L, VBAMovieRecording()); 2.2298 - return 1; 2.2299 - } 2.2300 - 2.2301 - int movie_isplaying(lua_State *L) 2.2302 - { 2.2303 - lua_pushboolean(L, VBAMoviePlaying()); 2.2304 - return 1; 2.2305 - } 2.2306 - 2.2307 - int movie_getlength(lua_State *L) 2.2308 - { 2.2309 - if (VBAMovieActive()) 2.2310 - lua_pushinteger(L, VBAMovieGetLength()); 2.2311 - else 2.2312 - lua_pushinteger(L, 0); 2.2313 - return 1; 2.2314 - } 2.2315 - 2.2316 - static int memory_readbyte(lua_State *L) 2.2317 - { 2.2318 - u32 addr; 2.2319 - u8 val; 2.2320 - 2.2321 - addr = luaL_checkinteger(L, 1); 2.2322 - if (systemIsRunningGBA()) 2.2323 - { 2.2324 - val = CPUReadByteQuick(addr); 2.2325 - } 2.2326 - else 2.2327 - { 2.2328 - val = gbReadMemoryQuick8(addr); 2.2329 - } 2.2330 - 2.2331 - lua_pushinteger(L, val); 2.2332 - return 1; 2.2333 - } 2.2334 - 2.2335 - static int memory_readbytesigned(lua_State *L) 2.2336 - { 2.2337 - u32 addr; 2.2338 - s8 val; 2.2339 - 2.2340 - addr = luaL_checkinteger(L, 1); 2.2341 - if (systemIsRunningGBA()) 2.2342 - { 2.2343 - val = (s8) CPUReadByteQuick(addr); 2.2344 - } 2.2345 - else 2.2346 - { 2.2347 - val = (s8) gbReadMemoryQuick8(addr); 2.2348 - } 2.2349 - 2.2350 - lua_pushinteger(L, val); 2.2351 - return 1; 2.2352 - } 2.2353 - 2.2354 - static int memory_readword(lua_State *L) 2.2355 - { 2.2356 - u32 addr; 2.2357 - u16 val; 2.2358 - 2.2359 - addr = luaL_checkinteger(L, 1); 2.2360 - if (systemIsRunningGBA()) 2.2361 - { 2.2362 - val = CPUReadHalfWordQuick(addr); 2.2363 - } 2.2364 - else 2.2365 - { 2.2366 - val = gbReadMemoryQuick16(addr & 0x0000FFFF); 2.2367 - } 2.2368 - 2.2369 - lua_pushinteger(L, val); 2.2370 - return 1; 2.2371 - } 2.2372 - 2.2373 - static int memory_readwordsigned(lua_State *L) 2.2374 - { 2.2375 - u32 addr; 2.2376 - s16 val; 2.2377 - 2.2378 - addr = luaL_checkinteger(L, 1); 2.2379 - if (systemIsRunningGBA()) 2.2380 - { 2.2381 - val = (s16) CPUReadHalfWordQuick(addr); 2.2382 - } 2.2383 - else 2.2384 - { 2.2385 - val = (s16) gbReadMemoryQuick16(addr); 2.2386 - } 2.2387 - 2.2388 - lua_pushinteger(L, val); 2.2389 - return 1; 2.2390 - } 2.2391 - 2.2392 - static int memory_readdword(lua_State *L) 2.2393 - { 2.2394 - u32 addr; 2.2395 - u32 val; 2.2396 - 2.2397 - addr = luaL_checkinteger(L, 1); 2.2398 - if (systemIsRunningGBA()) 2.2399 - { 2.2400 - val = CPUReadMemoryQuick(addr); 2.2401 - } 2.2402 - else 2.2403 - { 2.2404 - val = gbReadMemoryQuick32(addr & 0x0000FFFF); 2.2405 - } 2.2406 - 2.2407 - // lua_pushinteger doesn't work properly for 32bit system, does it? 2.2408 - if (val >= 0x80000000 && sizeof(int) <= 4) 2.2409 - lua_pushnumber(L, val); 2.2410 - else 2.2411 - lua_pushinteger(L, val); 2.2412 - return 1; 2.2413 - } 2.2414 - 2.2415 - static int memory_readdwordsigned(lua_State *L) 2.2416 - { 2.2417 - u32 addr; 2.2418 - s32 val; 2.2419 - 2.2420 - addr = luaL_checkinteger(L, 1); 2.2421 - if (systemIsRunningGBA()) 2.2422 - { 2.2423 - val = (s32) CPUReadMemoryQuick(addr); 2.2424 - } 2.2425 - else 2.2426 - { 2.2427 - val = (s32) gbReadMemoryQuick32(addr); 2.2428 - } 2.2429 - 2.2430 - lua_pushinteger(L, val); 2.2431 - return 1; 2.2432 - } 2.2433 - 2.2434 - static int memory_readbyterange(lua_State *L) 2.2435 - { 2.2436 - uint32 address = luaL_checkinteger(L, 1); 2.2437 - int length = luaL_checkinteger(L, 2); 2.2438 - 2.2439 - if (length < 0) 2.2440 - { 2.2441 - address += length; 2.2442 - length = -length; 2.2443 - } 2.2444 - 2.2445 - // push the array 2.2446 - lua_createtable(L, abs(length), 0); 2.2447 - 2.2448 - // put all the values into the (1-based) array 2.2449 - for (int a = address, n = 1; n <= length; a++, n++) 2.2450 - { 2.2451 - unsigned char value; 2.2452 - 2.2453 - if (systemIsRunningGBA()) 2.2454 - { 2.2455 - value = CPUReadByteQuick(a); 2.2456 - } 2.2457 - else 2.2458 - { 2.2459 - value = gbReadMemoryQuick8(a); 2.2460 - } 2.2461 - 2.2462 - lua_pushinteger(L, value); 2.2463 - lua_rawseti(L, -2, n); 2.2464 - } 2.2465 - 2.2466 - return 1; 2.2467 - } 2.2468 - 2.2469 - static int memory_writebyte(lua_State *L) 2.2470 - { 2.2471 - u32 addr; 2.2472 - int val; 2.2473 - 2.2474 - addr = luaL_checkinteger(L, 1); 2.2475 - val = luaL_checkinteger(L, 2); 2.2476 - if (systemIsRunningGBA()) 2.2477 - { 2.2478 - CPUWriteByteQuick(addr, val); 2.2479 - } 2.2480 - else 2.2481 - { 2.2482 - gbWriteMemoryQuick8(addr, val); 2.2483 - } 2.2484 - 2.2485 - CallRegisteredLuaMemHook(addr, 1, val, LUAMEMHOOK_WRITE); 2.2486 - return 0; 2.2487 - } 2.2488 - 2.2489 - static int memory_writeword(lua_State *L) 2.2490 - { 2.2491 - u32 addr; 2.2492 - int val; 2.2493 - 2.2494 - addr = luaL_checkinteger(L, 1); 2.2495 - val = luaL_checkinteger(L, 2); 2.2496 - if (systemIsRunningGBA()) 2.2497 - { 2.2498 - CPUWriteHalfWordQuick(addr, val); 2.2499 - } 2.2500 - else 2.2501 - { 2.2502 - gbWriteMemoryQuick16(addr, val); 2.2503 - } 2.2504 - 2.2505 - CallRegisteredLuaMemHook(addr, 2, val, LUAMEMHOOK_WRITE); 2.2506 - return 0; 2.2507 - } 2.2508 - 2.2509 - static int memory_writedword(lua_State *L) 2.2510 - { 2.2511 - u32 addr; 2.2512 - int val; 2.2513 - 2.2514 - addr = luaL_checkinteger(L, 1); 2.2515 - val = luaL_checkinteger(L, 2); 2.2516 - if (systemIsRunningGBA()) 2.2517 - { 2.2518 - CPUWriteMemoryQuick(addr, val); 2.2519 - } 2.2520 - else 2.2521 - { 2.2522 - gbWriteMemoryQuick32(addr, val); 2.2523 - } 2.2524 - 2.2525 - CallRegisteredLuaMemHook(addr, 4, val, LUAMEMHOOK_WRITE); 2.2526 - return 0; 2.2527 - } 2.2528 - 2.2529 - static int memory_gbromreadbyte(lua_State *L) 2.2530 - { 2.2531 - u32 addr; 2.2532 - u8 val; 2.2533 - 2.2534 - addr = luaL_checkinteger(L, 1); 2.2535 - if (systemIsRunningGBA()) 2.2536 - { 2.2537 - lua_pushnil(L); 2.2538 - return 1; 2.2539 - } 2.2540 - else 2.2541 - { 2.2542 - val = gbReadROMQuick8(addr); 2.2543 - } 2.2544 - 2.2545 - lua_pushinteger(L, val); 2.2546 - return 1; 2.2547 - } 2.2548 - 2.2549 - static int memory_gbromreadbytesigned(lua_State *L) 2.2550 - { 2.2551 - u32 addr; 2.2552 - s8 val; 2.2553 - 2.2554 - addr = luaL_checkinteger(L, 1); 2.2555 - if (systemIsRunningGBA()) 2.2556 - { 2.2557 - lua_pushnil(L); 2.2558 - return 1; 2.2559 - } 2.2560 - else 2.2561 - { 2.2562 - val = (s8) gbReadROMQuick8(addr); 2.2563 - } 2.2564 - 2.2565 - lua_pushinteger(L, val); 2.2566 - return 1; 2.2567 - } 2.2568 - 2.2569 - static int memory_gbromreadword(lua_State *L) 2.2570 - { 2.2571 - u32 addr; 2.2572 - u16 val; 2.2573 - 2.2574 - addr = luaL_checkinteger(L, 1); 2.2575 - if (systemIsRunningGBA()) 2.2576 - { 2.2577 - lua_pushnil(L); 2.2578 - return 1; 2.2579 - } 2.2580 - else 2.2581 - { 2.2582 - val = gbReadROMQuick16(addr); 2.2583 - } 2.2584 - 2.2585 - lua_pushinteger(L, val); 2.2586 - return 1; 2.2587 - } 2.2588 - 2.2589 - static int memory_gbromreadwordsigned(lua_State *L) 2.2590 - { 2.2591 - u32 addr; 2.2592 - s16 val; 2.2593 - 2.2594 - addr = luaL_checkinteger(L, 1); 2.2595 - if (systemIsRunningGBA()) 2.2596 - { 2.2597 - lua_pushnil(L); 2.2598 - return 1; 2.2599 - } 2.2600 - else 2.2601 - { 2.2602 - val = (s16) gbReadROMQuick16(addr); 2.2603 - } 2.2604 - 2.2605 - lua_pushinteger(L, val); 2.2606 - return 1; 2.2607 - } 2.2608 - 2.2609 - static int memory_gbromreaddword(lua_State *L) 2.2610 - { 2.2611 - u32 addr; 2.2612 - u32 val; 2.2613 - 2.2614 - addr = luaL_checkinteger(L, 1); 2.2615 - if (systemIsRunningGBA()) 2.2616 - { 2.2617 - lua_pushnil(L); 2.2618 - return 1; 2.2619 - } 2.2620 - else 2.2621 - { 2.2622 - val = gbReadROMQuick32(addr); 2.2623 - } 2.2624 - 2.2625 - // lua_pushinteger doesn't work properly for 32bit system, does it? 2.2626 - if (val >= 0x80000000 && sizeof(int) <= 4) 2.2627 - lua_pushnumber(L, val); 2.2628 - else 2.2629 - lua_pushinteger(L, val); 2.2630 - return 1; 2.2631 - } 2.2632 - 2.2633 - static int memory_gbromreaddwordsigned(lua_State *L) 2.2634 - { 2.2635 - u32 addr; 2.2636 - s32 val; 2.2637 - 2.2638 - addr = luaL_checkinteger(L, 1); 2.2639 - if (systemIsRunningGBA()) 2.2640 - { 2.2641 - lua_pushnil(L); 2.2642 - return 1; 2.2643 - } 2.2644 - else 2.2645 - { 2.2646 - val = (s32) gbReadROMQuick32(addr); 2.2647 - } 2.2648 - 2.2649 - lua_pushinteger(L, val); 2.2650 - return 1; 2.2651 - } 2.2652 - 2.2653 - static int memory_gbromreadbyterange(lua_State *L) 2.2654 - { 2.2655 - uint32 address = luaL_checkinteger(L, 1); 2.2656 - int length = luaL_checkinteger(L, 2); 2.2657 - 2.2658 - if (length < 0) 2.2659 - { 2.2660 - address += length; 2.2661 - length = -length; 2.2662 - } 2.2663 - 2.2664 - // push the array 2.2665 - lua_createtable(L, abs(length), 0); 2.2666 - 2.2667 - // put all the values into the (1-based) array 2.2668 - for (int a = address, n = 1; n <= length; a++, n++) 2.2669 - { 2.2670 - unsigned char value; 2.2671 - 2.2672 - if (systemIsRunningGBA()) 2.2673 - { 2.2674 - lua_pushnil(L); 2.2675 - return 1; 2.2676 - } 2.2677 - else 2.2678 - { 2.2679 - value = gbReadROMQuick8(a); 2.2680 - } 2.2681 - 2.2682 - lua_pushinteger(L, value); 2.2683 - lua_rawseti(L, -2, n); 2.2684 - } 2.2685 - 2.2686 - return 1; 2.2687 - } 2.2688 +int vba_emulating(lua_State *L) 2.2689 +{ 2.2690 + lua_pushboolean(L, systemIsEmulating()); 2.2691 + return 1; 2.2692 +} 2.2693 + 2.2694 +int movie_isactive(lua_State *L) 2.2695 +{ 2.2696 + lua_pushboolean(L, VBAMovieActive()); 2.2697 + return 1; 2.2698 +} 2.2699 + 2.2700 +int movie_isrecording(lua_State *L) 2.2701 +{ 2.2702 + lua_pushboolean(L, VBAMovieRecording()); 2.2703 + return 1; 2.2704 +} 2.2705 + 2.2706 +int movie_isplaying(lua_State *L) 2.2707 +{ 2.2708 + lua_pushboolean(L, VBAMoviePlaying()); 2.2709 + return 1; 2.2710 +} 2.2711 + 2.2712 +int movie_getlength(lua_State *L) 2.2713 +{ 2.2714 + if (VBAMovieActive()) 2.2715 + lua_pushinteger(L, VBAMovieGetLength()); 2.2716 + else 2.2717 + lua_pushinteger(L, 0); 2.2718 + return 1; 2.2719 +} 2.2720 + 2.2721 +static int memory_readbyte(lua_State *L) 2.2722 +{ 2.2723 + u32 addr; 2.2724 + u8 val; 2.2725 + 2.2726 + addr = luaL_checkinteger(L, 1); 2.2727 + if (systemIsRunningGBA()) 2.2728 + { 2.2729 + val = CPUReadByteQuick(addr); 2.2730 + } 2.2731 + else 2.2732 + { 2.2733 + val = gbReadMemoryQuick8(addr); 2.2734 + } 2.2735 + 2.2736 + lua_pushinteger(L, val); 2.2737 + return 1; 2.2738 +} 2.2739 + 2.2740 +static int memory_readbytesigned(lua_State *L) 2.2741 +{ 2.2742 + u32 addr; 2.2743 + s8 val; 2.2744 + 2.2745 + addr = luaL_checkinteger(L, 1); 2.2746 + if (systemIsRunningGBA()) 2.2747 + { 2.2748 + val = (s8) CPUReadByteQuick(addr); 2.2749 + } 2.2750 + else 2.2751 + { 2.2752 + val = (s8) gbReadMemoryQuick8(addr); 2.2753 + } 2.2754 + 2.2755 + lua_pushinteger(L, val); 2.2756 + return 1; 2.2757 +} 2.2758 + 2.2759 +static int memory_readword(lua_State *L) 2.2760 +{ 2.2761 + u32 addr; 2.2762 + u16 val; 2.2763 + 2.2764 + addr = luaL_checkinteger(L, 1); 2.2765 + if (systemIsRunningGBA()) 2.2766 + { 2.2767 + val = CPUReadHalfWordQuick(addr); 2.2768 + } 2.2769 + else 2.2770 + { 2.2771 + val = gbReadMemoryQuick16(addr & 0x0000FFFF); 2.2772 + } 2.2773 + 2.2774 + lua_pushinteger(L, val); 2.2775 + return 1; 2.2776 +} 2.2777 + 2.2778 +static int memory_readwordsigned(lua_State *L) 2.2779 +{ 2.2780 + u32 addr; 2.2781 + s16 val; 2.2782 + 2.2783 + addr = luaL_checkinteger(L, 1); 2.2784 + if (systemIsRunningGBA()) 2.2785 + { 2.2786 + val = (s16) CPUReadHalfWordQuick(addr); 2.2787 + } 2.2788 + else 2.2789 + { 2.2790 + val = (s16) gbReadMemoryQuick16(addr); 2.2791 + } 2.2792 + 2.2793 + lua_pushinteger(L, val); 2.2794 + return 1; 2.2795 +} 2.2796 + 2.2797 +static int memory_readdword(lua_State *L) 2.2798 +{ 2.2799 + u32 addr; 2.2800 + u32 val; 2.2801 + 2.2802 + addr = luaL_checkinteger(L, 1); 2.2803 + if (systemIsRunningGBA()) 2.2804 + { 2.2805 + val = CPUReadMemoryQuick(addr); 2.2806 + } 2.2807 + else 2.2808 + { 2.2809 + val = gbReadMemoryQuick32(addr & 0x0000FFFF); 2.2810 + } 2.2811 + 2.2812 + // lua_pushinteger doesn't work properly for 32bit system, does it? 2.2813 + if (val >= 0x80000000 && sizeof(int) <= 4) 2.2814 + lua_pushnumber(L, val); 2.2815 + else 2.2816 + lua_pushinteger(L, val); 2.2817 + return 1; 2.2818 +} 2.2819 + 2.2820 +static int memory_readdwordsigned(lua_State *L) 2.2821 +{ 2.2822 + u32 addr; 2.2823 + s32 val; 2.2824 + 2.2825 + addr = luaL_checkinteger(L, 1); 2.2826 + if (systemIsRunningGBA()) 2.2827 + { 2.2828 + val = (s32) CPUReadMemoryQuick(addr); 2.2829 + } 2.2830 + else 2.2831 + { 2.2832 + val = (s32) gbReadMemoryQuick32(addr); 2.2833 + } 2.2834 + 2.2835 + lua_pushinteger(L, val); 2.2836 + return 1; 2.2837 +} 2.2838 + 2.2839 +static int memory_readbyterange(lua_State *L) 2.2840 +{ 2.2841 + uint32 address = luaL_checkinteger(L, 1); 2.2842 + int length = luaL_checkinteger(L, 2); 2.2843 + 2.2844 + if (length < 0) 2.2845 + { 2.2846 + address += length; 2.2847 + length = -length; 2.2848 + } 2.2849 + 2.2850 + // push the array 2.2851 + lua_createtable(L, abs(length), 0); 2.2852 + 2.2853 + // put all the values into the (1-based) array 2.2854 + for (int a = address, n = 1; n <= length; a++, n++) 2.2855 + { 2.2856 + unsigned char value; 2.2857 + 2.2858 + if (systemIsRunningGBA()) 2.2859 + { 2.2860 + value = CPUReadByteQuick(a); 2.2861 + } 2.2862 + else 2.2863 + { 2.2864 + value = gbReadMemoryQuick8(a); 2.2865 + } 2.2866 + 2.2867 + lua_pushinteger(L, value); 2.2868 + lua_rawseti(L, -2, n); 2.2869 + } 2.2870 + 2.2871 + return 1; 2.2872 +} 2.2873 + 2.2874 +static int memory_writebyte(lua_State *L) 2.2875 +{ 2.2876 + u32 addr; 2.2877 + int val; 2.2878 + 2.2879 + addr = luaL_checkinteger(L, 1); 2.2880 + val = luaL_checkinteger(L, 2); 2.2881 + if (systemIsRunningGBA()) 2.2882 + { 2.2883 + CPUWriteByteQuick(addr, val); 2.2884 + } 2.2885 + else 2.2886 + { 2.2887 + gbWriteMemoryQuick8(addr, val); 2.2888 + } 2.2889 + 2.2890 + CallRegisteredLuaMemHook(addr, 1, val, LUAMEMHOOK_WRITE); 2.2891 + return 0; 2.2892 +} 2.2893 + 2.2894 +static int memory_writeword(lua_State *L) 2.2895 +{ 2.2896 + u32 addr; 2.2897 + int val; 2.2898 + 2.2899 + addr = luaL_checkinteger(L, 1); 2.2900 + val = luaL_checkinteger(L, 2); 2.2901 + if (systemIsRunningGBA()) 2.2902 + { 2.2903 + CPUWriteHalfWordQuick(addr, val); 2.2904 + } 2.2905 + else 2.2906 + { 2.2907 + gbWriteMemoryQuick16(addr, val); 2.2908 + } 2.2909 + 2.2910 + CallRegisteredLuaMemHook(addr, 2, val, LUAMEMHOOK_WRITE); 2.2911 + return 0; 2.2912 +} 2.2913 + 2.2914 +static int memory_writedword(lua_State *L) 2.2915 +{ 2.2916 + u32 addr; 2.2917 + int val; 2.2918 + 2.2919 + addr = luaL_checkinteger(L, 1); 2.2920 + val = luaL_checkinteger(L, 2); 2.2921 + if (systemIsRunningGBA()) 2.2922 + { 2.2923 + CPUWriteMemoryQuick(addr, val); 2.2924 + } 2.2925 + else 2.2926 + { 2.2927 + gbWriteMemoryQuick32(addr, val); 2.2928 + } 2.2929 + 2.2930 + CallRegisteredLuaMemHook(addr, 4, val, LUAMEMHOOK_WRITE); 2.2931 + return 0; 2.2932 +} 2.2933 + 2.2934 +static int memory_gbromreadbyte(lua_State *L) 2.2935 +{ 2.2936 + u32 addr; 2.2937 + u8 val; 2.2938 + 2.2939 + addr = luaL_checkinteger(L, 1); 2.2940 + if (systemIsRunningGBA()) 2.2941 + { 2.2942 + lua_pushnil(L); 2.2943 + return 1; 2.2944 + } 2.2945 + else 2.2946 + { 2.2947 + val = gbReadROMQuick8(addr); 2.2948 + } 2.2949 + 2.2950 + lua_pushinteger(L, val); 2.2951 + return 1; 2.2952 +} 2.2953 + 2.2954 +static int memory_gbromreadbytesigned(lua_State *L) 2.2955 +{ 2.2956 + u32 addr; 2.2957 + s8 val; 2.2958 + 2.2959 + addr = luaL_checkinteger(L, 1); 2.2960 + if (systemIsRunningGBA()) 2.2961 + { 2.2962 + lua_pushnil(L); 2.2963 + return 1; 2.2964 + } 2.2965 + else 2.2966 + { 2.2967 + val = (s8) gbReadROMQuick8(addr); 2.2968 + } 2.2969 + 2.2970 + lua_pushinteger(L, val); 2.2971 + return 1; 2.2972 +} 2.2973 + 2.2974 +static int memory_gbromreadword(lua_State *L) 2.2975 +{ 2.2976 + u32 addr; 2.2977 + u16 val; 2.2978 + 2.2979 + addr = luaL_checkinteger(L, 1); 2.2980 + if (systemIsRunningGBA()) 2.2981 + { 2.2982 + lua_pushnil(L); 2.2983 + return 1; 2.2984 + } 2.2985 + else 2.2986 + { 2.2987 + val = gbReadROMQuick16(addr); 2.2988 + } 2.2989 + 2.2990 + lua_pushinteger(L, val); 2.2991 + return 1; 2.2992 +} 2.2993 + 2.2994 +static int memory_gbromreadwordsigned(lua_State *L) 2.2995 +{ 2.2996 + u32 addr; 2.2997 + s16 val; 2.2998 + 2.2999 + addr = luaL_checkinteger(L, 1); 2.3000 + if (systemIsRunningGBA()) 2.3001 + { 2.3002 + lua_pushnil(L); 2.3003 + return 1; 2.3004 + } 2.3005 + else 2.3006 + { 2.3007 + val = (s16) gbReadROMQuick16(addr); 2.3008 + } 2.3009 + 2.3010 + lua_pushinteger(L, val); 2.3011 + return 1; 2.3012 +} 2.3013 + 2.3014 +static int memory_gbromreaddword(lua_State *L) 2.3015 +{ 2.3016 + u32 addr; 2.3017 + u32 val; 2.3018 + 2.3019 + addr = luaL_checkinteger(L, 1); 2.3020 + if (systemIsRunningGBA()) 2.3021 + { 2.3022 + lua_pushnil(L); 2.3023 + return 1; 2.3024 + } 2.3025 + else 2.3026 + { 2.3027 + val = gbReadROMQuick32(addr); 2.3028 + } 2.3029 + 2.3030 + // lua_pushinteger doesn't work properly for 32bit system, does it? 2.3031 + if (val >= 0x80000000 && sizeof(int) <= 4) 2.3032 + lua_pushnumber(L, val); 2.3033 + else 2.3034 + lua_pushinteger(L, val); 2.3035 + return 1; 2.3036 +} 2.3037 + 2.3038 +static int memory_gbromreaddwordsigned(lua_State *L) 2.3039 +{ 2.3040 + u32 addr; 2.3041 + s32 val; 2.3042 + 2.3043 + addr = luaL_checkinteger(L, 1); 2.3044 + if (systemIsRunningGBA()) 2.3045 + { 2.3046 + lua_pushnil(L); 2.3047 + return 1; 2.3048 + } 2.3049 + else 2.3050 + { 2.3051 + val = (s32) gbReadROMQuick32(addr); 2.3052 + } 2.3053 + 2.3054 + lua_pushinteger(L, val); 2.3055 + return 1; 2.3056 +} 2.3057 + 2.3058 +static int memory_gbromreadbyterange(lua_State *L) 2.3059 +{ 2.3060 + uint32 address = luaL_checkinteger(L, 1); 2.3061 + int length = luaL_checkinteger(L, 2); 2.3062 + 2.3063 + if (length < 0) 2.3064 + { 2.3065 + address += length; 2.3066 + length = -length; 2.3067 + } 2.3068 + 2.3069 + // push the array 2.3070 + lua_createtable(L, abs(length), 0); 2.3071 + 2.3072 + // put all the values into the (1-based) array 2.3073 + for (int a = address, n = 1; n <= length; a++, n++) 2.3074 + { 2.3075 + unsigned char value; 2.3076 + 2.3077 + if (systemIsRunningGBA()) 2.3078 + { 2.3079 + lua_pushnil(L); 2.3080 + return 1; 2.3081 + } 2.3082 + else 2.3083 + { 2.3084 + value = gbReadROMQuick8(a); 2.3085 + } 2.3086 + 2.3087 + lua_pushinteger(L, value); 2.3088 + lua_rawseti(L, -2, n); 2.3089 + } 2.3090 + 2.3091 + return 1; 2.3092 +} 2.3093 2.3094 // table joypad.get(int which = 1) 2.3095 // 2.3096 // Reads the joypads as inputted by the user. 2.3097 - static int joy_get_internal(lua_State *L, bool reportUp, bool reportDown) 2.3098 - { 2.3099 - // Reads the joypads as inputted by the user 2.3100 - int which = luaL_checkinteger(L, 1); 2.3101 - 2.3102 - if (which < 0 || which > 4) 2.3103 - { 2.3104 - luaL_error(L, "Invalid input port (valid range 0-4, specified %d)", which); 2.3105 - } 2.3106 - 2.3107 - uint32 buttons = systemGetOriginalJoypad(which - 1, false); 2.3108 - 2.3109 - lua_newtable(L); 2.3110 - 2.3111 - int i; 2.3112 - for (i = 0; i < 10; i++) 2.3113 - { 2.3114 - bool pressed = (buttons & (1 << i)) != 0; 2.3115 - if ((pressed && reportDown) || (!pressed && reportUp)) 2.3116 - { 2.3117 - lua_pushboolean(L, pressed); 2.3118 - lua_setfield(L, -2, button_mappings[i]); 2.3119 - } 2.3120 - } 2.3121 - 2.3122 - return 1; 2.3123 - } 2.3124 +static int joy_get_internal(lua_State *L, bool reportUp, bool reportDown) 2.3125 +{ 2.3126 + // Reads the joypads as inputted by the user 2.3127 + int which = luaL_checkinteger(L, 1); 2.3128 + 2.3129 + if (which < 0 || which > 4) 2.3130 + { 2.3131 + luaL_error(L, "Invalid input port (valid range 0-4, specified %d)", which); 2.3132 + } 2.3133 + 2.3134 + uint32 buttons = systemGetOriginalJoypad(which - 1, false); 2.3135 + 2.3136 + lua_newtable(L); 2.3137 + 2.3138 + int i; 2.3139 + for (i = 0; i < 10; i++) 2.3140 + { 2.3141 + bool pressed = (buttons & (1 << i)) != 0; 2.3142 + if ((pressed && reportDown) || (!pressed && reportUp)) 2.3143 + { 2.3144 + lua_pushboolean(L, pressed); 2.3145 + lua_setfield(L, -2, button_mappings[i]); 2.3146 + } 2.3147 + } 2.3148 + 2.3149 + return 1; 2.3150 +} 2.3151 2.3152 // joypad.get(which) 2.3153 // returns a table of every game button, 2.3154 // true meaning currently-held and false meaning not-currently-held 2.3155 // (as of last frame boundary) 2.3156 // this WILL read input from a currently-playing movie 2.3157 - static int joypad_get(lua_State *L) 2.3158 - { 2.3159 - return joy_get_internal(L, true, true); 2.3160 - } 2.3161 +static int joypad_get(lua_State *L) 2.3162 +{ 2.3163 + return joy_get_internal(L, true, true); 2.3164 +} 2.3165 2.3166 // joypad.getdown(which) 2.3167 // returns a table of every game button that is currently held 2.3168 - static int joypad_getdown(lua_State *L) 2.3169 - { 2.3170 - return joy_get_internal(L, false, true); 2.3171 - } 2.3172 +static int joypad_getdown(lua_State *L) 2.3173 +{ 2.3174 + return joy_get_internal(L, false, true); 2.3175 +} 2.3176 2.3177 // joypad.getup(which) 2.3178 // returns a table of every game button that is not currently held 2.3179 - static int joypad_getup(lua_State *L) 2.3180 - { 2.3181 - return joy_get_internal(L, true, false); 2.3182 - } 2.3183 +static int joypad_getup(lua_State *L) 2.3184 +{ 2.3185 + return joy_get_internal(L, true, false); 2.3186 +} 2.3187 2.3188 // joypad.set(int which, table buttons) 2.3189 // 2.3190 @@ -1834,83 +1834,83 @@ 2.3191 // frame advance. The table should have the right 2.3192 2.3193 // keys (no pun intended) set. 2.3194 - static int joypad_set(lua_State *L) 2.3195 - { 2.3196 - // Which joypad we're tampering with 2.3197 - int which = luaL_checkinteger(L, 1); 2.3198 - if (which < 0 || which > 4) 2.3199 - { 2.3200 - luaL_error(L, "Invalid output port (valid range 0-4, specified %d)", which); 2.3201 - } 2.3202 - 2.3203 - if (which == 0) 2.3204 - which = systemGetDefaultJoypad(); 2.3205 - 2.3206 - // And the table of buttons. 2.3207 - luaL_checktype(L, 2, LUA_TTABLE); 2.3208 - 2.3209 - // Set up for taking control of the indicated controller 2.3210 - lua_joypads_used |= 1 << (which - 1); 2.3211 - lua_joypads[which - 1] = 0; 2.3212 - 2.3213 - for (int i = 0; i < 10; i++) 2.3214 - { 2.3215 - const char *name = button_mappings[i]; 2.3216 - lua_getfield(L, 2, name); 2.3217 - if (!lua_isnil(L, -1)) 2.3218 - { 2.3219 - bool pressed = lua_toboolean(L, -1) != 0; 2.3220 - if (pressed) 2.3221 - lua_joypads[which - 1] |= 1 << i; 2.3222 - else 2.3223 - lua_joypads[which - 1] &= ~(1 << i); 2.3224 - } 2.3225 - lua_pop(L, 1); 2.3226 - } 2.3227 - 2.3228 - return 0; 2.3229 - } 2.3230 +static int joypad_set(lua_State *L) 2.3231 +{ 2.3232 + // Which joypad we're tampering with 2.3233 + int which = luaL_checkinteger(L, 1); 2.3234 + if (which < 0 || which > 4) 2.3235 + { 2.3236 + luaL_error(L, "Invalid output port (valid range 0-4, specified %d)", which); 2.3237 + } 2.3238 + 2.3239 + if (which == 0) 2.3240 + which = systemGetDefaultJoypad(); 2.3241 + 2.3242 + // And the table of buttons. 2.3243 + luaL_checktype(L, 2, LUA_TTABLE); 2.3244 + 2.3245 + // Set up for taking control of the indicated controller 2.3246 + lua_joypads_used |= 1 << (which - 1); 2.3247 + lua_joypads[which - 1] = 0; 2.3248 + 2.3249 + for (int i = 0; i < 10; i++) 2.3250 + { 2.3251 + const char *name = button_mappings[i]; 2.3252 + lua_getfield(L, 2, name); 2.3253 + if (!lua_isnil(L, -1)) 2.3254 + { 2.3255 + bool pressed = lua_toboolean(L, -1) != 0; 2.3256 + if (pressed) 2.3257 + lua_joypads[which - 1] |= 1 << i; 2.3258 + else 2.3259 + lua_joypads[which - 1] &= ~(1 << i); 2.3260 + } 2.3261 + lua_pop(L, 1); 2.3262 + } 2.3263 + 2.3264 + return 0; 2.3265 +} 2.3266 2.3267 // Helper function to convert a savestate object to the filename it represents. 2.3268 - static const char *savestateobj2filename(lua_State *L, int offset) 2.3269 - { 2.3270 - // First we get the metatable of the indicated object 2.3271 - int result = lua_getmetatable(L, offset); 2.3272 - 2.3273 - if (!result) 2.3274 - luaL_error(L, "object not a savestate object"); 2.3275 - 2.3276 - // Also check that the type entry is set 2.3277 - lua_getfield(L, -1, "__metatable"); 2.3278 - if (strcmp(lua_tostring(L, -1), "vba Savestate") != 0) 2.3279 - luaL_error(L, "object not a savestate object"); 2.3280 - lua_pop(L, 1); 2.3281 - 2.3282 - // Now, get the field we want 2.3283 - lua_getfield(L, -1, "filename"); 2.3284 - 2.3285 - // Return it 2.3286 - return lua_tostring(L, -1); 2.3287 - } 2.3288 +static const char *savestateobj2filename(lua_State *L, int offset) 2.3289 +{ 2.3290 + // First we get the metatable of the indicated object 2.3291 + int result = lua_getmetatable(L, offset); 2.3292 + 2.3293 + if (!result) 2.3294 + luaL_error(L, "object not a savestate object"); 2.3295 + 2.3296 + // Also check that the type entry is set 2.3297 + lua_getfield(L, -1, "__metatable"); 2.3298 + if (strcmp(lua_tostring(L, -1), "vba Savestate") != 0) 2.3299 + luaL_error(L, "object not a savestate object"); 2.3300 + lua_pop(L, 1); 2.3301 + 2.3302 + // Now, get the field we want 2.3303 + lua_getfield(L, -1, "filename"); 2.3304 + 2.3305 + // Return it 2.3306 + return lua_tostring(L, -1); 2.3307 +} 2.3308 2.3309 // Helper function for garbage collection. 2.3310 - static int savestate_gc(lua_State *L) 2.3311 - { 2.3312 - // The object we're collecting is on top of the stack 2.3313 - lua_getmetatable(L, 1); 2.3314 - 2.3315 - // Get the filename 2.3316 - const char *filename; 2.3317 - lua_getfield(L, -1, "filename"); 2.3318 - filename = lua_tostring(L, -1); 2.3319 - 2.3320 - // Delete the file 2.3321 - remove(filename); 2.3322 - 2.3323 - // We exit, and the garbage collector takes care of the rest. 2.3324 - // Edit: Visual Studio needs a return value anyway, so returns 0. 2.3325 - return 0; 2.3326 - } 2.3327 +static int savestate_gc(lua_State *L) 2.3328 +{ 2.3329 + // The object we're collecting is on top of the stack 2.3330 + lua_getmetatable(L, 1); 2.3331 + 2.3332 + // Get the filename 2.3333 + const char *filename; 2.3334 + lua_getfield(L, -1, "filename"); 2.3335 + filename = lua_tostring(L, -1); 2.3336 + 2.3337 + // Delete the file 2.3338 + remove(filename); 2.3339 + 2.3340 + // We exit, and the garbage collector takes care of the rest. 2.3341 + // Edit: Visual Studio needs a return value anyway, so returns 0. 2.3342 + return 0; 2.3343 +} 2.3344 2.3345 // object savestate.create(int which = nil) 2.3346 // 2.3347 @@ -1918,244 +1918,244 @@ 2.3348 // The object can be associated with a player-accessible savestate 2.3349 2.3350 // ("which" between 1 and 12) or not (which == nil). 2.3351 - static int savestate_create(lua_State *L) 2.3352 - { 2.3353 - int which = -1; 2.3354 - if (lua_gettop(L) >= 1) 2.3355 - { 2.3356 - which = luaL_checkinteger(L, 1); 2.3357 - if (which < 1 || which > 12) 2.3358 - { 2.3359 - luaL_error(L, "invalid player's savestate %d", which); 2.3360 - } 2.3361 - } 2.3362 - 2.3363 - char stateName[2048]; 2.3364 - 2.3365 - if (which > 0) 2.3366 - { 2.3367 - // Find an appropriate filename. This is OS specific, unfortunately. 2.3368 +static int savestate_create(lua_State *L) 2.3369 +{ 2.3370 + int which = -1; 2.3371 + if (lua_gettop(L) >= 1) 2.3372 + { 2.3373 + which = luaL_checkinteger(L, 1); 2.3374 + if (which < 1 || which > 12) 2.3375 + { 2.3376 + luaL_error(L, "invalid player's savestate %d", which); 2.3377 + } 2.3378 + } 2.3379 + 2.3380 + char stateName[2048]; 2.3381 + 2.3382 + if (which > 0) 2.3383 + { 2.3384 + // Find an appropriate filename. This is OS specific, unfortunately. 2.3385 #if (defined(WIN32) && !defined(SDL)) 2.3386 - CString stateName = winGetSavestateFilename(theApp.gameFilename, which); 2.3387 + CString stateName = winGetSavestateFilename(theApp.gameFilename, which); 2.3388 #else 2.3389 - extern char saveDir[2048]; 2.3390 - extern char filename[2048]; 2.3391 - extern char *sdlGetFilename(char *name); 2.3392 - 2.3393 - if (saveDir[0]) 2.3394 - sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename), which); 2.3395 - else 2.3396 - sprintf(stateName, "%s%d.sgm", filename, which); 2.3397 + extern char saveDir[2048]; 2.3398 + extern char filename[2048]; 2.3399 + extern char *sdlGetFilename(char *name); 2.3400 + 2.3401 + if (saveDir[0]) 2.3402 + sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename), which); 2.3403 + else 2.3404 + sprintf(stateName, "%s%d.sgm", filename, which); 2.3405 #endif 2.3406 - } 2.3407 - else 2.3408 - { 2.3409 - char *stateNameTemp = tempnam(NULL, "snlua"); 2.3410 - strcpy(stateName, stateNameTemp); 2.3411 - if (stateNameTemp) 2.3412 - free(stateNameTemp); 2.3413 - } 2.3414 - 2.3415 - // Our "object". We don't care about the type, we just need the memory and GC services. 2.3416 - lua_newuserdata(L, 1); 2.3417 - 2.3418 - // The metatable we use, protected from Lua and contains garbage collection info and stuff. 2.3419 - lua_newtable(L); 2.3420 - 2.3421 - // First, we must protect it 2.3422 - lua_pushstring(L, "vba Savestate"); 2.3423 - lua_setfield(L, -2, "__metatable"); 2.3424 - 2.3425 - // Now we need to save the file itself. 2.3426 - lua_pushstring(L, stateName); 2.3427 - lua_setfield(L, -2, "filename"); 2.3428 - 2.3429 - // If it's an anonymous savestate, we must delete the file from disk should it be gargage collected 2.3430 - if (which < 0) 2.3431 - { 2.3432 - lua_pushcfunction(L, savestate_gc); 2.3433 - lua_setfield(L, -2, "__gc"); 2.3434 - } 2.3435 - 2.3436 - // Set the metatable 2.3437 - lua_setmetatable(L, -2); 2.3438 - 2.3439 - // Awesome. Return the object 2.3440 - return 1; 2.3441 - } 2.3442 + } 2.3443 + else 2.3444 + { 2.3445 + char *stateNameTemp = tempnam(NULL, "snlua"); 2.3446 + strcpy(stateName, stateNameTemp); 2.3447 + if (stateNameTemp) 2.3448 + free(stateNameTemp); 2.3449 + } 2.3450 + 2.3451 + // Our "object". We don't care about the type, we just need the memory and GC services. 2.3452 + lua_newuserdata(L, 1); 2.3453 + 2.3454 + // The metatable we use, protected from Lua and contains garbage collection info and stuff. 2.3455 + lua_newtable(L); 2.3456 + 2.3457 + // First, we must protect it 2.3458 + lua_pushstring(L, "vba Savestate"); 2.3459 + lua_setfield(L, -2, "__metatable"); 2.3460 + 2.3461 + // Now we need to save the file itself. 2.3462 + lua_pushstring(L, stateName); 2.3463 + lua_setfield(L, -2, "filename"); 2.3464 + 2.3465 + // If it's an anonymous savestate, we must delete the file from disk should it be gargage collected 2.3466 + if (which < 0) 2.3467 + { 2.3468 + lua_pushcfunction(L, savestate_gc); 2.3469 + lua_setfield(L, -2, "__gc"); 2.3470 + } 2.3471 + 2.3472 + // Set the metatable 2.3473 + lua_setmetatable(L, -2); 2.3474 + 2.3475 + // Awesome. Return the object 2.3476 + return 1; 2.3477 +} 2.3478 2.3479 // savestate.save(object state) 2.3480 // 2.3481 2.3482 // Saves a state to the given object. 2.3483 - static int savestate_save(lua_State *L) 2.3484 - { 2.3485 - const char *filename = savestateobj2filename(L, 1); 2.3486 - 2.3487 - // printf("saving %s\n", filename); 2.3488 - // Save states are very expensive. They take time. 2.3489 - numTries--; 2.3490 - 2.3491 - bool8 retvalue = theEmulator.emuWriteState ? theEmulator.emuWriteState(filename) : false; 2.3492 - if (!retvalue) 2.3493 - { 2.3494 - // Uh oh 2.3495 - luaL_error(L, "savestate failed"); 2.3496 - } 2.3497 - 2.3498 - return 0; 2.3499 - } 2.3500 +static int savestate_save(lua_State *L) 2.3501 +{ 2.3502 + const char *filename = savestateobj2filename(L, 1); 2.3503 + 2.3504 + // printf("saving %s\n", filename); 2.3505 + // Save states are very expensive. They take time. 2.3506 + numTries--; 2.3507 + 2.3508 + bool8 retvalue = theEmulator.emuWriteState ? theEmulator.emuWriteState(filename) : false; 2.3509 + if (!retvalue) 2.3510 + { 2.3511 + // Uh oh 2.3512 + luaL_error(L, "savestate failed"); 2.3513 + } 2.3514 + 2.3515 + return 0; 2.3516 +} 2.3517 2.3518 // savestate.load(object state) 2.3519 // 2.3520 2.3521 // Loads the given state 2.3522 - static int savestate_load(lua_State *L) 2.3523 - { 2.3524 - const char *filename = savestateobj2filename(L, 1); 2.3525 - 2.3526 - numTries--; 2.3527 - 2.3528 - // printf("loading %s\n", filename); 2.3529 - bool8 retvalue = theEmulator.emuReadState ? theEmulator.emuReadState(filename) : false; 2.3530 - if (!retvalue) 2.3531 - { 2.3532 - // Uh oh 2.3533 - luaL_error(L, "loadstate failed"); 2.3534 - } 2.3535 - 2.3536 - return 0; 2.3537 - } 2.3538 +static int savestate_load(lua_State *L) 2.3539 +{ 2.3540 + const char *filename = savestateobj2filename(L, 1); 2.3541 + 2.3542 + numTries--; 2.3543 + 2.3544 + // printf("loading %s\n", filename); 2.3545 + bool8 retvalue = theEmulator.emuReadState ? theEmulator.emuReadState(filename) : false; 2.3546 + if (!retvalue) 2.3547 + { 2.3548 + // Uh oh 2.3549 + luaL_error(L, "loadstate failed"); 2.3550 + } 2.3551 + 2.3552 + return 0; 2.3553 +} 2.3554 2.3555 // int vba.framecount() 2.3556 // 2.3557 2.3558 // Gets the frame counter for the movie, or the number of frames since last reset. 2.3559 - int vba_framecount(lua_State *L) 2.3560 - { 2.3561 - if (!VBAMovieActive()) 2.3562 - { 2.3563 - lua_pushinteger(L, systemCounters.frameCount); 2.3564 - } 2.3565 - else 2.3566 - { 2.3567 - lua_pushinteger(L, VBAMovieGetFrameCounter()); 2.3568 - } 2.3569 - 2.3570 - return 1; 2.3571 - } 2.3572 +int vba_framecount(lua_State *L) 2.3573 +{ 2.3574 + if (!VBAMovieActive()) 2.3575 + { 2.3576 + lua_pushinteger(L, systemCounters.frameCount); 2.3577 + } 2.3578 + else 2.3579 + { 2.3580 + lua_pushinteger(L, VBAMovieGetFrameCounter()); 2.3581 + } 2.3582 + 2.3583 + return 1; 2.3584 +} 2.3585 2.3586 //string movie.getauthor 2.3587 // 2.3588 2.3589 // returns author info field of .vbm file 2.3590 - int movie_getauthor(lua_State *L) 2.3591 - { 2.3592 - if (!VBAMovieActive()) 2.3593 - { 2.3594 - //lua_pushnil(L); 2.3595 - lua_pushstring(L, ""); 2.3596 - return 1; 2.3597 - } 2.3598 - 2.3599 - lua_pushstring(L, VBAMovieGetAuthorInfo().c_str()); 2.3600 - return 1; 2.3601 - } 2.3602 +int movie_getauthor(lua_State *L) 2.3603 +{ 2.3604 + if (!VBAMovieActive()) 2.3605 + { 2.3606 + //lua_pushnil(L); 2.3607 + lua_pushstring(L, ""); 2.3608 + return 1; 2.3609 + } 2.3610 + 2.3611 + lua_pushstring(L, VBAMovieGetAuthorInfo().c_str()); 2.3612 + return 1; 2.3613 +} 2.3614 2.3615 //string movie.filename 2.3616 - int movie_getfilename(lua_State *L) 2.3617 - { 2.3618 - if (!VBAMovieActive()) 2.3619 - { 2.3620 - //lua_pushnil(L); 2.3621 - lua_pushstring(L, ""); 2.3622 - return 1; 2.3623 - } 2.3624 - 2.3625 - lua_pushstring(L, VBAMovieGetFilename().c_str()); 2.3626 - return 1; 2.3627 - } 2.3628 +int movie_getfilename(lua_State *L) 2.3629 +{ 2.3630 + if (!VBAMovieActive()) 2.3631 + { 2.3632 + //lua_pushnil(L); 2.3633 + lua_pushstring(L, ""); 2.3634 + return 1; 2.3635 + } 2.3636 + 2.3637 + lua_pushstring(L, VBAMovieGetFilename().c_str()); 2.3638 + return 1; 2.3639 +} 2.3640 2.3641 // string movie.mode() 2.3642 // 2.3643 2.3644 // "record", "playback" or nil 2.3645 - int movie_getmode(lua_State *L) 2.3646 - { 2.3647 - assert(!VBAMovieLoading()); 2.3648 - if (!VBAMovieActive()) 2.3649 - { 2.3650 - lua_pushnil(L); 2.3651 - return 1; 2.3652 - } 2.3653 - 2.3654 - if (VBAMovieRecording()) 2.3655 - lua_pushstring(L, "record"); 2.3656 - else 2.3657 - lua_pushstring(L, "playback"); 2.3658 - return 1; 2.3659 - } 2.3660 - 2.3661 - static int movie_rerecordcount(lua_State *L) 2.3662 - { 2.3663 - if (VBAMovieActive()) 2.3664 - lua_pushinteger(L, VBAMovieGetRerecordCount()); 2.3665 - else 2.3666 - lua_pushinteger(L, 0); 2.3667 - return 1; 2.3668 - } 2.3669 - 2.3670 - static int movie_setrerecordcount(lua_State *L) 2.3671 - { 2.3672 - if (VBAMovieActive()) 2.3673 - VBAMovieSetRerecordCount(luaL_checkinteger(L, 1)); 2.3674 - return 0; 2.3675 - } 2.3676 - 2.3677 - static int movie_rerecordcounting(lua_State *L) 2.3678 - { 2.3679 - if (lua_gettop(L) == 0) 2.3680 - luaL_error(L, "no parameters specified"); 2.3681 - 2.3682 - skipRerecords = lua_toboolean(L, 1); 2.3683 - return 0; 2.3684 - } 2.3685 +int movie_getmode(lua_State *L) 2.3686 +{ 2.3687 + assert(!VBAMovieLoading()); 2.3688 + if (!VBAMovieActive()) 2.3689 + { 2.3690 + lua_pushnil(L); 2.3691 + return 1; 2.3692 + } 2.3693 + 2.3694 + if (VBAMovieRecording()) 2.3695 + lua_pushstring(L, "record"); 2.3696 + else 2.3697 + lua_pushstring(L, "playback"); 2.3698 + return 1; 2.3699 +} 2.3700 + 2.3701 +static int movie_rerecordcount(lua_State *L) 2.3702 +{ 2.3703 + if (VBAMovieActive()) 2.3704 + lua_pushinteger(L, VBAMovieGetRerecordCount()); 2.3705 + else 2.3706 + lua_pushinteger(L, 0); 2.3707 + return 1; 2.3708 +} 2.3709 + 2.3710 +static int movie_setrerecordcount(lua_State *L) 2.3711 +{ 2.3712 + if (VBAMovieActive()) 2.3713 + VBAMovieSetRerecordCount(luaL_checkinteger(L, 1)); 2.3714 + return 0; 2.3715 +} 2.3716 + 2.3717 +static int movie_rerecordcounting(lua_State *L) 2.3718 +{ 2.3719 + if (lua_gettop(L) == 0) 2.3720 + luaL_error(L, "no parameters specified"); 2.3721 + 2.3722 + skipRerecords = lua_toboolean(L, 1); 2.3723 + return 0; 2.3724 +} 2.3725 2.3726 // movie.stop() 2.3727 // 2.3728 2.3729 // Stops movie playback/recording. Bombs out if movie is not running. 2.3730 - static int movie_stop(lua_State *L) 2.3731 - { 2.3732 - if (!VBAMovieActive()) 2.3733 - luaL_error(L, "no movie"); 2.3734 - 2.3735 - VBAMovieStop(false); 2.3736 - return 0; 2.3737 - } 2.3738 +static int movie_stop(lua_State *L) 2.3739 +{ 2.3740 + if (!VBAMovieActive()) 2.3741 + luaL_error(L, "no movie"); 2.3742 + 2.3743 + VBAMovieStop(false); 2.3744 + return 0; 2.3745 +} 2.3746 2.3747 #define LUA_SCREEN_WIDTH 256 2.3748 #define LUA_SCREEN_HEIGHT 239 2.3749 2.3750 // Common code by the gui library: make sure the screen array is ready 2.3751 - static void gui_prepare(void) 2.3752 - { 2.3753 - if (!gui_data) 2.3754 - gui_data = (uint8 *)malloc(LUA_SCREEN_WIDTH * LUA_SCREEN_HEIGHT * 4); 2.3755 - if (!gui_used) 2.3756 - memset(gui_data, 0, LUA_SCREEN_WIDTH * LUA_SCREEN_HEIGHT * 4); 2.3757 - gui_used = true; 2.3758 - } 2.3759 +static void gui_prepare(void) 2.3760 +{ 2.3761 + if (!gui_data) 2.3762 + gui_data = (uint8 *)malloc(LUA_SCREEN_WIDTH * LUA_SCREEN_HEIGHT * 4); 2.3763 + if (!gui_used) 2.3764 + memset(gui_data, 0, LUA_SCREEN_WIDTH * LUA_SCREEN_HEIGHT * 4); 2.3765 + gui_used = true; 2.3766 +} 2.3767 2.3768 // pixform for lua graphics 2.3769 #define BUILD_PIXEL_ARGB8888(A, R, G, B) (((int)(A) << 24) | ((int)(R) << 16) | ((int)(G) << 8) | (int)(B)) 2.3770 -#define DECOMPOSE_PIXEL_ARGB8888(PIX, A, R, G, B) \ 2.3771 - { \ 2.3772 - (A) = ((PIX) >> 24) & 0xff; \ 2.3773 - (R) = ((PIX) >> 16) & 0xff; \ 2.3774 - (G) = ((PIX) >> 8) & 0xff; \ 2.3775 - (B) = (PIX) & 0xff; \ 2.3776 - } 2.3777 +#define DECOMPOSE_PIXEL_ARGB8888(PIX, A, R, G, B) \ 2.3778 + { \ 2.3779 + (A) = ((PIX) >> 24) & 0xff; \ 2.3780 + (R) = ((PIX) >> 16) & 0xff; \ 2.3781 + (G) = ((PIX) >> 8) & 0xff; \ 2.3782 + (B) = (PIX) & 0xff; \ 2.3783 + } 2.3784 #define LUA_BUILD_PIXEL BUILD_PIXEL_ARGB8888 2.3785 #define LUA_DECOMPOSE_PIXEL DECOMPOSE_PIXEL_ARGB8888 2.3786 #define LUA_PIXEL_A(PIX) (((PIX) >> 24) & 0xff) 2.3787 @@ -2163,387 +2163,387 @@ 2.3788 #define LUA_PIXEL_G(PIX) (((PIX) >> 8) & 0xff) 2.3789 #define LUA_PIXEL_B(PIX) ((PIX) & 0xff) 2.3790 2.3791 - template<class T> 2.3792 - static void swap(T &one, T &two) 2.3793 - { 2.3794 - T temp = one; 2.3795 - one = two; 2.3796 - two = temp; 2.3797 - } 2.3798 +template<class T> 2.3799 +static void swap(T &one, T &two) 2.3800 +{ 2.3801 + T temp = one; 2.3802 + one = two; 2.3803 + two = temp; 2.3804 +} 2.3805 2.3806 // write a pixel to buffer 2.3807 - static inline void blend32(uint32 *dstPixel, uint32 colour) 2.3808 - { 2.3809 - uint8 *dst = (uint8 *)dstPixel; 2.3810 - int a, r, g, b; 2.3811 - LUA_DECOMPOSE_PIXEL(colour, a, r, g, b); 2.3812 - 2.3813 - if (a == 255 || dst[3] == 0) 2.3814 - { 2.3815 - // direct copy 2.3816 - *(uint32 *) (dst) = colour; 2.3817 - } 2.3818 - else if (a == 0) 2.3819 - { 2.3820 - // do not copy 2.3821 - } 2.3822 - else 2.3823 - { 2.3824 - // alpha-blending 2.3825 - int a_dst = ((255 - a) * dst[3] + 128) / 255; 2.3826 - int a_new = a + a_dst; 2.3827 - 2.3828 - dst[0] = (uint8) (((dst[0] * a_dst + b * a) + (a_new / 2)) / a_new); 2.3829 - dst[1] = (uint8) (((dst[1] * a_dst + g * a) + (a_new / 2)) / a_new); 2.3830 - dst[2] = (uint8) (((dst[2] * a_dst + r * a) + (a_new / 2)) / a_new); 2.3831 - dst[3] = (uint8) a_new; 2.3832 - } 2.3833 - } 2.3834 +static inline void blend32(uint32 *dstPixel, uint32 colour) 2.3835 +{ 2.3836 + uint8 *dst = (uint8 *)dstPixel; 2.3837 + int a, r, g, b; 2.3838 + LUA_DECOMPOSE_PIXEL(colour, a, r, g, b); 2.3839 + 2.3840 + if (a == 255 || dst[3] == 0) 2.3841 + { 2.3842 + // direct copy 2.3843 + *(uint32 *) (dst) = colour; 2.3844 + } 2.3845 + else if (a == 0) 2.3846 + { 2.3847 + // do not copy 2.3848 + } 2.3849 + else 2.3850 + { 2.3851 + // alpha-blending 2.3852 + int a_dst = ((255 - a) * dst[3] + 128) / 255; 2.3853 + int a_new = a + a_dst; 2.3854 + 2.3855 + dst[0] = (uint8) (((dst[0] * a_dst + b * a) + (a_new / 2)) / a_new); 2.3856 + dst[1] = (uint8) (((dst[1] * a_dst + g * a) + (a_new / 2)) / a_new); 2.3857 + dst[2] = (uint8) (((dst[2] * a_dst + r * a) + (a_new / 2)) / a_new); 2.3858 + dst[3] = (uint8) a_new; 2.3859 + } 2.3860 +} 2.3861 2.3862 // check if a pixel is in the lua canvas 2.3863 - static inline bool gui_check_boundary(int x, int y) 2.3864 - { 2.3865 - return !(x < 0 || x >= LUA_SCREEN_WIDTH || y < 0 || y >= LUA_SCREEN_HEIGHT); 2.3866 - } 2.3867 +static inline bool gui_check_boundary(int x, int y) 2.3868 +{ 2.3869 + return !(x < 0 || x >= LUA_SCREEN_WIDTH || y < 0 || y >= LUA_SCREEN_HEIGHT); 2.3870 +} 2.3871 2.3872 // check if any part of a box is in the lua canvas 2.3873 - static inline bool gui_checkbox(int x1, int y1, int x2, int y2) 2.3874 - { 2.3875 - if ((x1 < 0 && x2 < 0) 2.3876 - || (x1 >= LUA_SCREEN_WIDTH && x2 >= LUA_SCREEN_WIDTH) 2.3877 - || (y1 < 0 && y2 < 0) 2.3878 - || (y1 >= LUA_SCREEN_HEIGHT && y2 >= LUA_SCREEN_HEIGHT)) 2.3879 - return false; 2.3880 - return true; 2.3881 - } 2.3882 +static inline bool gui_checkbox(int x1, int y1, int x2, int y2) 2.3883 +{ 2.3884 + if ((x1 < 0 && x2 < 0) 2.3885 + || (x1 >= LUA_SCREEN_WIDTH && x2 >= LUA_SCREEN_WIDTH) 2.3886 + || (y1 < 0 && y2 < 0) 2.3887 + || (y1 >= LUA_SCREEN_HEIGHT && y2 >= LUA_SCREEN_HEIGHT)) 2.3888 + return false; 2.3889 + return true; 2.3890 +} 2.3891 2.3892 // write a pixel to gui_data (do not check boundaries for speedup) 2.3893 - static inline void gui_drawpixel_fast(int x, int y, uint32 colour) 2.3894 - { 2.3895 - //gui_prepare(); 2.3896 - blend32((uint32 *) &gui_data[(y * LUA_SCREEN_WIDTH + x) * 4], colour); 2.3897 - } 2.3898 +static inline void gui_drawpixel_fast(int x, int y, uint32 colour) 2.3899 +{ 2.3900 + //gui_prepare(); 2.3901 + blend32((uint32 *) &gui_data[(y * LUA_SCREEN_WIDTH + x) * 4], colour); 2.3902 +} 2.3903 2.3904 // write a pixel to gui_data (check boundaries) 2.3905 - static inline void gui_drawpixel_internal(int x, int y, uint32 colour) 2.3906 - { 2.3907 - //gui_prepare(); 2.3908 - if (gui_check_boundary(x, y)) 2.3909 - gui_drawpixel_fast(x, y, colour); 2.3910 - } 2.3911 +static inline void gui_drawpixel_internal(int x, int y, uint32 colour) 2.3912 +{ 2.3913 + //gui_prepare(); 2.3914 + if (gui_check_boundary(x, y)) 2.3915 + gui_drawpixel_fast(x, y, colour); 2.3916 +} 2.3917 2.3918 // draw a line on gui_data (checks boundaries) 2.3919 - static void gui_drawline_internal(int x1, int y1, int x2, int y2, bool lastPixel, uint32 colour) 2.3920 - { 2.3921 - //gui_prepare(); 2.3922 - // Note: New version of Bresenham's Line Algorithm 2.3923 - // 2.3924 - // 2.3925 - // http://groups.google.co.jp/group/rec.games.roguelike.development/browse_thread/thread/345f4c42c3b25858/29e07a3af3a450e6?show_docid=29e07a3af3a450e6 2.3926 - int swappedx = 0; 2.3927 - int swappedy = 0; 2.3928 - 2.3929 - int xtemp = x1 - x2; 2.3930 - int ytemp = y1 - y2; 2.3931 - if (xtemp == 0 && ytemp == 0) 2.3932 - { 2.3933 - gui_drawpixel_internal(x1, y1, colour); 2.3934 - return; 2.3935 - } 2.3936 - 2.3937 - if (xtemp < 0) 2.3938 - { 2.3939 - xtemp = -xtemp; 2.3940 - swappedx = 1; 2.3941 - } 2.3942 - 2.3943 - if (ytemp < 0) 2.3944 - { 2.3945 - ytemp = -ytemp; 2.3946 - swappedy = 1; 2.3947 - } 2.3948 - 2.3949 - int delta_x = xtemp << 1; 2.3950 - int delta_y = ytemp << 1; 2.3951 - 2.3952 - signed char ix = x1 > x2 ? 1 : -1; 2.3953 - signed char iy = y1 > y2 ? 1 : -1; 2.3954 - 2.3955 - if (lastPixel) 2.3956 - gui_drawpixel_internal(x2, y2, colour); 2.3957 - 2.3958 - if (delta_x >= delta_y) 2.3959 - { 2.3960 - int error = delta_y - (delta_x >> 1); 2.3961 - 2.3962 - while (x2 != x1) 2.3963 - { 2.3964 - if (error == 0 && !swappedx) 2.3965 - gui_drawpixel_internal(x2 + ix, y2, colour); 2.3966 - if (error >= 0) 2.3967 - { 2.3968 - if (error || (ix > 0)) 2.3969 - { 2.3970 - y2 += iy; 2.3971 - error -= delta_x; 2.3972 - } 2.3973 - } 2.3974 - 2.3975 - x2 += ix; 2.3976 - gui_drawpixel_internal(x2, y2, colour); 2.3977 - if (error == 0 && swappedx) 2.3978 - gui_drawpixel_internal(x2, y2 + iy, colour); 2.3979 - error += delta_y; 2.3980 - } 2.3981 - } 2.3982 - else 2.3983 - { 2.3984 - int error = delta_x - (delta_y >> 1); 2.3985 - 2.3986 - while (y2 != y1) 2.3987 - { 2.3988 - if (error == 0 && !swappedy) 2.3989 - gui_drawpixel_internal(x2, y2 + iy, colour); 2.3990 - if (error >= 0) 2.3991 - { 2.3992 - if (error || (iy > 0)) 2.3993 - { 2.3994 - x2 += ix; 2.3995 - error -= delta_y; 2.3996 - } 2.3997 - } 2.3998 - 2.3999 - y2 += iy; 2.4000 - gui_drawpixel_internal(x2, y2, colour); 2.4001 - if (error == 0 && swappedy) 2.4002 - gui_drawpixel_internal(x2 + ix, y2, colour); 2.4003 - error += delta_x; 2.4004 - } 2.4005 - } 2.4006 - } 2.4007 +static void gui_drawline_internal(int x1, int y1, int x2, int y2, bool lastPixel, uint32 colour) 2.4008 +{ 2.4009 + //gui_prepare(); 2.4010 + // Note: New version of Bresenham's Line Algorithm 2.4011 + // 2.4012 + // 2.4013 + // http://groups.google.co.jp/group/rec.games.roguelike.development/browse_thread/thread/345f4c42c3b25858/29e07a3af3a450e6?show_docid=29e07a3af3a450e6 2.4014 + int swappedx = 0; 2.4015 + int swappedy = 0; 2.4016 + 2.4017 + int xtemp = x1 - x2; 2.4018 + int ytemp = y1 - y2; 2.4019 + if (xtemp == 0 && ytemp == 0) 2.4020 + { 2.4021 + gui_drawpixel_internal(x1, y1, colour); 2.4022 + return; 2.4023 + } 2.4024 + 2.4025 + if (xtemp < 0) 2.4026 + { 2.4027 + xtemp = -xtemp; 2.4028 + swappedx = 1; 2.4029 + } 2.4030 + 2.4031 + if (ytemp < 0) 2.4032 + { 2.4033 + ytemp = -ytemp; 2.4034 + swappedy = 1; 2.4035 + } 2.4036 + 2.4037 + int delta_x = xtemp << 1; 2.4038 + int delta_y = ytemp << 1; 2.4039 + 2.4040 + signed char ix = x1 > x2 ? 1 : -1; 2.4041 + signed char iy = y1 > y2 ? 1 : -1; 2.4042 + 2.4043 + if (lastPixel) 2.4044 + gui_drawpixel_internal(x2, y2, colour); 2.4045 + 2.4046 + if (delta_x >= delta_y) 2.4047 + { 2.4048 + int error = delta_y - (delta_x >> 1); 2.4049 + 2.4050 + while (x2 != x1) 2.4051 + { 2.4052 + if (error == 0 && !swappedx) 2.4053 + gui_drawpixel_internal(x2 + ix, y2, colour); 2.4054 + if (error >= 0) 2.4055 + { 2.4056 + if (error || (ix > 0)) 2.4057 + { 2.4058 + y2 += iy; 2.4059 + error -= delta_x; 2.4060 + } 2.4061 + } 2.4062 + 2.4063 + x2 += ix; 2.4064 + gui_drawpixel_internal(x2, y2, colour); 2.4065 + if (error == 0 && swappedx) 2.4066 + gui_drawpixel_internal(x2, y2 + iy, colour); 2.4067 + error += delta_y; 2.4068 + } 2.4069 + } 2.4070 + else 2.4071 + { 2.4072 + int error = delta_x - (delta_y >> 1); 2.4073 + 2.4074 + while (y2 != y1) 2.4075 + { 2.4076 + if (error == 0 && !swappedy) 2.4077 + gui_drawpixel_internal(x2, y2 + iy, colour); 2.4078 + if (error >= 0) 2.4079 + { 2.4080 + if (error || (iy > 0)) 2.4081 + { 2.4082 + x2 += ix; 2.4083 + error -= delta_y; 2.4084 + } 2.4085 + } 2.4086 + 2.4087 + y2 += iy; 2.4088 + gui_drawpixel_internal(x2, y2, colour); 2.4089 + if (error == 0 && swappedy) 2.4090 + gui_drawpixel_internal(x2 + ix, y2, colour); 2.4091 + error += delta_x; 2.4092 + } 2.4093 + } 2.4094 +} 2.4095 2.4096 // draw a rect on gui_data 2.4097 - static void gui_drawbox_internal(int x1, int y1, int x2, int y2, uint32 colour) 2.4098 - { 2.4099 - if (x1 > x2) 2.4100 - std::swap(x1, x2); 2.4101 - if (y1 > y2) 2.4102 - std::swap(y1, y2); 2.4103 - if (x1 < 0) 2.4104 - x1 = -1; 2.4105 - if (y1 < 0) 2.4106 - y1 = -1; 2.4107 - if (x2 >= LUA_SCREEN_WIDTH) 2.4108 - x2 = LUA_SCREEN_WIDTH; 2.4109 - if (y2 >= LUA_SCREEN_HEIGHT) 2.4110 - y2 = LUA_SCREEN_HEIGHT; 2.4111 - 2.4112 - if (!gui_checkbox(x1, y1, x2, y2)) 2.4113 - return; 2.4114 - 2.4115 - //gui_prepare(); 2.4116 - gui_drawline_internal(x1, y1, x2, y1, true, colour); 2.4117 - gui_drawline_internal(x1, y2, x2, y2, true, colour); 2.4118 - gui_drawline_internal(x1, y1, x1, y2, true, colour); 2.4119 - gui_drawline_internal(x2, y1, x2, y2, true, colour); 2.4120 - } 2.4121 +static void gui_drawbox_internal(int x1, int y1, int x2, int y2, uint32 colour) 2.4122 +{ 2.4123 + if (x1 > x2) 2.4124 + std::swap(x1, x2); 2.4125 + if (y1 > y2) 2.4126 + std::swap(y1, y2); 2.4127 + if (x1 < 0) 2.4128 + x1 = -1; 2.4129 + if (y1 < 0) 2.4130 + y1 = -1; 2.4131 + if (x2 >= LUA_SCREEN_WIDTH) 2.4132 + x2 = LUA_SCREEN_WIDTH; 2.4133 + if (y2 >= LUA_SCREEN_HEIGHT) 2.4134 + y2 = LUA_SCREEN_HEIGHT; 2.4135 + 2.4136 + if (!gui_checkbox(x1, y1, x2, y2)) 2.4137 + return; 2.4138 + 2.4139 + //gui_prepare(); 2.4140 + gui_drawline_internal(x1, y1, x2, y1, true, colour); 2.4141 + gui_drawline_internal(x1, y2, x2, y2, true, colour); 2.4142 + gui_drawline_internal(x1, y1, x1, y2, true, colour); 2.4143 + gui_drawline_internal(x2, y1, x2, y2, true, colour); 2.4144 +} 2.4145 2.4146 // draw a circle on gui_data 2.4147 - static void gui_drawcircle_internal(int x0, int y0, int radius, uint32 colour) 2.4148 - { 2.4149 - //gui_prepare(); 2.4150 - if (radius < 0) 2.4151 - radius = -radius; 2.4152 - if (radius == 0) 2.4153 - return; 2.4154 - if (radius == 1) 2.4155 - { 2.4156 - gui_drawpixel_internal(x0, y0, colour); 2.4157 - return; 2.4158 - } 2.4159 - 2.4160 - // http://en.wikipedia.org/wiki/Midpoint_circle_algorithm 2.4161 - int f = 1 - radius; 2.4162 - int ddF_x = 1; 2.4163 - int ddF_y = -2 * radius; 2.4164 - int x = 0; 2.4165 - int y = radius; 2.4166 - 2.4167 - if (!gui_checkbox(x0 - radius, y0 - radius, x0 + radius, y0 + radius)) 2.4168 - return; 2.4169 - 2.4170 - gui_drawpixel_internal(x0, y0 + radius, colour); 2.4171 - gui_drawpixel_internal(x0, y0 - radius, colour); 2.4172 - gui_drawpixel_internal(x0 + radius, y0, colour); 2.4173 - gui_drawpixel_internal(x0 - radius, y0, colour); 2.4174 - 2.4175 - // same pixel shouldn't be drawed twice, 2.4176 - // because each pixel has opacity. 2.4177 - // so now the routine gets ugly. 2.4178 - while (true) 2.4179 - { 2.4180 - assert(ddF_x == 2 * x + 1); 2.4181 - assert(ddF_y == -2 * y); 2.4182 - assert(f == x * x + y * y - radius * radius + 2 * x - y + 1); 2.4183 - if (f >= 0) 2.4184 - { 2.4185 - y--; 2.4186 - ddF_y += 2; 2.4187 - f += ddF_y; 2.4188 - } 2.4189 - 2.4190 - x++; 2.4191 - ddF_x += 2; 2.4192 - f += ddF_x; 2.4193 - if (x < y) 2.4194 - { 2.4195 - gui_drawpixel_internal(x0 + x, y0 + y, colour); 2.4196 - gui_drawpixel_internal(x0 - x, y0 + y, colour); 2.4197 - gui_drawpixel_internal(x0 + x, y0 - y, colour); 2.4198 - gui_drawpixel_internal(x0 - x, y0 - y, colour); 2.4199 - gui_drawpixel_internal(x0 + y, y0 + x, colour); 2.4200 - gui_drawpixel_internal(x0 - y, y0 + x, colour); 2.4201 - gui_drawpixel_internal(x0 + y, y0 - x, colour); 2.4202 - gui_drawpixel_internal(x0 - y, y0 - x, colour); 2.4203 - } 2.4204 - else if (x == y) 2.4205 - { 2.4206 - gui_drawpixel_internal(x0 + x, y0 + y, colour); 2.4207 - gui_drawpixel_internal(x0 - x, y0 + y, colour); 2.4208 - gui_drawpixel_internal(x0 + x, y0 - y, colour); 2.4209 - gui_drawpixel_internal(x0 - x, y0 - y, colour); 2.4210 - break; 2.4211 - } 2.4212 - else 2.4213 - break; 2.4214 - } 2.4215 - } 2.4216 +static void gui_drawcircle_internal(int x0, int y0, int radius, uint32 colour) 2.4217 +{ 2.4218 + //gui_prepare(); 2.4219 + if (radius < 0) 2.4220 + radius = -radius; 2.4221 + if (radius == 0) 2.4222 + return; 2.4223 + if (radius == 1) 2.4224 + { 2.4225 + gui_drawpixel_internal(x0, y0, colour); 2.4226 + return; 2.4227 + } 2.4228 + 2.4229 + // http://en.wikipedia.org/wiki/Midpoint_circle_algorithm 2.4230 + int f = 1 - radius; 2.4231 + int ddF_x = 1; 2.4232 + int ddF_y = -2 * radius; 2.4233 + int x = 0; 2.4234 + int y = radius; 2.4235 + 2.4236 + if (!gui_checkbox(x0 - radius, y0 - radius, x0 + radius, y0 + radius)) 2.4237 + return; 2.4238 + 2.4239 + gui_drawpixel_internal(x0, y0 + radius, colour); 2.4240 + gui_drawpixel_internal(x0, y0 - radius, colour); 2.4241 + gui_drawpixel_internal(x0 + radius, y0, colour); 2.4242 + gui_drawpixel_internal(x0 - radius, y0, colour); 2.4243 + 2.4244 + // same pixel shouldn't be drawed twice, 2.4245 + // because each pixel has opacity. 2.4246 + // so now the routine gets ugly. 2.4247 + while (true) 2.4248 + { 2.4249 + assert(ddF_x == 2 * x + 1); 2.4250 + assert(ddF_y == -2 * y); 2.4251 + assert(f == x * x + y * y - radius * radius + 2 * x - y + 1); 2.4252 + if (f >= 0) 2.4253 + { 2.4254 + y--; 2.4255 + ddF_y += 2; 2.4256 + f += ddF_y; 2.4257 + } 2.4258 + 2.4259 + x++; 2.4260 + ddF_x += 2; 2.4261 + f += ddF_x; 2.4262 + if (x < y) 2.4263 + { 2.4264 + gui_drawpixel_internal(x0 + x, y0 + y, colour); 2.4265 + gui_drawpixel_internal(x0 - x, y0 + y, colour); 2.4266 + gui_drawpixel_internal(x0 + x, y0 - y, colour); 2.4267 + gui_drawpixel_internal(x0 - x, y0 - y, colour); 2.4268 + gui_drawpixel_internal(x0 + y, y0 + x, colour); 2.4269 + gui_drawpixel_internal(x0 - y, y0 + x, colour); 2.4270 + gui_drawpixel_internal(x0 + y, y0 - x, colour); 2.4271 + gui_drawpixel_internal(x0 - y, y0 - x, colour); 2.4272 + } 2.4273 + else if (x == y) 2.4274 + { 2.4275 + gui_drawpixel_internal(x0 + x, y0 + y, colour); 2.4276 + gui_drawpixel_internal(x0 - x, y0 + y, colour); 2.4277 + gui_drawpixel_internal(x0 + x, y0 - y, colour); 2.4278 + gui_drawpixel_internal(x0 - x, y0 - y, colour); 2.4279 + break; 2.4280 + } 2.4281 + else 2.4282 + break; 2.4283 + } 2.4284 +} 2.4285 2.4286 // draw fill rect on gui_data 2.4287 - static void gui_fillbox_internal(int x1, int y1, int x2, int y2, uint32 colour) 2.4288 - { 2.4289 - if (x1 > x2) 2.4290 - std::swap(x1, x2); 2.4291 - if (y1 > y2) 2.4292 - std::swap(y1, y2); 2.4293 - if (x1 < 0) 2.4294 - x1 = 0; 2.4295 - if (y1 < 0) 2.4296 - y1 = 0; 2.4297 - if (x2 >= LUA_SCREEN_WIDTH) 2.4298 - x2 = LUA_SCREEN_WIDTH - 1; 2.4299 - if (y2 >= LUA_SCREEN_HEIGHT) 2.4300 - y2 = LUA_SCREEN_HEIGHT - 1; 2.4301 - 2.4302 - //gui_prepare(); 2.4303 - int ix, iy; 2.4304 - for (iy = y1; iy <= y2; iy++) 2.4305 - { 2.4306 - for (ix = x1; ix <= x2; ix++) 2.4307 - { 2.4308 - gui_drawpixel_fast(ix, iy, colour); 2.4309 - } 2.4310 - } 2.4311 - } 2.4312 +static void gui_fillbox_internal(int x1, int y1, int x2, int y2, uint32 colour) 2.4313 +{ 2.4314 + if (x1 > x2) 2.4315 + std::swap(x1, x2); 2.4316 + if (y1 > y2) 2.4317 + std::swap(y1, y2); 2.4318 + if (x1 < 0) 2.4319 + x1 = 0; 2.4320 + if (y1 < 0) 2.4321 + y1 = 0; 2.4322 + if (x2 >= LUA_SCREEN_WIDTH) 2.4323 + x2 = LUA_SCREEN_WIDTH - 1; 2.4324 + if (y2 >= LUA_SCREEN_HEIGHT) 2.4325 + y2 = LUA_SCREEN_HEIGHT - 1; 2.4326 + 2.4327 + //gui_prepare(); 2.4328 + int ix, iy; 2.4329 + for (iy = y1; iy <= y2; iy++) 2.4330 + { 2.4331 + for (ix = x1; ix <= x2; ix++) 2.4332 + { 2.4333 + gui_drawpixel_fast(ix, iy, colour); 2.4334 + } 2.4335 + } 2.4336 +} 2.4337 2.4338 // fill a circle on gui_data 2.4339 - static void gui_fillcircle_internal(int x0, int y0, int radius, uint32 colour) 2.4340 - { 2.4341 - //gui_prepare(); 2.4342 - if (radius < 0) 2.4343 - radius = -radius; 2.4344 - if (radius == 0) 2.4345 - return; 2.4346 - if (radius == 1) 2.4347 - { 2.4348 - gui_drawpixel_internal(x0, y0, colour); 2.4349 - return; 2.4350 - } 2.4351 - 2.4352 - // http://en.wikipedia.org/wiki/Midpoint_circle_algorithm 2.4353 - int f = 1 - radius; 2.4354 - int ddF_x = 1; 2.4355 - int ddF_y = -2 * radius; 2.4356 - int x = 0; 2.4357 - int y = radius; 2.4358 - 2.4359 - if (!gui_checkbox(x0 - radius, y0 - radius, x0 + radius, y0 + radius)) 2.4360 - return; 2.4361 - 2.4362 - gui_drawline_internal(x0, y0 - radius, x0, y0 + radius, true, colour); 2.4363 - 2.4364 - while (true) 2.4365 - { 2.4366 - assert(ddF_x == 2 * x + 1); 2.4367 - assert(ddF_y == -2 * y); 2.4368 - assert(f == x * x + y * y - radius * radius + 2 * x - y + 1); 2.4369 - if (f >= 0) 2.4370 - { 2.4371 - y--; 2.4372 - ddF_y += 2; 2.4373 - f += ddF_y; 2.4374 - } 2.4375 - 2.4376 - x++; 2.4377 - ddF_x += 2; 2.4378 - f += ddF_x; 2.4379 - 2.4380 - if (x < y) 2.4381 - { 2.4382 - gui_drawline_internal(x0 + x, y0 - y, x0 + x, y0 + y, true, colour); 2.4383 - gui_drawline_internal(x0 - x, y0 - y, x0 - x, y0 + y, true, colour); 2.4384 - if (f >= 0) 2.4385 - { 2.4386 - gui_drawline_internal(x0 + y, y0 - x, x0 + y, y0 + x, true, colour); 2.4387 - gui_drawline_internal(x0 - y, y0 - x, x0 - y, y0 + x, true, colour); 2.4388 - } 2.4389 - } 2.4390 - else if (x == y) 2.4391 - { 2.4392 - gui_drawline_internal(x0 + x, y0 - y, x0 + x, y0 + y, true, colour); 2.4393 - gui_drawline_internal(x0 - x, y0 - y, x0 - x, y0 + y, true, colour); 2.4394 - break; 2.4395 - } 2.4396 - else 2.4397 - break; 2.4398 - } 2.4399 - } 2.4400 +static void gui_fillcircle_internal(int x0, int y0, int radius, uint32 colour) 2.4401 +{ 2.4402 + //gui_prepare(); 2.4403 + if (radius < 0) 2.4404 + radius = -radius; 2.4405 + if (radius == 0) 2.4406 + return; 2.4407 + if (radius == 1) 2.4408 + { 2.4409 + gui_drawpixel_internal(x0, y0, colour); 2.4410 + return; 2.4411 + } 2.4412 + 2.4413 + // http://en.wikipedia.org/wiki/Midpoint_circle_algorithm 2.4414 + int f = 1 - radius; 2.4415 + int ddF_x = 1; 2.4416 + int ddF_y = -2 * radius; 2.4417 + int x = 0; 2.4418 + int y = radius; 2.4419 + 2.4420 + if (!gui_checkbox(x0 - radius, y0 - radius, x0 + radius, y0 + radius)) 2.4421 + return; 2.4422 + 2.4423 + gui_drawline_internal(x0, y0 - radius, x0, y0 + radius, true, colour); 2.4424 + 2.4425 + while (true) 2.4426 + { 2.4427 + assert(ddF_x == 2 * x + 1); 2.4428 + assert(ddF_y == -2 * y); 2.4429 + assert(f == x * x + y * y - radius * radius + 2 * x - y + 1); 2.4430 + if (f >= 0) 2.4431 + { 2.4432 + y--; 2.4433 + ddF_y += 2; 2.4434 + f += ddF_y; 2.4435 + } 2.4436 + 2.4437 + x++; 2.4438 + ddF_x += 2; 2.4439 + f += ddF_x; 2.4440 + 2.4441 + if (x < y) 2.4442 + { 2.4443 + gui_drawline_internal(x0 + x, y0 - y, x0 + x, y0 + y, true, colour); 2.4444 + gui_drawline_internal(x0 - x, y0 - y, x0 - x, y0 + y, true, colour); 2.4445 + if (f >= 0) 2.4446 + { 2.4447 + gui_drawline_internal(x0 + y, y0 - x, x0 + y, y0 + x, true, colour); 2.4448 + gui_drawline_internal(x0 - y, y0 - x, x0 - y, y0 + x, true, colour); 2.4449 + } 2.4450 + } 2.4451 + else if (x == y) 2.4452 + { 2.4453 + gui_drawline_internal(x0 + x, y0 - y, x0 + x, y0 + y, true, colour); 2.4454 + gui_drawline_internal(x0 - x, y0 - y, x0 - x, y0 + y, true, colour); 2.4455 + break; 2.4456 + } 2.4457 + else 2.4458 + break; 2.4459 + } 2.4460 +} 2.4461 2.4462 // Helper for a simple hex parser 2.4463 - static int hex2int(lua_State *L, char c) 2.4464 - { 2.4465 - if (c >= '0' && c <= '9') 2.4466 - return c - '0'; 2.4467 - if (c >= 'a' && c <= 'f') 2.4468 - return c - 'a' + 10; 2.4469 - if (c >= 'A' && c <= 'F') 2.4470 - return c - 'A' + 10; 2.4471 - return luaL_error(L, "invalid hex in colour"); 2.4472 - } 2.4473 - 2.4474 - static const struct ColorMapping 2.4475 - { 2.4476 - const char *name; 2.4477 - int value; 2.4478 - } 2.4479 - s_colorMapping[] = 2.4480 - { 2.4481 - { "white", 0xFFFFFFFF }, 2.4482 - { "black", 0x000000FF }, 2.4483 - { "clear", 0x00000000 }, 2.4484 - { "gray", 0x7F7F7FFF }, 2.4485 - { "grey", 0x7F7F7FFF }, 2.4486 - { "red", 0xFF0000FF }, 2.4487 - { "orange", 0xFF7F00FF }, 2.4488 - { "yellow", 0xFFFF00FF }, 2.4489 - { "chartreuse", 0x7FFF00FF }, 2.4490 - { "green", 0x00FF00FF }, 2.4491 - { "teal", 0x00FF7FFF }, 2.4492 - { "cyan", 0x00FFFFFF }, 2.4493 - { "blue", 0x0000FFFF }, 2.4494 - { "purple", 0x7F00FFFF }, 2.4495 - { "magenta", 0xFF00FFFF }, 2.4496 - }; 2.4497 +static int hex2int(lua_State *L, char c) 2.4498 +{ 2.4499 + if (c >= '0' && c <= '9') 2.4500 + return c - '0'; 2.4501 + if (c >= 'a' && c <= 'f') 2.4502 + return c - 'a' + 10; 2.4503 + if (c >= 'A' && c <= 'F') 2.4504 + return c - 'A' + 10; 2.4505 + return luaL_error(L, "invalid hex in colour"); 2.4506 +} 2.4507 + 2.4508 +static const struct ColorMapping 2.4509 +{ 2.4510 + const char *name; 2.4511 + int value; 2.4512 +} 2.4513 + s_colorMapping[] = 2.4514 + { 2.4515 + { "white", 0xFFFFFFFF }, 2.4516 + { "black", 0x000000FF }, 2.4517 + { "clear", 0x00000000 }, 2.4518 + { "gray", 0x7F7F7FFF }, 2.4519 + { "grey", 0x7F7F7FFF }, 2.4520 + { "red", 0xFF0000FF }, 2.4521 + { "orange", 0xFF7F00FF }, 2.4522 + { "yellow", 0xFFFF00FF }, 2.4523 + { "chartreuse", 0x7FFF00FF }, 2.4524 + { "green", 0x00FF00FF }, 2.4525 + { "teal", 0x00FF7FFF }, 2.4526 + { "cyan", 0x00FFFFFF }, 2.4527 + { "blue", 0x0000FFFF }, 2.4528 + { "purple", 0x7F00FFFF }, 2.4529 + { "magenta", 0xFF00FFFF }, 2.4530 + }; 2.4531 2.4532 /** 2.4533 * Converts an integer or a string on the stack at the given 2.4534 @@ -2551,358 +2551,358 @@ 2.4535 * The user may construct their own RGB value, given a simple colour name, 2.4536 * or an HTML-style "#09abcd" colour. 16 bit reduction doesn't occur at this time. 2.4537 */ 2.4538 - static inline bool str2colour(uint32 *colour, lua_State *L, const char *str) 2.4539 - { 2.4540 - if (str[0] == '#') 2.4541 - { 2.4542 - int color; 2.4543 - sscanf(str + 1, "%X", &color); 2.4544 - 2.4545 - int len = strlen(str + 1); 2.4546 - int missing = max(0, 8 - len); 2.4547 - color <<= missing << 2; 2.4548 - if (missing >= 2) 2.4549 - color |= 0xFF; 2.4550 - *colour = color; 2.4551 - return true; 2.4552 - } 2.4553 - else 2.4554 - { 2.4555 - if (!strnicmp(str, "rand", 4)) 2.4556 - { 2.4557 - *colour = gen_rand32() | 0xFF; //((rand()*255/RAND_MAX) << 8) | ((rand()*255/RAND_MAX) << 16) | 2.4558 - // ((rand()*255/RAND_MAX) << 24) | 0xFF; 2.4559 - return true; 2.4560 - } 2.4561 - 2.4562 - for (int i = 0; i < sizeof(s_colorMapping) / sizeof(*s_colorMapping); i++) 2.4563 - { 2.4564 - if (!stricmp(str, s_colorMapping[i].name)) 2.4565 - { 2.4566 - *colour = s_colorMapping[i].value; 2.4567 - return true; 2.4568 - } 2.4569 - } 2.4570 - } 2.4571 - 2.4572 - return false; 2.4573 - } 2.4574 - 2.4575 - static inline uint32 gui_getcolour_wrapped(lua_State *L, int offset, bool hasDefaultValue, uint32 defaultColour) 2.4576 - { 2.4577 - switch (lua_type(L, offset)) 2.4578 - { 2.4579 - case LUA_TSTRING: 2.4580 - { 2.4581 - const char *str = lua_tostring(L, offset); 2.4582 - uint32 colour; 2.4583 - 2.4584 - if (str2colour(&colour, L, str)) 2.4585 - return colour; 2.4586 - else 2.4587 - { 2.4588 - if (hasDefaultValue) 2.4589 - return defaultColour; 2.4590 - else 2.4591 - return luaL_error(L, "unknown colour %s", str); 2.4592 - } 2.4593 - } 2.4594 - 2.4595 - case LUA_TNUMBER: 2.4596 - { 2.4597 - uint32 colour = (uint32) lua_tointeger(L, offset); 2.4598 - return colour; 2.4599 - } 2.4600 - 2.4601 - case LUA_TTABLE: 2.4602 - { 2.4603 - int color = 0xFF; 2.4604 - lua_pushnil(L); // first key 2.4605 - int keyIndex = lua_gettop(L); 2.4606 - int valueIndex = keyIndex + 1; 2.4607 - bool first = true; 2.4608 - while (lua_next(L, offset)) 2.4609 - { 2.4610 - bool keyIsString = (lua_type(L, keyIndex) == LUA_TSTRING); 2.4611 - bool keyIsNumber = (lua_type(L, keyIndex) == LUA_TNUMBER); 2.4612 - int key = keyIsString ? tolower(*lua_tostring(L, keyIndex)) : (keyIsNumber ? lua_tointeger(L, keyIndex) : 0); 2.4613 - int value = lua_tointeger(L, valueIndex); 2.4614 - if (value < 0) value = 0; 2.4615 - if (value > 255) value = 255; 2.4616 - switch (key) 2.4617 - { 2.4618 - case 1: 2.4619 - case 'r': 2.4620 - color |= value << 24; break; 2.4621 - case 2: 2.4622 - case 'g': 2.4623 - color |= value << 16; break; 2.4624 - case 3: 2.4625 - case 'b': 2.4626 - color |= value << 8; break; 2.4627 - case 4: 2.4628 - case 'a': 2.4629 - color = (color & ~0xFF) | value; break; 2.4630 - } 2.4631 - lua_pop(L, 1); 2.4632 - } 2.4633 - return color; 2.4634 - } break; 2.4635 - 2.4636 - case LUA_TFUNCTION: 2.4637 - luaL_error(L, "invalid colour"); // NYI 2.4638 - return 0; 2.4639 - 2.4640 - default: 2.4641 - if (hasDefaultValue) 2.4642 - return defaultColour; 2.4643 - else 2.4644 - return luaL_error(L, "invalid colour"); 2.4645 - } 2.4646 - } 2.4647 - 2.4648 - static uint32 gui_getcolour(lua_State *L, int offset) 2.4649 - { 2.4650 - uint32 colour; 2.4651 - int a, r, g, b; 2.4652 - 2.4653 - colour = gui_getcolour_wrapped(L, offset, false, 0); 2.4654 - a = ((colour & 0xff) * transparencyModifier) / 255; 2.4655 - if (a > 255) 2.4656 - a = 255; 2.4657 - b = (colour >> 8) & 0xff; 2.4658 - g = (colour >> 16) & 0xff; 2.4659 - r = (colour >> 24) & 0xff; 2.4660 - return LUA_BUILD_PIXEL(a, r, g, b); 2.4661 - } 2.4662 - 2.4663 - static uint32 gui_optcolour(lua_State *L, int offset, uint32 defaultColour) 2.4664 - { 2.4665 - uint32 colour; 2.4666 - int a, r, g, b; 2.4667 - uint8 defA, defB, defG, defR; 2.4668 - 2.4669 - LUA_DECOMPOSE_PIXEL(defaultColour, defA, defR, defG, defB); 2.4670 - defaultColour = (defR << 24) | (defG << 16) | (defB << 8) | defA; 2.4671 - 2.4672 - colour = gui_getcolour_wrapped(L, offset, true, defaultColour); 2.4673 - a = ((colour & 0xff) * transparencyModifier) / 255; 2.4674 - if (a > 255) 2.4675 - a = 255; 2.4676 - b = (colour >> 8) & 0xff; 2.4677 - g = (colour >> 16) & 0xff; 2.4678 - r = (colour >> 24) & 0xff; 2.4679 - return LUA_BUILD_PIXEL(a, r, g, b); 2.4680 - } 2.4681 +static inline bool str2colour(uint32 *colour, lua_State *L, const char *str) 2.4682 +{ 2.4683 + if (str[0] == '#') 2.4684 + { 2.4685 + int color; 2.4686 + sscanf(str + 1, "%X", &color); 2.4687 + 2.4688 + int len = strlen(str + 1); 2.4689 + int missing = max(0, 8 - len); 2.4690 + color <<= missing << 2; 2.4691 + if (missing >= 2) 2.4692 + color |= 0xFF; 2.4693 + *colour = color; 2.4694 + return true; 2.4695 + } 2.4696 + else 2.4697 + { 2.4698 + if (!strnicmp(str, "rand", 4)) 2.4699 + { 2.4700 + *colour = gen_rand32() | 0xFF; //((rand()*255/RAND_MAX) << 8) | ((rand()*255/RAND_MAX) << 16) | 2.4701 + // ((rand()*255/RAND_MAX) << 24) | 0xFF; 2.4702 + return true; 2.4703 + } 2.4704 + 2.4705 + for (int i = 0; i < sizeof(s_colorMapping) / sizeof(*s_colorMapping); i++) 2.4706 + { 2.4707 + if (!stricmp(str, s_colorMapping[i].name)) 2.4708 + { 2.4709 + *colour = s_colorMapping[i].value; 2.4710 + return true; 2.4711 + } 2.4712 + } 2.4713 + } 2.4714 + 2.4715 + return false; 2.4716 +} 2.4717 + 2.4718 +static inline uint32 gui_getcolour_wrapped(lua_State *L, int offset, bool hasDefaultValue, uint32 defaultColour) 2.4719 +{ 2.4720 + switch (lua_type(L, offset)) 2.4721 + { 2.4722 + case LUA_TSTRING: 2.4723 + { 2.4724 + const char *str = lua_tostring(L, offset); 2.4725 + uint32 colour; 2.4726 + 2.4727 + if (str2colour(&colour, L, str)) 2.4728 + return colour; 2.4729 + else 2.4730 + { 2.4731 + if (hasDefaultValue) 2.4732 + return defaultColour; 2.4733 + else 2.4734 + return luaL_error(L, "unknown colour %s", str); 2.4735 + } 2.4736 + } 2.4737 + 2.4738 + case LUA_TNUMBER: 2.4739 + { 2.4740 + uint32 colour = (uint32) lua_tointeger(L, offset); 2.4741 + return colour; 2.4742 + } 2.4743 + 2.4744 + case LUA_TTABLE: 2.4745 + { 2.4746 + int color = 0xFF; 2.4747 + lua_pushnil(L); // first key 2.4748 + int keyIndex = lua_gettop(L); 2.4749 + int valueIndex = keyIndex + 1; 2.4750 + bool first = true; 2.4751 + while (lua_next(L, offset)) 2.4752 + { 2.4753 + bool keyIsString = (lua_type(L, keyIndex) == LUA_TSTRING); 2.4754 + bool keyIsNumber = (lua_type(L, keyIndex) == LUA_TNUMBER); 2.4755 + int key = keyIsString ? tolower(*lua_tostring(L, keyIndex)) : (keyIsNumber ? lua_tointeger(L, keyIndex) : 0); 2.4756 + int value = lua_tointeger(L, valueIndex); 2.4757 + if (value < 0) value = 0; 2.4758 + if (value > 255) value = 255; 2.4759 + switch (key) 2.4760 + { 2.4761 + case 1: 2.4762 + case 'r': 2.4763 + color |= value << 24; break; 2.4764 + case 2: 2.4765 + case 'g': 2.4766 + color |= value << 16; break; 2.4767 + case 3: 2.4768 + case 'b': 2.4769 + color |= value << 8; break; 2.4770 + case 4: 2.4771 + case 'a': 2.4772 + color = (color & ~0xFF) | value; break; 2.4773 + } 2.4774 + lua_pop(L, 1); 2.4775 + } 2.4776 + return color; 2.4777 + } break; 2.4778 + 2.4779 + case LUA_TFUNCTION: 2.4780 + luaL_error(L, "invalid colour"); // NYI 2.4781 + return 0; 2.4782 + 2.4783 + default: 2.4784 + if (hasDefaultValue) 2.4785 + return defaultColour; 2.4786 + else 2.4787 + return luaL_error(L, "invalid colour"); 2.4788 + } 2.4789 +} 2.4790 + 2.4791 +static uint32 gui_getcolour(lua_State *L, int offset) 2.4792 +{ 2.4793 + uint32 colour; 2.4794 + int a, r, g, b; 2.4795 + 2.4796 + colour = gui_getcolour_wrapped(L, offset, false, 0); 2.4797 + a = ((colour & 0xff) * transparencyModifier) / 255; 2.4798 + if (a > 255) 2.4799 + a = 255; 2.4800 + b = (colour >> 8) & 0xff; 2.4801 + g = (colour >> 16) & 0xff; 2.4802 + r = (colour >> 24) & 0xff; 2.4803 + return LUA_BUILD_PIXEL(a, r, g, b); 2.4804 +} 2.4805 + 2.4806 +static uint32 gui_optcolour(lua_State *L, int offset, uint32 defaultColour) 2.4807 +{ 2.4808 + uint32 colour; 2.4809 + int a, r, g, b; 2.4810 + uint8 defA, defB, defG, defR; 2.4811 + 2.4812 + LUA_DECOMPOSE_PIXEL(defaultColour, defA, defR, defG, defB); 2.4813 + defaultColour = (defR << 24) | (defG << 16) | (defB << 8) | defA; 2.4814 + 2.4815 + colour = gui_getcolour_wrapped(L, offset, true, defaultColour); 2.4816 + a = ((colour & 0xff) * transparencyModifier) / 255; 2.4817 + if (a > 255) 2.4818 + a = 255; 2.4819 + b = (colour >> 8) & 0xff; 2.4820 + g = (colour >> 16) & 0xff; 2.4821 + r = (colour >> 24) & 0xff; 2.4822 + return LUA_BUILD_PIXEL(a, r, g, b); 2.4823 +} 2.4824 2.4825 // gui.drawpixel(x,y,colour) 2.4826 - static int gui_drawpixel(lua_State *L) 2.4827 - { 2.4828 - int x = luaL_checkinteger(L, 1); 2.4829 - int y = luaL_checkinteger(L, 2); 2.4830 - 2.4831 - uint32 colour = gui_getcolour(L, 3); 2.4832 - 2.4833 - // if (!gui_check_boundary(x, y)) 2.4834 - // luaL_error(L,"bad coordinates"); 2.4835 - gui_prepare(); 2.4836 - 2.4837 - gui_drawpixel_internal(x, y, colour); 2.4838 - 2.4839 - return 0; 2.4840 - } 2.4841 +static int gui_drawpixel(lua_State *L) 2.4842 +{ 2.4843 + int x = luaL_checkinteger(L, 1); 2.4844 + int y = luaL_checkinteger(L, 2); 2.4845 + 2.4846 + uint32 colour = gui_getcolour(L, 3); 2.4847 + 2.4848 + // if (!gui_check_boundary(x, y)) 2.4849 + // luaL_error(L,"bad coordinates"); 2.4850 + gui_prepare(); 2.4851 + 2.4852 + gui_drawpixel_internal(x, y, colour); 2.4853 + 2.4854 + return 0; 2.4855 +} 2.4856 2.4857 // gui.drawline(x1,y1,x2,y2,color,skipFirst) 2.4858 - static int gui_drawline(lua_State *L) 2.4859 - { 2.4860 - int x1, y1, x2, y2; 2.4861 - uint32 color; 2.4862 - x1 = luaL_checkinteger(L, 1); 2.4863 - y1 = luaL_checkinteger(L, 2); 2.4864 - x2 = luaL_checkinteger(L, 3); 2.4865 - y2 = luaL_checkinteger(L, 4); 2.4866 - color = gui_optcolour(L, 5, LUA_BUILD_PIXEL(255, 255, 255, 255)); 2.4867 - int skipFirst = lua_toboolean(L, 6); 2.4868 - 2.4869 - gui_prepare(); 2.4870 - 2.4871 - gui_drawline_internal(x2, y2, x1, y1, !skipFirst, color); 2.4872 - 2.4873 - return 0; 2.4874 - } 2.4875 +static int gui_drawline(lua_State *L) 2.4876 +{ 2.4877 + int x1, y1, x2, y2; 2.4878 + uint32 color; 2.4879 + x1 = luaL_checkinteger(L, 1); 2.4880 + y1 = luaL_checkinteger(L, 2); 2.4881 + x2 = luaL_checkinteger(L, 3); 2.4882 + y2 = luaL_checkinteger(L, 4); 2.4883 + color = gui_optcolour(L, 5, LUA_BUILD_PIXEL(255, 255, 255, 255)); 2.4884 + int skipFirst = lua_toboolean(L, 6); 2.4885 + 2.4886 + gui_prepare(); 2.4887 + 2.4888 + gui_drawline_internal(x2, y2, x1, y1, !skipFirst, color); 2.4889 + 2.4890 + return 0; 2.4891 +} 2.4892 2.4893 // gui.drawbox(x1, y1, x2, y2, fillcolor, outlinecolor) 2.4894 - static int gui_drawbox(lua_State *L) 2.4895 - { 2.4896 - int x1, y1, x2, y2; 2.4897 - uint32 fillcolor; 2.4898 - uint32 outlinecolor; 2.4899 - 2.4900 - x1 = luaL_checkinteger(L, 1); 2.4901 - y1 = luaL_checkinteger(L, 2); 2.4902 - x2 = luaL_checkinteger(L, 3); 2.4903 - y2 = luaL_checkinteger(L, 4); 2.4904 - fillcolor = gui_optcolour(L, 5, LUA_BUILD_PIXEL(63, 255, 255, 255)); 2.4905 - outlinecolor = gui_optcolour(L, 6, LUA_BUILD_PIXEL(255, LUA_PIXEL_R(fillcolor), LUA_PIXEL_G(fillcolor), LUA_PIXEL_B(fillcolor))); 2.4906 - 2.4907 - if (x1 > x2) 2.4908 - std::swap(x1, x2); 2.4909 - if (y1 > y2) 2.4910 - std::swap(y1, y2); 2.4911 - 2.4912 - gui_prepare(); 2.4913 - 2.4914 - gui_drawbox_internal(x1, y1, x2, y2, outlinecolor); 2.4915 - if ((x2 - x1) >= 2 && (y2 - y1) >= 2) 2.4916 - gui_fillbox_internal(x1 + 1, y1 + 1, x2 - 1, y2 - 1, fillcolor); 2.4917 - 2.4918 - return 0; 2.4919 - } 2.4920 +static int gui_drawbox(lua_State *L) 2.4921 +{ 2.4922 + int x1, y1, x2, y2; 2.4923 + uint32 fillcolor; 2.4924 + uint32 outlinecolor; 2.4925 + 2.4926 + x1 = luaL_checkinteger(L, 1); 2.4927 + y1 = luaL_checkinteger(L, 2); 2.4928 + x2 = luaL_checkinteger(L, 3); 2.4929 + y2 = luaL_checkinteger(L, 4); 2.4930 + fillcolor = gui_optcolour(L, 5, LUA_BUILD_PIXEL(63, 255, 255, 255)); 2.4931 + outlinecolor = gui_optcolour(L, 6, LUA_BUILD_PIXEL(255, LUA_PIXEL_R(fillcolor), LUA_PIXEL_G(fillcolor), LUA_PIXEL_B(fillcolor))); 2.4932 + 2.4933 + if (x1 > x2) 2.4934 + std::swap(x1, x2); 2.4935 + if (y1 > y2) 2.4936 + std::swap(y1, y2); 2.4937 + 2.4938 + gui_prepare(); 2.4939 + 2.4940 + gui_drawbox_internal(x1, y1, x2, y2, outlinecolor); 2.4941 + if ((x2 - x1) >= 2 && (y2 - y1) >= 2) 2.4942 + gui_fillbox_internal(x1 + 1, y1 + 1, x2 - 1, y2 - 1, fillcolor); 2.4943 + 2.4944 + return 0; 2.4945 +} 2.4946 2.4947 // gui.drawcircle(x0, y0, radius, colour) 2.4948 - static int gui_drawcircle(lua_State *L) 2.4949 - { 2.4950 - int x, y, r; 2.4951 - uint32 colour; 2.4952 - 2.4953 - x = luaL_checkinteger(L, 1); 2.4954 - y = luaL_checkinteger(L, 2); 2.4955 - r = luaL_checkinteger(L, 3); 2.4956 - colour = gui_getcolour(L, 4); 2.4957 - 2.4958 - gui_prepare(); 2.4959 - 2.4960 - gui_drawcircle_internal(x, y, r, colour); 2.4961 - 2.4962 - return 0; 2.4963 - } 2.4964 +static int gui_drawcircle(lua_State *L) 2.4965 +{ 2.4966 + int x, y, r; 2.4967 + uint32 colour; 2.4968 + 2.4969 + x = luaL_checkinteger(L, 1); 2.4970 + y = luaL_checkinteger(L, 2); 2.4971 + r = luaL_checkinteger(L, 3); 2.4972 + colour = gui_getcolour(L, 4); 2.4973 + 2.4974 + gui_prepare(); 2.4975 + 2.4976 + gui_drawcircle_internal(x, y, r, colour); 2.4977 + 2.4978 + return 0; 2.4979 +} 2.4980 2.4981 // gui.fillbox(x1, y1, x2, y2, colour) 2.4982 - static int gui_fillbox(lua_State *L) 2.4983 - { 2.4984 - int x1, y1, x2, y2; 2.4985 - uint32 colour; 2.4986 - 2.4987 - x1 = luaL_checkinteger(L, 1); 2.4988 - y1 = luaL_checkinteger(L, 2); 2.4989 - x2 = luaL_checkinteger(L, 3); 2.4990 - y2 = luaL_checkinteger(L, 4); 2.4991 - colour = gui_getcolour(L, 5); 2.4992 - 2.4993 - // if (!gui_check_boundary(x1, y1)) 2.4994 - // luaL_error(L,"bad coordinates"); 2.4995 - // 2.4996 - // if (!gui_check_boundary(x2, y2)) 2.4997 - // luaL_error(L,"bad coordinates"); 2.4998 - gui_prepare(); 2.4999 - 2.5000 - if (!gui_checkbox(x1, y1, x2, y2)) 2.5001 - return 0; 2.5002 - 2.5003 - gui_fillbox_internal(x1, y1, x2, y2, colour); 2.5004 - 2.5005 - return 0; 2.5006 - } 2.5007 +static int gui_fillbox(lua_State *L) 2.5008 +{ 2.5009 + int x1, y1, x2, y2; 2.5010 + uint32 colour; 2.5011 + 2.5012 + x1 = luaL_checkinteger(L, 1); 2.5013 + y1 = luaL_checkinteger(L, 2); 2.5014 + x2 = luaL_checkinteger(L, 3); 2.5015 + y2 = luaL_checkinteger(L, 4); 2.5016 + colour = gui_getcolour(L, 5); 2.5017 + 2.5018 + // if (!gui_check_boundary(x1, y1)) 2.5019 + // luaL_error(L,"bad coordinates"); 2.5020 + // 2.5021 + // if (!gui_check_boundary(x2, y2)) 2.5022 + // luaL_error(L,"bad coordinates"); 2.5023 + gui_prepare(); 2.5024 + 2.5025 + if (!gui_checkbox(x1, y1, x2, y2)) 2.5026 + return 0; 2.5027 + 2.5028 + gui_fillbox_internal(x1, y1, x2, y2, colour); 2.5029 + 2.5030 + return 0; 2.5031 +} 2.5032 2.5033 // gui.fillcircle(x0, y0, radius, colour) 2.5034 - static int gui_fillcircle(lua_State *L) 2.5035 - { 2.5036 - int x, y, r; 2.5037 - uint32 colour; 2.5038 - 2.5039 - x = luaL_checkinteger(L, 1); 2.5040 - y = luaL_checkinteger(L, 2); 2.5041 - r = luaL_checkinteger(L, 3); 2.5042 - colour = gui_getcolour(L, 4); 2.5043 - 2.5044 - gui_prepare(); 2.5045 - 2.5046 - gui_fillcircle_internal(x, y, r, colour); 2.5047 - 2.5048 - return 0; 2.5049 - } 2.5050 - 2.5051 - static int gui_getpixel(lua_State *L) 2.5052 - { 2.5053 - int x = luaL_checkinteger(L, 1); 2.5054 - int y = luaL_checkinteger(L, 2); 2.5055 - 2.5056 - int pixWidth = 240, pixHeight = 160; 2.5057 - int scrWidth = 240, scrHeight = 160; 2.5058 - int scrOffsetX = 0, scrOffsetY = 0; 2.5059 - int pitch; 2.5060 - if (!systemIsRunningGBA()) 2.5061 - { 2.5062 - if (gbBorderOn) 2.5063 - { 2.5064 - pixWidth = 256, pixHeight = 224; 2.5065 - scrOffsetX = 48, scrOffsetY = 40; 2.5066 - } 2.5067 - else 2.5068 - { 2.5069 - pixWidth = 160, pixHeight = 144; 2.5070 - } 2.5071 - scrWidth = 160, scrHeight = 144; 2.5072 - } 2.5073 - pitch = pixWidth * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); 2.5074 - scrOffsetY++; // don't know why it's needed 2.5075 - 2.5076 - if (!(x >= 0 && y >= 0 && x < scrWidth && y < scrHeight) /*!gui_check_boundary(x,y)*/) 2.5077 - { 2.5078 - lua_pushinteger(L, 0); 2.5079 - lua_pushinteger(L, 0); 2.5080 - lua_pushinteger(L, 0); 2.5081 - } 2.5082 - else 2.5083 - { 2.5084 - switch (systemColorDepth) 2.5085 - { 2.5086 - case 16: 2.5087 - { 2.5088 - uint16 *screen = (uint16 *) (&pix[scrOffsetY * pitch + scrOffsetX * 2]); 2.5089 - uint16 pixColor = screen[y * pitch / 2 + x]; 2.5090 - lua_pushinteger(L, (pixColor >> 8) & 0xF8); // red 2.5091 - lua_pushinteger(L, (pixColor >> 3) & 0xFC); // green 2.5092 - lua_pushinteger(L, (pixColor << 3) & 0xF8); // blue 2.5093 - } 2.5094 - break; 2.5095 - case 24: 2.5096 - { 2.5097 - uint8 *screen = &pix[scrOffsetY * pitch + scrOffsetX * 3]; 2.5098 - lua_pushinteger(L, screen[y * pitch + x * 3 + 2]); // red 2.5099 - lua_pushinteger(L, screen[y * pitch + x * 3 + 1]); // green 2.5100 - lua_pushinteger(L, screen[y * pitch + x * 3 + 0]); // blue 2.5101 - } 2.5102 - break; 2.5103 - case 32: 2.5104 - { 2.5105 - uint8 *screen = &pix[scrOffsetY * pitch + scrOffsetX * 4]; 2.5106 - lua_pushinteger(L, screen[y * pitch + x * 4 + 2]); // red 2.5107 - lua_pushinteger(L, screen[y * pitch + x * 4 + 1]); // green 2.5108 - lua_pushinteger(L, screen[y * pitch + x * 4 + 0]); // blue 2.5109 - } 2.5110 - break; 2.5111 - default: 2.5112 - lua_pushinteger(L, 0); 2.5113 - lua_pushinteger(L, 0); 2.5114 - lua_pushinteger(L, 0); 2.5115 - break; 2.5116 - } 2.5117 - } 2.5118 - return 3; 2.5119 - } 2.5120 - 2.5121 - static int gui_parsecolor(lua_State *L) 2.5122 - { 2.5123 - int r, g, b, a; 2.5124 - uint32 color = gui_getcolour(L, 1); 2.5125 - LUA_DECOMPOSE_PIXEL(color, a, r, g, b); 2.5126 - lua_pushinteger(L, r); 2.5127 - lua_pushinteger(L, g); 2.5128 - lua_pushinteger(L, b); 2.5129 - lua_pushinteger(L, a); 2.5130 - return 4; 2.5131 - } 2.5132 +static int gui_fillcircle(lua_State *L) 2.5133 +{ 2.5134 + int x, y, r; 2.5135 + uint32 colour; 2.5136 + 2.5137 + x = luaL_checkinteger(L, 1); 2.5138 + y = luaL_checkinteger(L, 2); 2.5139 + r = luaL_checkinteger(L, 3); 2.5140 + colour = gui_getcolour(L, 4); 2.5141 + 2.5142 + gui_prepare(); 2.5143 + 2.5144 + gui_fillcircle_internal(x, y, r, colour); 2.5145 + 2.5146 + return 0; 2.5147 +} 2.5148 + 2.5149 +static int gui_getpixel(lua_State *L) 2.5150 +{ 2.5151 + int x = luaL_checkinteger(L, 1); 2.5152 + int y = luaL_checkinteger(L, 2); 2.5153 + 2.5154 + int pixWidth = 240, pixHeight = 160; 2.5155 + int scrWidth = 240, scrHeight = 160; 2.5156 + int scrOffsetX = 0, scrOffsetY = 0; 2.5157 + int pitch; 2.5158 + if (!systemIsRunningGBA()) 2.5159 + { 2.5160 + if (gbBorderOn) 2.5161 + { 2.5162 + pixWidth = 256, pixHeight = 224; 2.5163 + scrOffsetX = 48, scrOffsetY = 40; 2.5164 + } 2.5165 + else 2.5166 + { 2.5167 + pixWidth = 160, pixHeight = 144; 2.5168 + } 2.5169 + scrWidth = 160, scrHeight = 144; 2.5170 + } 2.5171 + pitch = pixWidth * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); 2.5172 + scrOffsetY++; // don't know why it's needed 2.5173 + 2.5174 + if (!(x >= 0 && y >= 0 && x < scrWidth && y < scrHeight) /*!gui_check_boundary(x,y)*/) 2.5175 + { 2.5176 + lua_pushinteger(L, 0); 2.5177 + lua_pushinteger(L, 0); 2.5178 + lua_pushinteger(L, 0); 2.5179 + } 2.5180 + else 2.5181 + { 2.5182 + switch (systemColorDepth) 2.5183 + { 2.5184 + case 16: 2.5185 + { 2.5186 + uint16 *screen = (uint16 *) (&pix[scrOffsetY * pitch + scrOffsetX * 2]); 2.5187 + uint16 pixColor = screen[y * pitch / 2 + x]; 2.5188 + lua_pushinteger(L, (pixColor >> 8) & 0xF8); // red 2.5189 + lua_pushinteger(L, (pixColor >> 3) & 0xFC); // green 2.5190 + lua_pushinteger(L, (pixColor << 3) & 0xF8); // blue 2.5191 + } 2.5192 + break; 2.5193 + case 24: 2.5194 + { 2.5195 + uint8 *screen = &pix[scrOffsetY * pitch + scrOffsetX * 3]; 2.5196 + lua_pushinteger(L, screen[y * pitch + x * 3 + 2]); // red 2.5197 + lua_pushinteger(L, screen[y * pitch + x * 3 + 1]); // green 2.5198 + lua_pushinteger(L, screen[y * pitch + x * 3 + 0]); // blue 2.5199 + } 2.5200 + break; 2.5201 + case 32: 2.5202 + { 2.5203 + uint8 *screen = &pix[scrOffsetY * pitch + scrOffsetX * 4]; 2.5204 + lua_pushinteger(L, screen[y * pitch + x * 4 + 2]); // red 2.5205 + lua_pushinteger(L, screen[y * pitch + x * 4 + 1]); // green 2.5206 + lua_pushinteger(L, screen[y * pitch + x * 4 + 0]); // blue 2.5207 + } 2.5208 + break; 2.5209 + default: 2.5210 + lua_pushinteger(L, 0); 2.5211 + lua_pushinteger(L, 0); 2.5212 + lua_pushinteger(L, 0); 2.5213 + break; 2.5214 + } 2.5215 + } 2.5216 + return 3; 2.5217 +} 2.5218 + 2.5219 +static int gui_parsecolor(lua_State *L) 2.5220 +{ 2.5221 + int r, g, b, a; 2.5222 + uint32 color = gui_getcolour(L, 1); 2.5223 + LUA_DECOMPOSE_PIXEL(color, a, r, g, b); 2.5224 + lua_pushinteger(L, r); 2.5225 + lua_pushinteger(L, g); 2.5226 + lua_pushinteger(L, b); 2.5227 + lua_pushinteger(L, a); 2.5228 + return 4; 2.5229 +} 2.5230 2.5231 // gui.gdscreenshot() 2.5232 // 2.5233 @@ -2915,66 +2915,66 @@ 2.5234 // It really is easier that way. 2.5235 2.5236 // example: gd.createFromGdStr(gui.gdscreenshot()):png("outputimage.png") 2.5237 - static int gui_gdscreenshot(lua_State *L) 2.5238 - { 2.5239 - int xofs = 0, yofs = 0, ppl = 240, width = 240, height = 160; 2.5240 - if (!systemIsRunningGBA()) 2.5241 - { 2.5242 - if (gbBorderOn) 2.5243 - xofs = 48, yofs = 40, ppl = 256; 2.5244 - else 2.5245 - ppl = 160; 2.5246 - width = 160, height = 144; 2.5247 - } 2.5248 - 2.5249 - yofs++; 2.5250 - 2.5251 - //int pitch = (((ppl * systemColorDepth + 7)>>3)+3)&~3; 2.5252 - int pitch = ppl * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); 2.5253 - uint8 *screen = &pix[yofs * pitch + xofs * (systemColorDepth / 8)]; 2.5254 - 2.5255 - int size = 11 + width * height * 4; 2.5256 - char *str = new char[size + 1]; 2.5257 - str[size] = 0; 2.5258 - 2.5259 - unsigned char *ptr = (unsigned char *)str; 2.5260 - 2.5261 - // GD format header for truecolor image (11 bytes) 2.5262 - *ptr++ = (65534 >> 8) & 0xFF; 2.5263 - *ptr++ = (65534) & 0xFF; 2.5264 - *ptr++ = (width >> 8) & 0xFF; 2.5265 - *ptr++ = (width) & 0xFF; 2.5266 - *ptr++ = (height >> 8) & 0xFF; 2.5267 - *ptr++ = (height) & 0xFF; 2.5268 - *ptr++ = 1; 2.5269 - *ptr++ = 255; 2.5270 - *ptr++ = 255; 2.5271 - *ptr++ = 255; 2.5272 - *ptr++ = 255; 2.5273 - 2.5274 - GetColorFunc getColor; 2.5275 - getColorIOFunc(systemColorDepth, &getColor, NULL); 2.5276 - 2.5277 - int x, y; 2.5278 - for (y = 0; y < height; y++) 2.5279 - { 2.5280 - uint8 *s = &screen[y * pitch]; 2.5281 - for (x = 0; x < width; x++, s += systemColorDepth / 8) 2.5282 - { 2.5283 - uint8 r, g, b; 2.5284 - getColor(s, &r, &g, &b); 2.5285 - 2.5286 - *ptr++ = 0; 2.5287 - *ptr++ = r; 2.5288 - *ptr++ = g; 2.5289 - *ptr++ = b; 2.5290 - } 2.5291 - } 2.5292 - 2.5293 - lua_pushlstring(L, str, size); 2.5294 - delete[] str; 2.5295 - return 1; 2.5296 - } 2.5297 +static int gui_gdscreenshot(lua_State *L) 2.5298 +{ 2.5299 + int xofs = 0, yofs = 0, ppl = 240, width = 240, height = 160; 2.5300 + if (!systemIsRunningGBA()) 2.5301 + { 2.5302 + if (gbBorderOn) 2.5303 + xofs = 48, yofs = 40, ppl = 256; 2.5304 + else 2.5305 + ppl = 160; 2.5306 + width = 160, height = 144; 2.5307 + } 2.5308 + 2.5309 + yofs++; 2.5310 + 2.5311 + //int pitch = (((ppl * systemColorDepth + 7)>>3)+3)&~3; 2.5312 + int pitch = ppl * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); 2.5313 + uint8 *screen = &pix[yofs * pitch + xofs * (systemColorDepth / 8)]; 2.5314 + 2.5315 + int size = 11 + width * height * 4; 2.5316 + char *str = new char[size + 1]; 2.5317 + str[size] = 0; 2.5318 + 2.5319 + unsigned char *ptr = (unsigned char *)str; 2.5320 + 2.5321 + // GD format header for truecolor image (11 bytes) 2.5322 + *ptr++ = (65534 >> 8) & 0xFF; 2.5323 + *ptr++ = (65534) & 0xFF; 2.5324 + *ptr++ = (width >> 8) & 0xFF; 2.5325 + *ptr++ = (width) & 0xFF; 2.5326 + *ptr++ = (height >> 8) & 0xFF; 2.5327 + *ptr++ = (height) & 0xFF; 2.5328 + *ptr++ = 1; 2.5329 + *ptr++ = 255; 2.5330 + *ptr++ = 255; 2.5331 + *ptr++ = 255; 2.5332 + *ptr++ = 255; 2.5333 + 2.5334 + GetColorFunc getColor; 2.5335 + getColorIOFunc(systemColorDepth, &getColor, NULL); 2.5336 + 2.5337 + int x, y; 2.5338 + for (y = 0; y < height; y++) 2.5339 + { 2.5340 + uint8 *s = &screen[y * pitch]; 2.5341 + for (x = 0; x < width; x++, s += systemColorDepth / 8) 2.5342 + { 2.5343 + uint8 r, g, b; 2.5344 + getColor(s, &r, &g, &b); 2.5345 + 2.5346 + *ptr++ = 0; 2.5347 + *ptr++ = r; 2.5348 + *ptr++ = g; 2.5349 + *ptr++ = b; 2.5350 + } 2.5351 + } 2.5352 + 2.5353 + lua_pushlstring(L, str, size); 2.5354 + delete[] str; 2.5355 + return 1; 2.5356 +} 2.5357 2.5358 // gui.opacity(number alphaValue) 2.5359 // sets the transparency of subsequent draw calls 2.5360 @@ -2984,472 +2984,472 @@ 2.5361 // because you can provide an alpha value in the color argument of each draw call. 2.5362 2.5363 // however, it can be convenient to be able to globally modify the drawing transparency 2.5364 - static int gui_setopacity(lua_State *L) 2.5365 - { 2.5366 - double opacF = luaL_checknumber(L, 1); 2.5367 - transparencyModifier = (int)(opacF * 255); 2.5368 - if (transparencyModifier < 0) 2.5369 - transparencyModifier = 0; 2.5370 - return 0; 2.5371 - } 2.5372 +static int gui_setopacity(lua_State *L) 2.5373 +{ 2.5374 + double opacF = luaL_checknumber(L, 1); 2.5375 + transparencyModifier = (int)(opacF * 255); 2.5376 + if (transparencyModifier < 0) 2.5377 + transparencyModifier = 0; 2.5378 + return 0; 2.5379 +} 2.5380 2.5381 // gui.transparency(int strength) 2.5382 // 2.5383 2.5384 // 0 = solid, 2.5385 - static int gui_transparency(lua_State *L) 2.5386 - { 2.5387 - double trans = luaL_checknumber(L, 1); 2.5388 - transparencyModifier = (int)((4.0 - trans) / 4.0 * 255); 2.5389 - if (transparencyModifier < 0) 2.5390 - transparencyModifier = 0; 2.5391 - return 0; 2.5392 - } 2.5393 - 2.5394 - static const uint32 Small_Font_Data[] = 2.5395 - { 2.5396 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 32 2.5397 - 0x00000000, 0x00000300, 0x00000400, 0x00000500, 0x00000000, 0x00000700, 0x00000000, // 33 ! 2.5398 - 0x00000000, 0x00040002, 0x00050003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 34 " 2.5399 - 0x00000000, 0x00040002, 0x00050403, 0x00060004, 0x00070605, 0x00080006, 0x00000000, // 35 # 2.5400 - 0x00000000, 0x00040300, 0x00000403, 0x00000500, 0x00070600, 0x00000706, 0x00000000, // 36 $ 2.5401 - 0x00000000, 0x00000002, 0x00050000, 0x00000500, 0x00000005, 0x00080000, 0x00000000, // 37 % 2.5402 - 0x00000000, 0x00000300, 0x00050003, 0x00000500, 0x00070005, 0x00080700, 0x00000000, // 38 & 2.5403 - 0x00000000, 0x00000300, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 39 ' 2.5404 - 0x00000000, 0x00000300, 0x00000003, 0x00000004, 0x00000005, 0x00000700, 0x00000000, // 40 ( 2.5405 - 0x00000000, 0x00000300, 0x00050000, 0x00060000, 0x00070000, 0x00000700, 0x00000000, // 41 ) 2.5406 - 0x00000000, 0x00000000, 0x00000400, 0x00060504, 0x00000600, 0x00080006, 0x00000000, // 42 * 2.5407 - 0x00000000, 0x00000000, 0x00000400, 0x00060504, 0x00000600, 0x00000000, 0x00000000, // 43 + 2.5408 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000600, 0x00000700, 0x00000007, // 44 , 2.5409 - 0x00000000, 0x00000000, 0x00000000, 0x00060504, 0x00000000, 0x00000000, 0x00000000, // 45 - 2.5410 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000700, 0x00000000, // 46 . 2.5411 - 0x00030000, 0x00040000, 0x00000400, 0x00000500, 0x00000005, 0x00000006, 0x00000000, // 47 / 2.5412 - 0x00000000, 0x00000300, 0x00050003, 0x00060004, 0x00070005, 0x00000700, 0x00000000, // 48 0 2.5413 - 0x00000000, 0x00000300, 0x00000403, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 49 1 2.5414 - 0x00000000, 0x00000302, 0x00050000, 0x00000500, 0x00000005, 0x00080706, 0x00000000, // 50 2 2.5415 - 0x00000000, 0x00000302, 0x00050000, 0x00000504, 0x00070000, 0x00000706, 0x00000000, // 51 3 2.5416 - 0x00000000, 0x00000300, 0x00000003, 0x00060004, 0x00070605, 0x00080000, 0x00000000, // 52 4 2.5417 - 0x00000000, 0x00040302, 0x00000003, 0x00000504, 0x00070000, 0x00000706, 0x00000000, // 53 5 2.5418 - 0x00000000, 0x00000300, 0x00000003, 0x00000504, 0x00070005, 0x00000700, 0x00000000, // 54 6 2.5419 - 0x00000000, 0x00040302, 0x00050000, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 55 7 2.5420 - 0x00000000, 0x00000300, 0x00050003, 0x00000500, 0x00070005, 0x00000700, 0x00000000, // 56 8 2.5421 - 0x00000000, 0x00000300, 0x00050003, 0x00060500, 0x00070000, 0x00000700, 0x00000000, // 57 9 2.5422 - 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000700, 0x00000000, // 58 : 2.5423 - 0x00000000, 0x00000000, 0x00000000, 0x00000500, 0x00000000, 0x00000700, 0x00000007, // 59 ; 2.5424 - 0x00000000, 0x00040000, 0x00000400, 0x00000004, 0x00000600, 0x00080000, 0x00000000, // 60 < 2.5425 - 0x00000000, 0x00000000, 0x00050403, 0x00000000, 0x00070605, 0x00000000, 0x00000000, // 61 = 2.5426 - 0x00000000, 0x00000002, 0x00000400, 0x00060000, 0x00000600, 0x00000006, 0x00000000, // 62 > 2.5427 - 0x00000000, 0x00000302, 0x00050000, 0x00000500, 0x00000000, 0x00000700, 0x00000000, // 63 ? 2.5428 - 0x00000000, 0x00000300, 0x00050400, 0x00060004, 0x00070600, 0x00000000, 0x00000000, // 64 @ 2.5429 - 0x00000000, 0x00000300, 0x00050003, 0x00060504, 0x00070005, 0x00080006, 0x00000000, // 65 A 2.5430 - 0x00000000, 0x00000302, 0x00050003, 0x00000504, 0x00070005, 0x00000706, 0x00000000, // 66 B 2.5431 - 0x00000000, 0x00040300, 0x00000003, 0x00000004, 0x00000005, 0x00080700, 0x00000000, // 67 C 2.5432 - 0x00000000, 0x00000302, 0x00050003, 0x00060004, 0x00070005, 0x00000706, 0x00000000, // 68 D 2.5433 - 0x00000000, 0x00040302, 0x00000003, 0x00000504, 0x00000005, 0x00080706, 0x00000000, // 69 E 2.5434 - 0x00000000, 0x00040302, 0x00000003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 70 F 2.5435 - 0x00000000, 0x00040300, 0x00000003, 0x00060004, 0x00070005, 0x00080700, 0x00000000, // 71 G 2.5436 - 0x00000000, 0x00040002, 0x00050003, 0x00060504, 0x00070005, 0x00080006, 0x00000000, // 72 H 2.5437 - 0x00000000, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 73 I 2.5438 - 0x00000000, 0x00040000, 0x00050000, 0x00060000, 0x00070005, 0x00000700, 0x00000000, // 74 J 2.5439 - 0x00000000, 0x00040002, 0x00050003, 0x00000504, 0x00070005, 0x00080006, 0x00000000, // 75 K 2.5440 - 0x00000000, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00080706, 0x00000000, // 76 l 2.5441 - 0x00000000, 0x00040002, 0x00050403, 0x00060004, 0x00070005, 0x00080006, 0x00000000, // 77 M 2.5442 - 0x00000000, 0x00000302, 0x00050003, 0x00060004, 0x00070005, 0x00080006, 0x00000000, // 78 N 2.5443 - 0x00000000, 0x00040302, 0x00050003, 0x00060004, 0x00070005, 0x00080706, 0x00000000, // 79 O 2.5444 - 0x00000000, 0x00000302, 0x00050003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 80 P 2.5445 - 0x00000000, 0x00040302, 0x00050003, 0x00060004, 0x00070005, 0x00080706, 0x00090000, // 81 Q 2.5446 - 0x00000000, 0x00000302, 0x00050003, 0x00000504, 0x00070005, 0x00080006, 0x00000000, // 82 R 2.5447 - 0x00000000, 0x00040300, 0x00000003, 0x00000500, 0x00070000, 0x00000706, 0x00000000, // 83 S 2.5448 - 0x00000000, 0x00040302, 0x00000400, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 84 T 2.5449 - 0x00000000, 0x00040002, 0x00050003, 0x00060004, 0x00070005, 0x00080706, 0x00000000, // 85 U 2.5450 - 0x00000000, 0x00040002, 0x00050003, 0x00060004, 0x00000600, 0x00000700, 0x00000000, // 86 V 2.5451 - 0x00000000, 0x00040002, 0x00050003, 0x00060004, 0x00070605, 0x00080006, 0x00000000, // 87 W 2.5452 - 0x00000000, 0x00040002, 0x00050003, 0x00000500, 0x00070005, 0x00080006, 0x00000000, // 88 X 2.5453 - 0x00000000, 0x00040002, 0x00050003, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 89 Y 2.5454 - 0x00000000, 0x00040302, 0x00050000, 0x00000500, 0x00000005, 0x00080706, 0x00000000, // 90 Z 2.5455 - 0x00000000, 0x00040300, 0x00000400, 0x00000500, 0x00000600, 0x00080700, 0x00000000, // 91 [ 2.5456 - 0x00000000, 0x00000002, 0x00000400, 0x00000500, 0x00070000, 0x00080000, 0x00000000, // 92 '\' 2.5457 - 0x00000000, 0x00000302, 0x00000400, 0x00000500, 0x00000600, 0x00000706, 0x00000000, // 93 ] 2.5458 - 0x00000000, 0x00000300, 0x00050003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 94 ^ 2.5459 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080706, 0x00000000, // 95 _ 2.5460 - 0x00000000, 0x00000002, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 96 ` 2.5461 - 0x00000000, 0x00000000, 0x00050400, 0x00060004, 0x00070005, 0x00080700, 0x00000000, // 97 a 2.5462 - 0x00000000, 0x00000002, 0x00000003, 0x00000504, 0x00070005, 0x00000706, 0x00000000, // 98 b 2.5463 - 0x00000000, 0x00000000, 0x00050400, 0x00000004, 0x00000005, 0x00080700, 0x00000000, // 99 c 2.5464 - 0x00000000, 0x00040000, 0x00050000, 0x00060500, 0x00070005, 0x00080700, 0x00000000, // 100 d 2.5465 - 0x00000000, 0x00000000, 0x00050400, 0x00060504, 0x00000005, 0x00080700, 0x00000000, // 101 e 2.5466 - 0x00000000, 0x00040300, 0x00000003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 102 f 2.5467 - 0x00000000, 0x00000000, 0x00050400, 0x00060004, 0x00070600, 0x00080000, 0x00000807, // 103 g 2.5468 - 0x00000000, 0x00000002, 0x00000003, 0x00000504, 0x00070005, 0x00080006, 0x00000000, // 104 h 2.5469 - 0x00000000, 0x00000300, 0x00000000, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 105 i 2.5470 - 0x00000000, 0x00000300, 0x00000000, 0x00000500, 0x00000600, 0x00000700, 0x00000007, // 106 j 2.5471 - 0x00000000, 0x00000002, 0x00000003, 0x00060004, 0x00000605, 0x00080006, 0x00000000, // 107 k 2.5472 - 0x00000000, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00080000, 0x00000000, // 108 l 2.5473 - 0x00000000, 0x00000000, 0x00050003, 0x00060504, 0x00070005, 0x00080006, 0x00000000, // 109 m 2.5474 - 0x00000000, 0x00000000, 0x00000403, 0x00060004, 0x00070005, 0x00080006, 0x00000000, // 110 n 2.5475 - 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00070005, 0x00000700, 0x00000000, // 111 o 2.5476 - 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00000605, 0x00000006, 0x00000007, // 112 p 2.5477 - 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00070600, 0x00080000, 0x00090000, // 113 q 2.5478 - 0x00000000, 0x00000000, 0x00050003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 114 r 2.5479 - 0x00000000, 0x00000000, 0x00050400, 0x00000004, 0x00070600, 0x00000706, 0x00000000, // 115 s 2.5480 - 0x00000000, 0x00000300, 0x00050403, 0x00000500, 0x00000600, 0x00080000, 0x00000000, // 116 t 2.5481 - 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00070005, 0x00080700, 0x00000000, // 117 u 2.5482 - 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00070005, 0x00000700, 0x00000000, // 118 v 2.5483 - 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00070605, 0x00080006, 0x00000000, // 119 w 2.5484 - 0x00000000, 0x00000000, 0x00050003, 0x00000500, 0x00070005, 0x00080006, 0x00000000, // 120 x 2.5485 - 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00000600, 0x00000700, 0x00000007, // 121 y 2.5486 - 0x00000000, 0x00000000, 0x00050403, 0x00000500, 0x00000005, 0x00080706, 0x00000000, // 122 z 2.5487 - 0x00000000, 0x00040300, 0x00000400, 0x00000504, 0x00000600, 0x00080700, 0x00000000, // 123 { 2.5488 - 0x00000000, 0x00000300, 0x00000400, 0x00000000, 0x00000600, 0x00000700, 0x00000000, // 124 | 2.5489 - 0x00000000, 0x00000302, 0x00000400, 0x00060500, 0x00000600, 0x00000706, 0x00000000, // 125 } 2.5490 - 0x00000000, 0x00000302, 0x00050000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 126 ~ 2.5491 - 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00070605, 0x00000000, 0x00000000, // 127 2.5492 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.5493 - }; 2.5494 - 2.5495 - static void PutTextInternal(const char *str, int len, short x, short y, int color, int backcolor) 2.5496 - { 2.5497 - int Opac = (color >> 24) & 0xFF; 2.5498 - int backOpac = (backcolor >> 24) & 0xFF; 2.5499 - int origX = x; 2.5500 - 2.5501 - if (!Opac && !backOpac) 2.5502 - return; 2.5503 - 2.5504 - while (*str && len && y < LUA_SCREEN_HEIGHT) 2.5505 - { 2.5506 - int c = *str++; 2.5507 - while (x > LUA_SCREEN_WIDTH && c != '\n') 2.5508 - { 2.5509 - c = *str; 2.5510 - if (c == '\0') 2.5511 - break; 2.5512 - str++; 2.5513 - } 2.5514 - 2.5515 - if (c == '\n') 2.5516 - { 2.5517 - x = origX; 2.5518 - y += 8; 2.5519 - continue; 2.5520 - } 2.5521 - else if (c == '\t') // just in case 2.5522 - { 2.5523 - const int tabSpace = 8; 2.5524 - x += (tabSpace - (((x - origX) / 4) % tabSpace)) * 4; 2.5525 - continue; 2.5526 - } 2.5527 - 2.5528 - if ((unsigned int)(c - 32) >= 96) 2.5529 - continue; 2.5530 - 2.5531 - const unsigned char *Cur_Glyph = (const unsigned char *) &Small_Font_Data + (c - 32) * 7 * 4; 2.5532 - 2.5533 - for (int y2 = 0; y2 < 8; y2++) 2.5534 - { 2.5535 - unsigned int glyphLine = *((unsigned int *)Cur_Glyph + y2); 2.5536 - for (int x2 = -1; x2 < 4; x2++) 2.5537 - { 2.5538 - int shift = x2 << 3; 2.5539 - int mask = 0xFF << shift; 2.5540 - int intensity = (glyphLine & mask) >> shift; 2.5541 - 2.5542 - if (intensity && x2 >= 0 && y2 < 7) 2.5543 - { 2.5544 - //int xdraw = max(0,min(LUA_SCREEN_WIDTH - 1,x+x2)); 2.5545 - //int ydraw = max(0,min(LUA_SCREEN_HEIGHT - 1,y+y2)); 2.5546 - //gui_drawpixel_fast(xdraw, ydraw, color); 2.5547 - gui_drawpixel_internal(x + x2, y + y2, color); 2.5548 - } 2.5549 - else if (backOpac) 2.5550 - { 2.5551 - for (int y3 = max(0, y2 - 1); y3 <= min(6, y2 + 1); y3++) 2.5552 - { 2.5553 - unsigned int glyphLine = *((unsigned int *)Cur_Glyph + y3); 2.5554 - for (int x3 = max(0, x2 - 1); x3 <= min(3, x2 + 1); x3++) 2.5555 - { 2.5556 - int shift = x3 << 3; 2.5557 - int mask = 0xFF << shift; 2.5558 - intensity |= (glyphLine & mask) >> shift; 2.5559 - if (intensity) 2.5560 - goto draw_outline; // speedup? 2.5561 - } 2.5562 - } 2.5563 - 2.5564 -draw_outline: 2.5565 - if (intensity) 2.5566 - { 2.5567 - //int xdraw = max(0,min(LUA_SCREEN_WIDTH - 1,x+x2)); 2.5568 - //int ydraw = max(0,min(LUA_SCREEN_HEIGHT - 1,y+y2)); 2.5569 - //gui_drawpixel_fast(xdraw, ydraw, backcolor); 2.5570 - gui_drawpixel_internal(x + x2, y + y2, backcolor); 2.5571 - } 2.5572 - } 2.5573 - } 2.5574 - } 2.5575 - 2.5576 - x += 4; 2.5577 - len--; 2.5578 - } 2.5579 - } 2.5580 - 2.5581 - static int strlinelen(const char *string) 2.5582 - { 2.5583 - const char *s = string; 2.5584 - while (*s && *s != '\n') 2.5585 - s++; 2.5586 - if (*s) 2.5587 - s++; 2.5588 - return s - string; 2.5589 - } 2.5590 - 2.5591 - static void LuaDisplayString(const char *string, int y, int x, uint32 color, uint32 outlineColor) 2.5592 - { 2.5593 - if (!string) 2.5594 - return; 2.5595 - 2.5596 - gui_prepare(); 2.5597 - 2.5598 - PutTextInternal(string, strlen(string), x, y, color, outlineColor); 2.5599 - 2.5600 - /* 2.5601 - const char* ptr = string; 2.5602 - while(*ptr && y < LUA_SCREEN_HEIGHT) 2.5603 - { 2.5604 - int len = strlinelen(ptr); 2.5605 - int skip = 0; 2.5606 - if(len < 1) len = 1; 2.5607 - 2.5608 - // break up the line if it's too long to display otherwise 2.5609 - if(len > 63) 2.5610 - { 2.5611 - len = 63; 2.5612 - const char* ptr2 = ptr + len-1; 2.5613 - for(int j = len-1; j; j--, ptr2--) 2.5614 - { 2.5615 - if(*ptr2 == ' ' || *ptr2 == '\t') 2.5616 - { 2.5617 - len = j; 2.5618 - skip = 1; 2.5619 - break; 2.5620 - } 2.5621 - } 2.5622 - } 2.5623 - 2.5624 - int xl = 0; 2.5625 - int yl = 0; 2.5626 - int xh = (LUA_SCREEN_WIDTH - 1 - 1) - 4*len; 2.5627 - int yh = LUA_SCREEN_HEIGHT - 1; 2.5628 - int x2 = min(max(x,xl),xh); 2.5629 - int y2 = min(max(y,yl),yh); 2.5630 - 2.5631 - PutTextInternal(ptr,len,x2,y2,color,outlineColor); 2.5632 - 2.5633 - ptr += len + skip; 2.5634 - y += 8; 2.5635 - } 2.5636 - */ 2.5637 - } 2.5638 +static int gui_transparency(lua_State *L) 2.5639 +{ 2.5640 + double trans = luaL_checknumber(L, 1); 2.5641 + transparencyModifier = (int)((4.0 - trans) / 4.0 * 255); 2.5642 + if (transparencyModifier < 0) 2.5643 + transparencyModifier = 0; 2.5644 + return 0; 2.5645 +} 2.5646 + 2.5647 +static const uint32 Small_Font_Data[] = 2.5648 + { 2.5649 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 32 2.5650 + 0x00000000, 0x00000300, 0x00000400, 0x00000500, 0x00000000, 0x00000700, 0x00000000, // 33 ! 2.5651 + 0x00000000, 0x00040002, 0x00050003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 34 " 2.5652 + 0x00000000, 0x00040002, 0x00050403, 0x00060004, 0x00070605, 0x00080006, 0x00000000, // 35 # 2.5653 + 0x00000000, 0x00040300, 0x00000403, 0x00000500, 0x00070600, 0x00000706, 0x00000000, // 36 $ 2.5654 + 0x00000000, 0x00000002, 0x00050000, 0x00000500, 0x00000005, 0x00080000, 0x00000000, // 37 % 2.5655 + 0x00000000, 0x00000300, 0x00050003, 0x00000500, 0x00070005, 0x00080700, 0x00000000, // 38 & 2.5656 + 0x00000000, 0x00000300, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 39 ' 2.5657 + 0x00000000, 0x00000300, 0x00000003, 0x00000004, 0x00000005, 0x00000700, 0x00000000, // 40 ( 2.5658 + 0x00000000, 0x00000300, 0x00050000, 0x00060000, 0x00070000, 0x00000700, 0x00000000, // 41 ) 2.5659 + 0x00000000, 0x00000000, 0x00000400, 0x00060504, 0x00000600, 0x00080006, 0x00000000, // 42 * 2.5660 + 0x00000000, 0x00000000, 0x00000400, 0x00060504, 0x00000600, 0x00000000, 0x00000000, // 43 + 2.5661 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000600, 0x00000700, 0x00000007, // 44 , 2.5662 + 0x00000000, 0x00000000, 0x00000000, 0x00060504, 0x00000000, 0x00000000, 0x00000000, // 45 - 2.5663 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000700, 0x00000000, // 46 . 2.5664 + 0x00030000, 0x00040000, 0x00000400, 0x00000500, 0x00000005, 0x00000006, 0x00000000, // 47 / 2.5665 + 0x00000000, 0x00000300, 0x00050003, 0x00060004, 0x00070005, 0x00000700, 0x00000000, // 48 0 2.5666 + 0x00000000, 0x00000300, 0x00000403, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 49 1 2.5667 + 0x00000000, 0x00000302, 0x00050000, 0x00000500, 0x00000005, 0x00080706, 0x00000000, // 50 2 2.5668 + 0x00000000, 0x00000302, 0x00050000, 0x00000504, 0x00070000, 0x00000706, 0x00000000, // 51 3 2.5669 + 0x00000000, 0x00000300, 0x00000003, 0x00060004, 0x00070605, 0x00080000, 0x00000000, // 52 4 2.5670 + 0x00000000, 0x00040302, 0x00000003, 0x00000504, 0x00070000, 0x00000706, 0x00000000, // 53 5 2.5671 + 0x00000000, 0x00000300, 0x00000003, 0x00000504, 0x00070005, 0x00000700, 0x00000000, // 54 6 2.5672 + 0x00000000, 0x00040302, 0x00050000, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 55 7 2.5673 + 0x00000000, 0x00000300, 0x00050003, 0x00000500, 0x00070005, 0x00000700, 0x00000000, // 56 8 2.5674 + 0x00000000, 0x00000300, 0x00050003, 0x00060500, 0x00070000, 0x00000700, 0x00000000, // 57 9 2.5675 + 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000700, 0x00000000, // 58 : 2.5676 + 0x00000000, 0x00000000, 0x00000000, 0x00000500, 0x00000000, 0x00000700, 0x00000007, // 59 ; 2.5677 + 0x00000000, 0x00040000, 0x00000400, 0x00000004, 0x00000600, 0x00080000, 0x00000000, // 60 < 2.5678 + 0x00000000, 0x00000000, 0x00050403, 0x00000000, 0x00070605, 0x00000000, 0x00000000, // 61 = 2.5679 + 0x00000000, 0x00000002, 0x00000400, 0x00060000, 0x00000600, 0x00000006, 0x00000000, // 62 > 2.5680 + 0x00000000, 0x00000302, 0x00050000, 0x00000500, 0x00000000, 0x00000700, 0x00000000, // 63 ? 2.5681 + 0x00000000, 0x00000300, 0x00050400, 0x00060004, 0x00070600, 0x00000000, 0x00000000, // 64 @ 2.5682 + 0x00000000, 0x00000300, 0x00050003, 0x00060504, 0x00070005, 0x00080006, 0x00000000, // 65 A 2.5683 + 0x00000000, 0x00000302, 0x00050003, 0x00000504, 0x00070005, 0x00000706, 0x00000000, // 66 B 2.5684 + 0x00000000, 0x00040300, 0x00000003, 0x00000004, 0x00000005, 0x00080700, 0x00000000, // 67 C 2.5685 + 0x00000000, 0x00000302, 0x00050003, 0x00060004, 0x00070005, 0x00000706, 0x00000000, // 68 D 2.5686 + 0x00000000, 0x00040302, 0x00000003, 0x00000504, 0x00000005, 0x00080706, 0x00000000, // 69 E 2.5687 + 0x00000000, 0x00040302, 0x00000003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 70 F 2.5688 + 0x00000000, 0x00040300, 0x00000003, 0x00060004, 0x00070005, 0x00080700, 0x00000000, // 71 G 2.5689 + 0x00000000, 0x00040002, 0x00050003, 0x00060504, 0x00070005, 0x00080006, 0x00000000, // 72 H 2.5690 + 0x00000000, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 73 I 2.5691 + 0x00000000, 0x00040000, 0x00050000, 0x00060000, 0x00070005, 0x00000700, 0x00000000, // 74 J 2.5692 + 0x00000000, 0x00040002, 0x00050003, 0x00000504, 0x00070005, 0x00080006, 0x00000000, // 75 K 2.5693 + 0x00000000, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00080706, 0x00000000, // 76 l 2.5694 + 0x00000000, 0x00040002, 0x00050403, 0x00060004, 0x00070005, 0x00080006, 0x00000000, // 77 M 2.5695 + 0x00000000, 0x00000302, 0x00050003, 0x00060004, 0x00070005, 0x00080006, 0x00000000, // 78 N 2.5696 + 0x00000000, 0x00040302, 0x00050003, 0x00060004, 0x00070005, 0x00080706, 0x00000000, // 79 O 2.5697 + 0x00000000, 0x00000302, 0x00050003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 80 P 2.5698 + 0x00000000, 0x00040302, 0x00050003, 0x00060004, 0x00070005, 0x00080706, 0x00090000, // 81 Q 2.5699 + 0x00000000, 0x00000302, 0x00050003, 0x00000504, 0x00070005, 0x00080006, 0x00000000, // 82 R 2.5700 + 0x00000000, 0x00040300, 0x00000003, 0x00000500, 0x00070000, 0x00000706, 0x00000000, // 83 S 2.5701 + 0x00000000, 0x00040302, 0x00000400, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 84 T 2.5702 + 0x00000000, 0x00040002, 0x00050003, 0x00060004, 0x00070005, 0x00080706, 0x00000000, // 85 U 2.5703 + 0x00000000, 0x00040002, 0x00050003, 0x00060004, 0x00000600, 0x00000700, 0x00000000, // 86 V 2.5704 + 0x00000000, 0x00040002, 0x00050003, 0x00060004, 0x00070605, 0x00080006, 0x00000000, // 87 W 2.5705 + 0x00000000, 0x00040002, 0x00050003, 0x00000500, 0x00070005, 0x00080006, 0x00000000, // 88 X 2.5706 + 0x00000000, 0x00040002, 0x00050003, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 89 Y 2.5707 + 0x00000000, 0x00040302, 0x00050000, 0x00000500, 0x00000005, 0x00080706, 0x00000000, // 90 Z 2.5708 + 0x00000000, 0x00040300, 0x00000400, 0x00000500, 0x00000600, 0x00080700, 0x00000000, // 91 [ 2.5709 + 0x00000000, 0x00000002, 0x00000400, 0x00000500, 0x00070000, 0x00080000, 0x00000000, // 92 '\' 2.5710 + 0x00000000, 0x00000302, 0x00000400, 0x00000500, 0x00000600, 0x00000706, 0x00000000, // 93 ] 2.5711 + 0x00000000, 0x00000300, 0x00050003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 94 ^ 2.5712 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080706, 0x00000000, // 95 _ 2.5713 + 0x00000000, 0x00000002, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 96 ` 2.5714 + 0x00000000, 0x00000000, 0x00050400, 0x00060004, 0x00070005, 0x00080700, 0x00000000, // 97 a 2.5715 + 0x00000000, 0x00000002, 0x00000003, 0x00000504, 0x00070005, 0x00000706, 0x00000000, // 98 b 2.5716 + 0x00000000, 0x00000000, 0x00050400, 0x00000004, 0x00000005, 0x00080700, 0x00000000, // 99 c 2.5717 + 0x00000000, 0x00040000, 0x00050000, 0x00060500, 0x00070005, 0x00080700, 0x00000000, // 100 d 2.5718 + 0x00000000, 0x00000000, 0x00050400, 0x00060504, 0x00000005, 0x00080700, 0x00000000, // 101 e 2.5719 + 0x00000000, 0x00040300, 0x00000003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 102 f 2.5720 + 0x00000000, 0x00000000, 0x00050400, 0x00060004, 0x00070600, 0x00080000, 0x00000807, // 103 g 2.5721 + 0x00000000, 0x00000002, 0x00000003, 0x00000504, 0x00070005, 0x00080006, 0x00000000, // 104 h 2.5722 + 0x00000000, 0x00000300, 0x00000000, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 105 i 2.5723 + 0x00000000, 0x00000300, 0x00000000, 0x00000500, 0x00000600, 0x00000700, 0x00000007, // 106 j 2.5724 + 0x00000000, 0x00000002, 0x00000003, 0x00060004, 0x00000605, 0x00080006, 0x00000000, // 107 k 2.5725 + 0x00000000, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00080000, 0x00000000, // 108 l 2.5726 + 0x00000000, 0x00000000, 0x00050003, 0x00060504, 0x00070005, 0x00080006, 0x00000000, // 109 m 2.5727 + 0x00000000, 0x00000000, 0x00000403, 0x00060004, 0x00070005, 0x00080006, 0x00000000, // 110 n 2.5728 + 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00070005, 0x00000700, 0x00000000, // 111 o 2.5729 + 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00000605, 0x00000006, 0x00000007, // 112 p 2.5730 + 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00070600, 0x00080000, 0x00090000, // 113 q 2.5731 + 0x00000000, 0x00000000, 0x00050003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 114 r 2.5732 + 0x00000000, 0x00000000, 0x00050400, 0x00000004, 0x00070600, 0x00000706, 0x00000000, // 115 s 2.5733 + 0x00000000, 0x00000300, 0x00050403, 0x00000500, 0x00000600, 0x00080000, 0x00000000, // 116 t 2.5734 + 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00070005, 0x00080700, 0x00000000, // 117 u 2.5735 + 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00070005, 0x00000700, 0x00000000, // 118 v 2.5736 + 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00070605, 0x00080006, 0x00000000, // 119 w 2.5737 + 0x00000000, 0x00000000, 0x00050003, 0x00000500, 0x00070005, 0x00080006, 0x00000000, // 120 x 2.5738 + 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00000600, 0x00000700, 0x00000007, // 121 y 2.5739 + 0x00000000, 0x00000000, 0x00050403, 0x00000500, 0x00000005, 0x00080706, 0x00000000, // 122 z 2.5740 + 0x00000000, 0x00040300, 0x00000400, 0x00000504, 0x00000600, 0x00080700, 0x00000000, // 123 { 2.5741 + 0x00000000, 0x00000300, 0x00000400, 0x00000000, 0x00000600, 0x00000700, 0x00000000, // 124 | 2.5742 + 0x00000000, 0x00000302, 0x00000400, 0x00060500, 0x00000600, 0x00000706, 0x00000000, // 125 } 2.5743 + 0x00000000, 0x00000302, 0x00050000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 126 ~ 2.5744 + 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00070605, 0x00000000, 0x00000000, // 127 2.5745 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.5746 + }; 2.5747 + 2.5748 +static void PutTextInternal(const char *str, int len, short x, short y, int color, int backcolor) 2.5749 +{ 2.5750 + int Opac = (color >> 24) & 0xFF; 2.5751 + int backOpac = (backcolor >> 24) & 0xFF; 2.5752 + int origX = x; 2.5753 + 2.5754 + if (!Opac && !backOpac) 2.5755 + return; 2.5756 + 2.5757 + while (*str && len && y < LUA_SCREEN_HEIGHT) 2.5758 + { 2.5759 + int c = *str++; 2.5760 + while (x > LUA_SCREEN_WIDTH && c != '\n') 2.5761 + { 2.5762 + c = *str; 2.5763 + if (c == '\0') 2.5764 + break; 2.5765 + str++; 2.5766 + } 2.5767 + 2.5768 + if (c == '\n') 2.5769 + { 2.5770 + x = origX; 2.5771 + y += 8; 2.5772 + continue; 2.5773 + } 2.5774 + else if (c == '\t') // just in case 2.5775 + { 2.5776 + const int tabSpace = 8; 2.5777 + x += (tabSpace - (((x - origX) / 4) % tabSpace)) * 4; 2.5778 + continue; 2.5779 + } 2.5780 + 2.5781 + if ((unsigned int)(c - 32) >= 96) 2.5782 + continue; 2.5783 + 2.5784 + const unsigned char *Cur_Glyph = (const unsigned char *) &Small_Font_Data + (c - 32) * 7 * 4; 2.5785 + 2.5786 + for (int y2 = 0; y2 < 8; y2++) 2.5787 + { 2.5788 + unsigned int glyphLine = *((unsigned int *)Cur_Glyph + y2); 2.5789 + for (int x2 = -1; x2 < 4; x2++) 2.5790 + { 2.5791 + int shift = x2 << 3; 2.5792 + int mask = 0xFF << shift; 2.5793 + int intensity = (glyphLine & mask) >> shift; 2.5794 + 2.5795 + if (intensity && x2 >= 0 && y2 < 7) 2.5796 + { 2.5797 + //int xdraw = max(0,min(LUA_SCREEN_WIDTH - 1,x+x2)); 2.5798 + //int ydraw = max(0,min(LUA_SCREEN_HEIGHT - 1,y+y2)); 2.5799 + //gui_drawpixel_fast(xdraw, ydraw, color); 2.5800 + gui_drawpixel_internal(x + x2, y + y2, color); 2.5801 + } 2.5802 + else if (backOpac) 2.5803 + { 2.5804 + for (int y3 = max(0, y2 - 1); y3 <= min(6, y2 + 1); y3++) 2.5805 + { 2.5806 + unsigned int glyphLine = *((unsigned int *)Cur_Glyph + y3); 2.5807 + for (int x3 = max(0, x2 - 1); x3 <= min(3, x2 + 1); x3++) 2.5808 + { 2.5809 + int shift = x3 << 3; 2.5810 + int mask = 0xFF << shift; 2.5811 + intensity |= (glyphLine & mask) >> shift; 2.5812 + if (intensity) 2.5813 + goto draw_outline; // speedup? 2.5814 + } 2.5815 + } 2.5816 + 2.5817 + draw_outline: 2.5818 + if (intensity) 2.5819 + { 2.5820 + //int xdraw = max(0,min(LUA_SCREEN_WIDTH - 1,x+x2)); 2.5821 + //int ydraw = max(0,min(LUA_SCREEN_HEIGHT - 1,y+y2)); 2.5822 + //gui_drawpixel_fast(xdraw, ydraw, backcolor); 2.5823 + gui_drawpixel_internal(x + x2, y + y2, backcolor); 2.5824 + } 2.5825 + } 2.5826 + } 2.5827 + } 2.5828 + 2.5829 + x += 4; 2.5830 + len--; 2.5831 + } 2.5832 +} 2.5833 + 2.5834 +static int strlinelen(const char *string) 2.5835 +{ 2.5836 + const char *s = string; 2.5837 + while (*s && *s != '\n') 2.5838 + s++; 2.5839 + if (*s) 2.5840 + s++; 2.5841 + return s - string; 2.5842 +} 2.5843 + 2.5844 +static void LuaDisplayString(const char *string, int y, int x, uint32 color, uint32 outlineColor) 2.5845 +{ 2.5846 + if (!string) 2.5847 + return; 2.5848 + 2.5849 + gui_prepare(); 2.5850 + 2.5851 + PutTextInternal(string, strlen(string), x, y, color, outlineColor); 2.5852 + 2.5853 + /* 2.5854 + const char* ptr = string; 2.5855 + while(*ptr && y < LUA_SCREEN_HEIGHT) 2.5856 + { 2.5857 + int len = strlinelen(ptr); 2.5858 + int skip = 0; 2.5859 + if(len < 1) len = 1; 2.5860 + 2.5861 + // break up the line if it's too long to display otherwise 2.5862 + if(len > 63) 2.5863 + { 2.5864 + len = 63; 2.5865 + const char* ptr2 = ptr + len-1; 2.5866 + for(int j = len-1; j; j--, ptr2--) 2.5867 + { 2.5868 + if(*ptr2 == ' ' || *ptr2 == '\t') 2.5869 + { 2.5870 + len = j; 2.5871 + skip = 1; 2.5872 + break; 2.5873 + } 2.5874 + } 2.5875 + } 2.5876 + 2.5877 + int xl = 0; 2.5878 + int yl = 0; 2.5879 + int xh = (LUA_SCREEN_WIDTH - 1 - 1) - 4*len; 2.5880 + int yh = LUA_SCREEN_HEIGHT - 1; 2.5881 + int x2 = min(max(x,xl),xh); 2.5882 + int y2 = min(max(y,yl),yh); 2.5883 + 2.5884 + PutTextInternal(ptr,len,x2,y2,color,outlineColor); 2.5885 + 2.5886 + ptr += len + skip; 2.5887 + y += 8; 2.5888 + } 2.5889 + */ 2.5890 +} 2.5891 2.5892 // gui.text(int x, int y, string msg) 2.5893 // 2.5894 // Displays the given text on the screen, using the same font and techniques as the 2.5895 2.5896 // main HUD. 2.5897 - static int gui_text(lua_State *L) 2.5898 - { 2.5899 - //extern int font_height; 2.5900 - const char *msg; 2.5901 - int x, y; 2.5902 - uint32 colour, borderColour; 2.5903 - 2.5904 - x = luaL_checkinteger(L, 1); 2.5905 - y = luaL_checkinteger(L, 2); 2.5906 - //msg = luaL_checkstring(L, 3); 2.5907 - msg = toCString(L, 3); 2.5908 - 2.5909 - // if (x < 0 || x >= LUA_SCREEN_WIDTH || y < 0 || y >= (LUA_SCREEN_HEIGHT - font_height)) 2.5910 - // luaL_error(L,"bad coordinates"); 2.5911 - colour = gui_optcolour(L, 4, LUA_BUILD_PIXEL(255, 255, 255, 255)); 2.5912 - borderColour = gui_optcolour(L, 5, LUA_BUILD_PIXEL(255, 0, 0, 0)); 2.5913 - 2.5914 - gui_prepare(); 2.5915 - 2.5916 - LuaDisplayString(msg, y, x, colour, borderColour); 2.5917 - 2.5918 - return 0; 2.5919 - } 2.5920 +static int gui_text(lua_State *L) 2.5921 +{ 2.5922 + //extern int font_height; 2.5923 + const char *msg; 2.5924 + int x, y; 2.5925 + uint32 colour, borderColour; 2.5926 + 2.5927 + x = luaL_checkinteger(L, 1); 2.5928 + y = luaL_checkinteger(L, 2); 2.5929 + //msg = luaL_checkstring(L, 3); 2.5930 + msg = toCString(L, 3); 2.5931 + 2.5932 + // if (x < 0 || x >= LUA_SCREEN_WIDTH || y < 0 || y >= (LUA_SCREEN_HEIGHT - font_height)) 2.5933 + // luaL_error(L,"bad coordinates"); 2.5934 + colour = gui_optcolour(L, 4, LUA_BUILD_PIXEL(255, 255, 255, 255)); 2.5935 + borderColour = gui_optcolour(L, 5, LUA_BUILD_PIXEL(255, 0, 0, 0)); 2.5936 + 2.5937 + gui_prepare(); 2.5938 + 2.5939 + LuaDisplayString(msg, y, x, colour, borderColour); 2.5940 + 2.5941 + return 0; 2.5942 +} 2.5943 2.5944 // gui.gdoverlay([int dx=0, int dy=0,] string str [, sx=0, sy=0, sw, sh] [, float alphamul=1.0]) 2.5945 // 2.5946 // Overlays the given image on the screen. 2.5947 2.5948 // example: gui.gdoverlay(gd.createFromPng("myimage.png"):gdStr()) 2.5949 - static int gui_gdoverlay(lua_State *L) 2.5950 - { 2.5951 - int argCount = lua_gettop(L); 2.5952 - 2.5953 - int xStartDst = 0; 2.5954 - int yStartDst = 0; 2.5955 - int xStartSrc = 0; 2.5956 - int yStartSrc = 0; 2.5957 - 2.5958 - int index = 1; 2.5959 - if (lua_type(L, index) == LUA_TNUMBER) 2.5960 - { 2.5961 - xStartDst = lua_tointeger(L, index++); 2.5962 - if (lua_type(L, index) == LUA_TNUMBER) 2.5963 - yStartDst = lua_tointeger(L, index++); 2.5964 - } 2.5965 - 2.5966 - luaL_checktype(L, index, LUA_TSTRING); 2.5967 - 2.5968 - const unsigned char *ptr = (const unsigned char *)lua_tostring(L, index++); 2.5969 - 2.5970 - if (ptr[0] != 255 || (ptr[1] != 254 && ptr[1] != 255)) 2.5971 - luaL_error(L, "bad image data"); 2.5972 - 2.5973 - bool trueColor = (ptr[1] == 254); 2.5974 - ptr += 2; 2.5975 - 2.5976 - int imgwidth = *ptr++ << 8; 2.5977 - imgwidth |= *ptr++; 2.5978 - 2.5979 - int width = imgwidth; 2.5980 - int imgheight = *ptr++ << 8; 2.5981 - imgheight |= *ptr++; 2.5982 - 2.5983 - int height = imgheight; 2.5984 - if ((!trueColor && *ptr) || (trueColor && !*ptr)) 2.5985 - luaL_error(L, "bad image data"); 2.5986 - ptr++; 2.5987 - 2.5988 - int pitch = imgwidth * (trueColor ? 4 : 1); 2.5989 - 2.5990 - if ((argCount - index + 1) >= 4) 2.5991 - { 2.5992 - xStartSrc = luaL_checkinteger(L, index++); 2.5993 - yStartSrc = luaL_checkinteger(L, index++); 2.5994 - width = luaL_checkinteger(L, index++); 2.5995 - height = luaL_checkinteger(L, index++); 2.5996 - } 2.5997 - 2.5998 - int alphaMul = transparencyModifier; 2.5999 - if (lua_isnumber(L, index)) 2.6000 - alphaMul = (int)(alphaMul * lua_tonumber(L, index++)); 2.6001 - if (alphaMul <= 0) 2.6002 - return 0; 2.6003 - 2.6004 - // since there aren't that many possible opacity levels, 2.6005 - // do the opacity modification calculations beforehand instead of per pixel 2.6006 - int opacMap[256]; 2.6007 - for (int i = 0; i < 128; i++) 2.6008 - { 2.6009 - int opac = 255 - ((i << 1) | (i & 1)); // gdAlphaMax = 127, not 255 2.6010 - opac = (opac * alphaMul) / 255; 2.6011 - if (opac < 0) 2.6012 - opac = 0; 2.6013 - if (opac > 255) 2.6014 - opac = 255; 2.6015 - opacMap[i] = opac; 2.6016 - } 2.6017 - 2.6018 - for (int i = 128; i < 256; i++) 2.6019 - opacMap[i] = 0; // what should we do for them, actually? 2.6020 - int colorsTotal = 0; 2.6021 - if (!trueColor) 2.6022 - { 2.6023 - colorsTotal = *ptr++ << 8; 2.6024 - colorsTotal |= *ptr++; 2.6025 - } 2.6026 - 2.6027 - int transparent = *ptr++ << 24; 2.6028 - transparent |= *ptr++ << 16; 2.6029 - transparent |= *ptr++ << 8; 2.6030 - transparent |= *ptr++; 2.6031 - struct 2.6032 - { 2.6033 - uint8 r, g, b, a; 2.6034 - } pal[256]; 2.6035 - if (!trueColor) 2.6036 - for (int i = 0; i < 256; i++) 2.6037 - { 2.6038 - pal[i].r = *ptr++; 2.6039 - pal[i].g = *ptr++; 2.6040 - pal[i].b = *ptr++; 2.6041 - pal[i].a = opacMap[*ptr++]; 2.6042 - } 2.6043 - 2.6044 - // some of clippings 2.6045 - if (xStartSrc < 0) 2.6046 - { 2.6047 - width += xStartSrc; 2.6048 - xStartDst -= xStartSrc; 2.6049 - xStartSrc = 0; 2.6050 - } 2.6051 - 2.6052 - if (yStartSrc < 0) 2.6053 - { 2.6054 - height += yStartSrc; 2.6055 - yStartDst -= yStartSrc; 2.6056 - yStartSrc = 0; 2.6057 - } 2.6058 - 2.6059 - if (xStartSrc + width >= imgwidth) 2.6060 - width = imgwidth - xStartSrc; 2.6061 - if (yStartSrc + height >= imgheight) 2.6062 - height = imgheight - yStartSrc; 2.6063 - if (xStartDst < 0) 2.6064 - { 2.6065 - width += xStartDst; 2.6066 - if (width <= 0) 2.6067 - return 0; 2.6068 - xStartSrc = -xStartDst; 2.6069 - xStartDst = 0; 2.6070 - } 2.6071 - 2.6072 - if (yStartDst < 0) 2.6073 - { 2.6074 - height += yStartDst; 2.6075 - if (height <= 0) 2.6076 - return 0; 2.6077 - yStartSrc = -yStartDst; 2.6078 - yStartDst = 0; 2.6079 - } 2.6080 - 2.6081 - if (xStartDst + width >= LUA_SCREEN_WIDTH) 2.6082 - width = LUA_SCREEN_WIDTH - xStartDst; 2.6083 - if (yStartDst + height >= LUA_SCREEN_HEIGHT) 2.6084 - height = LUA_SCREEN_HEIGHT - yStartDst; 2.6085 - if (width <= 0 || height <= 0) 2.6086 - return 0; // out of screen or invalid size 2.6087 - gui_prepare(); 2.6088 - 2.6089 - const uint8 *pix = (const uint8 *)(&ptr[yStartSrc * pitch + (xStartSrc * (trueColor ? 4 : 1))]); 2.6090 - int bytesToNextLine = pitch - (width * (trueColor ? 4 : 1)); 2.6091 - if (trueColor) 2.6092 - { 2.6093 - for (int y = yStartDst; y < height + yStartDst && y < LUA_SCREEN_HEIGHT; y++, pix += bytesToNextLine) 2.6094 - { 2.6095 - for (int x = xStartDst; x < width + xStartDst && x < LUA_SCREEN_WIDTH; x++, pix += 4) 2.6096 - { 2.6097 - gui_drawpixel_fast(x, y, LUA_BUILD_PIXEL(opacMap[pix[0]], pix[1], pix[2], pix[3])); 2.6098 - } 2.6099 - } 2.6100 - } 2.6101 - else 2.6102 - { 2.6103 - for (int y = yStartDst; y < height + yStartDst && y < LUA_SCREEN_HEIGHT; y++, pix += bytesToNextLine) 2.6104 - { 2.6105 - for (int x = xStartDst; x < width + xStartDst && x < LUA_SCREEN_WIDTH; x++, pix++) 2.6106 - { 2.6107 - gui_drawpixel_fast(x, y, LUA_BUILD_PIXEL(pal[*pix].a, pal[*pix].r, pal[*pix].g, pal[*pix].b)); 2.6108 - } 2.6109 - } 2.6110 - } 2.6111 - 2.6112 - return 0; 2.6113 - } 2.6114 +static int gui_gdoverlay(lua_State *L) 2.6115 +{ 2.6116 + int argCount = lua_gettop(L); 2.6117 + 2.6118 + int xStartDst = 0; 2.6119 + int yStartDst = 0; 2.6120 + int xStartSrc = 0; 2.6121 + int yStartSrc = 0; 2.6122 + 2.6123 + int index = 1; 2.6124 + if (lua_type(L, index) == LUA_TNUMBER) 2.6125 + { 2.6126 + xStartDst = lua_tointeger(L, index++); 2.6127 + if (lua_type(L, index) == LUA_TNUMBER) 2.6128 + yStartDst = lua_tointeger(L, index++); 2.6129 + } 2.6130 + 2.6131 + luaL_checktype(L, index, LUA_TSTRING); 2.6132 + 2.6133 + const unsigned char *ptr = (const unsigned char *)lua_tostring(L, index++); 2.6134 + 2.6135 + if (ptr[0] != 255 || (ptr[1] != 254 && ptr[1] != 255)) 2.6136 + luaL_error(L, "bad image data"); 2.6137 + 2.6138 + bool trueColor = (ptr[1] == 254); 2.6139 + ptr += 2; 2.6140 + 2.6141 + int imgwidth = *ptr++ << 8; 2.6142 + imgwidth |= *ptr++; 2.6143 + 2.6144 + int width = imgwidth; 2.6145 + int imgheight = *ptr++ << 8; 2.6146 + imgheight |= *ptr++; 2.6147 + 2.6148 + int height = imgheight; 2.6149 + if ((!trueColor && *ptr) || (trueColor && !*ptr)) 2.6150 + luaL_error(L, "bad image data"); 2.6151 + ptr++; 2.6152 + 2.6153 + int pitch = imgwidth * (trueColor ? 4 : 1); 2.6154 + 2.6155 + if ((argCount - index + 1) >= 4) 2.6156 + { 2.6157 + xStartSrc = luaL_checkinteger(L, index++); 2.6158 + yStartSrc = luaL_checkinteger(L, index++); 2.6159 + width = luaL_checkinteger(L, index++); 2.6160 + height = luaL_checkinteger(L, index++); 2.6161 + } 2.6162 + 2.6163 + int alphaMul = transparencyModifier; 2.6164 + if (lua_isnumber(L, index)) 2.6165 + alphaMul = (int)(alphaMul * lua_tonumber(L, index++)); 2.6166 + if (alphaMul <= 0) 2.6167 + return 0; 2.6168 + 2.6169 + // since there aren't that many possible opacity levels, 2.6170 + // do the opacity modification calculations beforehand instead of per pixel 2.6171 + int opacMap[256]; 2.6172 + for (int i = 0; i < 128; i++) 2.6173 + { 2.6174 + int opac = 255 - ((i << 1) | (i & 1)); // gdAlphaMax = 127, not 255 2.6175 + opac = (opac * alphaMul) / 255; 2.6176 + if (opac < 0) 2.6177 + opac = 0; 2.6178 + if (opac > 255) 2.6179 + opac = 255; 2.6180 + opacMap[i] = opac; 2.6181 + } 2.6182 + 2.6183 + for (int i = 128; i < 256; i++) 2.6184 + opacMap[i] = 0; // what should we do for them, actually? 2.6185 + int colorsTotal = 0; 2.6186 + if (!trueColor) 2.6187 + { 2.6188 + colorsTotal = *ptr++ << 8; 2.6189 + colorsTotal |= *ptr++; 2.6190 + } 2.6191 + 2.6192 + int transparent = *ptr++ << 24; 2.6193 + transparent |= *ptr++ << 16; 2.6194 + transparent |= *ptr++ << 8; 2.6195 + transparent |= *ptr++; 2.6196 + struct 2.6197 + { 2.6198 + uint8 r, g, b, a; 2.6199 + } pal[256]; 2.6200 + if (!trueColor) 2.6201 + for (int i = 0; i < 256; i++) 2.6202 + { 2.6203 + pal[i].r = *ptr++; 2.6204 + pal[i].g = *ptr++; 2.6205 + pal[i].b = *ptr++; 2.6206 + pal[i].a = opacMap[*ptr++]; 2.6207 + } 2.6208 + 2.6209 + // some of clippings 2.6210 + if (xStartSrc < 0) 2.6211 + { 2.6212 + width += xStartSrc; 2.6213 + xStartDst -= xStartSrc; 2.6214 + xStartSrc = 0; 2.6215 + } 2.6216 + 2.6217 + if (yStartSrc < 0) 2.6218 + { 2.6219 + height += yStartSrc; 2.6220 + yStartDst -= yStartSrc; 2.6221 + yStartSrc = 0; 2.6222 + } 2.6223 + 2.6224 + if (xStartSrc + width >= imgwidth) 2.6225 + width = imgwidth - xStartSrc; 2.6226 + if (yStartSrc + height >= imgheight) 2.6227 + height = imgheight - yStartSrc; 2.6228 + if (xStartDst < 0) 2.6229 + { 2.6230 + width += xStartDst; 2.6231 + if (width <= 0) 2.6232 + return 0; 2.6233 + xStartSrc = -xStartDst; 2.6234 + xStartDst = 0; 2.6235 + } 2.6236 + 2.6237 + if (yStartDst < 0) 2.6238 + { 2.6239 + height += yStartDst; 2.6240 + if (height <= 0) 2.6241 + return 0; 2.6242 + yStartSrc = -yStartDst; 2.6243 + yStartDst = 0; 2.6244 + } 2.6245 + 2.6246 + if (xStartDst + width >= LUA_SCREEN_WIDTH) 2.6247 + width = LUA_SCREEN_WIDTH - xStartDst; 2.6248 + if (yStartDst + height >= LUA_SCREEN_HEIGHT) 2.6249 + height = LUA_SCREEN_HEIGHT - yStartDst; 2.6250 + if (width <= 0 || height <= 0) 2.6251 + return 0; // out of screen or invalid size 2.6252 + gui_prepare(); 2.6253 + 2.6254 + const uint8 *pix = (const uint8 *)(&ptr[yStartSrc * pitch + (xStartSrc * (trueColor ? 4 : 1))]); 2.6255 + int bytesToNextLine = pitch - (width * (trueColor ? 4 : 1)); 2.6256 + if (trueColor) 2.6257 + { 2.6258 + for (int y = yStartDst; y < height + yStartDst && y < LUA_SCREEN_HEIGHT; y++, pix += bytesToNextLine) 2.6259 + { 2.6260 + for (int x = xStartDst; x < width + xStartDst && x < LUA_SCREEN_WIDTH; x++, pix += 4) 2.6261 + { 2.6262 + gui_drawpixel_fast(x, y, LUA_BUILD_PIXEL(opacMap[pix[0]], pix[1], pix[2], pix[3])); 2.6263 + } 2.6264 + } 2.6265 + } 2.6266 + else 2.6267 + { 2.6268 + for (int y = yStartDst; y < height + yStartDst && y < LUA_SCREEN_HEIGHT; y++, pix += bytesToNextLine) 2.6269 + { 2.6270 + for (int x = xStartDst; x < width + xStartDst && x < LUA_SCREEN_WIDTH; x++, pix++) 2.6271 + { 2.6272 + gui_drawpixel_fast(x, y, LUA_BUILD_PIXEL(pal[*pix].a, pal[*pix].r, pal[*pix].g, pal[*pix].b)); 2.6273 + } 2.6274 + } 2.6275 + } 2.6276 + 2.6277 + return 0; 2.6278 +} 2.6279 2.6280 // function gui.register(function f) 2.6281 // 2.6282 @@ -3459,347 +3459,347 @@ 2.6283 // a previously registered function, and the previous function 2.6284 2.6285 // (if any) is returned, or nil if none. 2.6286 - static int gui_register(lua_State *L) 2.6287 - { 2.6288 - // We'll do this straight up. 2.6289 - // First set up the stack. 2.6290 - lua_settop(L, 1); 2.6291 - 2.6292 - // Verify the validity of the entry 2.6293 - if (!lua_isnil(L, 1)) 2.6294 - luaL_checktype(L, 1, LUA_TFUNCTION); 2.6295 - 2.6296 - // Get the old value 2.6297 - lua_getfield(L, LUA_REGISTRYINDEX, guiCallbackTable); 2.6298 - 2.6299 - // Save the new value 2.6300 - lua_pushvalue(L, 1); 2.6301 - lua_setfield(L, LUA_REGISTRYINDEX, guiCallbackTable); 2.6302 - 2.6303 - // The old value is on top of the stack. Return it. 2.6304 - return 1; 2.6305 - } 2.6306 +static int gui_register(lua_State *L) 2.6307 +{ 2.6308 + // We'll do this straight up. 2.6309 + // First set up the stack. 2.6310 + lua_settop(L, 1); 2.6311 + 2.6312 + // Verify the validity of the entry 2.6313 + if (!lua_isnil(L, 1)) 2.6314 + luaL_checktype(L, 1, LUA_TFUNCTION); 2.6315 + 2.6316 + // Get the old value 2.6317 + lua_getfield(L, LUA_REGISTRYINDEX, guiCallbackTable); 2.6318 + 2.6319 + // Save the new value 2.6320 + lua_pushvalue(L, 1); 2.6321 + lua_setfield(L, LUA_REGISTRYINDEX, guiCallbackTable); 2.6322 + 2.6323 + // The old value is on top of the stack. Return it. 2.6324 + return 1; 2.6325 +} 2.6326 2.6327 // string gui.popup(string message, [string type = "ok"]) 2.6328 // 2.6329 2.6330 // Popup dialog! 2.6331 - int gui_popup(lua_State *L) 2.6332 - { 2.6333 - const char *message = luaL_checkstring(L, 1); 2.6334 - const char *type = luaL_optstring(L, 2, "ok"); 2.6335 +int gui_popup(lua_State *L) 2.6336 +{ 2.6337 + const char *message = luaL_checkstring(L, 1); 2.6338 + const char *type = luaL_optstring(L, 2, "ok"); 2.6339 2.6340 #if (defined(WIN32) && !defined(SDL)) 2.6341 - int t; 2.6342 - if (strcmp(type, "ok") == 0) 2.6343 - t = MB_OK; 2.6344 - else if (strcmp(type, "yesno") == 0) 2.6345 - t = MB_YESNO; 2.6346 - else if (strcmp(type, "yesnocancel") == 0) 2.6347 - t = MB_YESNOCANCEL; 2.6348 - else 2.6349 - return luaL_error(L, "invalid popup type \"%s\"", type); 2.6350 - 2.6351 - theApp.winCheckFullscreen(); 2.6352 - systemSoundClearBuffer(); 2.6353 - int result = AfxGetApp()->m_pMainWnd->MessageBox(message, "Lua Script Pop-up", t); 2.6354 - 2.6355 - lua_settop(L, 1); 2.6356 - 2.6357 - if (t != MB_OK) 2.6358 - { 2.6359 - if (result == IDYES) 2.6360 - lua_pushstring(L, "yes"); 2.6361 - else if (result == IDNO) 2.6362 - lua_pushstring(L, "no"); 2.6363 - else if (result == IDCANCEL) 2.6364 - lua_pushstring(L, "cancel"); 2.6365 - else 2.6366 - luaL_error(L, "win32 unrecognized return value %d", result); 2.6367 - return 1; 2.6368 - } 2.6369 - 2.6370 - // else, we don't care. 2.6371 - return 0; 2.6372 + int t; 2.6373 + if (strcmp(type, "ok") == 0) 2.6374 + t = MB_OK; 2.6375 + else if (strcmp(type, "yesno") == 0) 2.6376 + t = MB_YESNO; 2.6377 + else if (strcmp(type, "yesnocancel") == 0) 2.6378 + t = MB_YESNOCANCEL; 2.6379 + else 2.6380 + return luaL_error(L, "invalid popup type \"%s\"", type); 2.6381 + 2.6382 + theApp.winCheckFullscreen(); 2.6383 + systemSoundClearBuffer(); 2.6384 + int result = AfxGetApp()->m_pMainWnd->MessageBox(message, "Lua Script Pop-up", t); 2.6385 + 2.6386 + lua_settop(L, 1); 2.6387 + 2.6388 + if (t != MB_OK) 2.6389 + { 2.6390 + if (result == IDYES) 2.6391 + lua_pushstring(L, "yes"); 2.6392 + else if (result == IDNO) 2.6393 + lua_pushstring(L, "no"); 2.6394 + else if (result == IDCANCEL) 2.6395 + lua_pushstring(L, "cancel"); 2.6396 + else 2.6397 + luaL_error(L, "win32 unrecognized return value %d", result); 2.6398 + return 1; 2.6399 + } 2.6400 + 2.6401 + // else, we don't care. 2.6402 + return 0; 2.6403 #else 2.6404 - char *t; 2.6405 - #ifdef __linux 2.6406 - // The Linux backend has a "FromPause" variable. 2.6407 - // If set to 1, assume some known external event has screwed with the flow of time. 2.6408 - // Since this pauses the emulator waiting for a response, we set it to 1. 2.6409 -// FIXME: Well, actually it doesn't 2.6410 -// extern int FromPause; 2.6411 -// FromPause = 1; 2.6412 - 2.6413 - int pid; // appease compiler 2.6414 - 2.6415 - // Before doing any work, verify the correctness of the parameters. 2.6416 - if (strcmp(type, "ok") == 0) 2.6417 - t = "OK:100"; 2.6418 - else if (strcmp(type, "yesno") == 0) 2.6419 - t = "Yes:100,No:101"; 2.6420 - else if (strcmp(type, "yesnocancel") == 0) 2.6421 - t = "Yes:100,No:101,Cancel:102"; 2.6422 - else 2.6423 - return luaL_error(L, "invalid popup type \"%s\"", type); 2.6424 - 2.6425 - // Can we find a copy of xmessage? Search the path. 2.6426 - char *path = strdup(getenv("PATH")); 2.6427 - 2.6428 - char *current = path; 2.6429 - 2.6430 - char *colon; 2.6431 - 2.6432 - int found = 0; 2.6433 - 2.6434 - while (current) 2.6435 - { 2.6436 - colon = strchr(current, ':'); 2.6437 - 2.6438 - // Clip off the colon. 2.6439 - *colon++ = 0; 2.6440 - 2.6441 - int len = strlen(current); 2.6442 - char *filename = (char *)malloc(len + 12); // always give excess 2.6443 - snprintf(filename, len + 12, "%s/xmessage", current); 2.6444 - 2.6445 - if (access(filename, X_OK) == 0) 2.6446 - { 2.6447 - free(filename); 2.6448 - found = 1; 2.6449 - break; 2.6450 - } 2.6451 - 2.6452 - // Failed, move on. 2.6453 - current = colon; 2.6454 - free(filename); 2.6455 - } 2.6456 - 2.6457 - free(path); 2.6458 - 2.6459 - // We've found it? 2.6460 - if (!found) 2.6461 - goto use_console; 2.6462 - 2.6463 - pid = fork(); 2.6464 - if (pid == 0) 2.6465 - { // I'm the virgin sacrifice 2.6466 - // I'm gonna be dead in a matter of microseconds anyways, so wasted memory doesn't matter to me. 2.6467 - // Go ahead and abuse strdup. 2.6468 - char *parameters[] = { "xmessage", "-buttons", t, strdup(message), NULL }; 2.6469 - 2.6470 - execvp("xmessage", parameters); 2.6471 - 2.6472 - // Aw shitty 2.6473 - perror("exec xmessage"); 2.6474 - exit(1); 2.6475 - } 2.6476 - else if (pid < 0) // something went wrong!!! Oh hell... use the console 2.6477 - goto use_console; 2.6478 - else 2.6479 - { 2.6480 - // We're the parent. Watch for the child. 2.6481 - int r; 2.6482 - int res = waitpid(pid, &r, 0); 2.6483 - if (res < 0) // wtf? 2.6484 - goto use_console; 2.6485 - 2.6486 - // The return value gets copmlicated... 2.6487 - if (!WIFEXITED(r)) 2.6488 - { 2.6489 - luaL_error(L, "don't screw with my xmessage process!"); 2.6490 - } 2.6491 - 2.6492 - r = WEXITSTATUS(r); 2.6493 - 2.6494 - // We assume it's worked. 2.6495 - if (r == 0) 2.6496 - { 2.6497 - return 0; // no parameters for an OK 2.6498 - } 2.6499 - 2.6500 - if (r == 100) 2.6501 - { 2.6502 - lua_pushstring(L, "yes"); 2.6503 - return 1; 2.6504 - } 2.6505 - 2.6506 - if (r == 101) 2.6507 - { 2.6508 - lua_pushstring(L, "no"); 2.6509 - return 1; 2.6510 - } 2.6511 - 2.6512 - if (r == 102) 2.6513 - { 2.6514 - lua_pushstring(L, "cancel"); 2.6515 - return 1; 2.6516 - } 2.6517 - 2.6518 - // Wtf? 2.6519 - return luaL_error(L, "popup failed due to unknown results involving xmessage (%d)", r); 2.6520 - } 2.6521 - 2.6522 -use_console: 2.6523 - #endif 2.6524 - 2.6525 - // All else has failed 2.6526 - if (strcmp(type, "ok") == 0) 2.6527 - t = ""; 2.6528 - else if (strcmp(type, "yesno") == 0) 2.6529 - t = "yn"; 2.6530 - else if (strcmp(type, "yesnocancel") == 0) 2.6531 - t = "ync"; 2.6532 - else 2.6533 - return luaL_error(L, "invalid popup type \"%s\"", type); 2.6534 - 2.6535 - fprintf(stderr, "Lua Message: %s\n", message); 2.6536 - 2.6537 - while (true) 2.6538 - { 2.6539 - char buffer[64]; 2.6540 - 2.6541 - // We don't want parameters 2.6542 - if (!t[0]) 2.6543 - { 2.6544 - fprintf(stderr, "[Press Enter]"); 2.6545 - fgets(buffer, sizeof(buffer), stdin); 2.6546 - 2.6547 - // We're done 2.6548 - return 0; 2.6549 - } 2.6550 - 2.6551 - fprintf(stderr, "(%s): ", t); 2.6552 - fgets(buffer, sizeof(buffer), stdin); 2.6553 - 2.6554 - // Check if the option is in the list 2.6555 - if (strchr(t, tolower(buffer[0]))) 2.6556 - { 2.6557 - switch (tolower(buffer[0])) 2.6558 - { 2.6559 - case 'y': 2.6560 - lua_pushstring(L, "yes"); 2.6561 - return 1; 2.6562 - case 'n': 2.6563 - lua_pushstring(L, "no"); 2.6564 - return 1; 2.6565 - case 'c': 2.6566 - lua_pushstring(L, "cancel"); 2.6567 - return 1; 2.6568 - default: 2.6569 - luaL_error(L, "internal logic error in console based prompts for gui.popup"); 2.6570 - } 2.6571 - } 2.6572 - 2.6573 - // We fell through, so we assume the user answered wrong and prompt again. 2.6574 - } 2.6575 - 2.6576 - // Nothing here, since the only way out is in the loop. 2.6577 + char *t; 2.6578 +#ifdef __linux 2.6579 + // The Linux backend has a "FromPause" variable. 2.6580 + // If set to 1, assume some known external event has screwed with the flow of time. 2.6581 + // Since this pauses the emulator waiting for a response, we set it to 1. 2.6582 + // FIXME: Well, actually it doesn't 2.6583 + // extern int FromPause; 2.6584 + // FromPause = 1; 2.6585 + 2.6586 + int pid; // appease compiler 2.6587 + 2.6588 + // Before doing any work, verify the correctness of the parameters. 2.6589 + if (strcmp(type, "ok") == 0) 2.6590 + t = "OK:100"; 2.6591 + else if (strcmp(type, "yesno") == 0) 2.6592 + t = "Yes:100,No:101"; 2.6593 + else if (strcmp(type, "yesnocancel") == 0) 2.6594 + t = "Yes:100,No:101,Cancel:102"; 2.6595 + else 2.6596 + return luaL_error(L, "invalid popup type \"%s\"", type); 2.6597 + 2.6598 + // Can we find a copy of xmessage? Search the path. 2.6599 + char *path = strdup(getenv("PATH")); 2.6600 + 2.6601 + char *current = path; 2.6602 + 2.6603 + char *colon; 2.6604 + 2.6605 + int found = 0; 2.6606 + 2.6607 + while (current) 2.6608 + { 2.6609 + colon = strchr(current, ':'); 2.6610 + 2.6611 + // Clip off the colon. 2.6612 + *colon++ = 0; 2.6613 + 2.6614 + int len = strlen(current); 2.6615 + char *filename = (char *)malloc(len + 12); // always give excess 2.6616 + snprintf(filename, len + 12, "%s/xmessage", current); 2.6617 + 2.6618 + if (access(filename, X_OK) == 0) 2.6619 + { 2.6620 + free(filename); 2.6621 + found = 1; 2.6622 + break; 2.6623 + } 2.6624 + 2.6625 + // Failed, move on. 2.6626 + current = colon; 2.6627 + free(filename); 2.6628 + } 2.6629 + 2.6630 + free(path); 2.6631 + 2.6632 + // We've found it? 2.6633 + if (!found) 2.6634 + goto use_console; 2.6635 + 2.6636 + pid = fork(); 2.6637 + if (pid == 0) 2.6638 + { // I'm the virgin sacrifice 2.6639 + // I'm gonna be dead in a matter of microseconds anyways, so wasted memory doesn't matter to me. 2.6640 + // Go ahead and abuse strdup. 2.6641 + char *parameters[] = { "xmessage", "-buttons", t, strdup(message), NULL }; 2.6642 + 2.6643 + execvp("xmessage", parameters); 2.6644 + 2.6645 + // Aw shitty 2.6646 + perror("exec xmessage"); 2.6647 + exit(1); 2.6648 + } 2.6649 + else if (pid < 0) // something went wrong!!! Oh hell... use the console 2.6650 + goto use_console; 2.6651 + else 2.6652 + { 2.6653 + // We're the parent. Watch for the child. 2.6654 + int r; 2.6655 + int res = waitpid(pid, &r, 0); 2.6656 + if (res < 0) // wtf? 2.6657 + goto use_console; 2.6658 + 2.6659 + // The return value gets copmlicated... 2.6660 + if (!WIFEXITED(r)) 2.6661 + { 2.6662 + luaL_error(L, "don't screw with my xmessage process!"); 2.6663 + } 2.6664 + 2.6665 + r = WEXITSTATUS(r); 2.6666 + 2.6667 + // We assume it's worked. 2.6668 + if (r == 0) 2.6669 + { 2.6670 + return 0; // no parameters for an OK 2.6671 + } 2.6672 + 2.6673 + if (r == 100) 2.6674 + { 2.6675 + lua_pushstring(L, "yes"); 2.6676 + return 1; 2.6677 + } 2.6678 + 2.6679 + if (r == 101) 2.6680 + { 2.6681 + lua_pushstring(L, "no"); 2.6682 + return 1; 2.6683 + } 2.6684 + 2.6685 + if (r == 102) 2.6686 + { 2.6687 + lua_pushstring(L, "cancel"); 2.6688 + return 1; 2.6689 + } 2.6690 + 2.6691 + // Wtf? 2.6692 + return luaL_error(L, "popup failed due to unknown results involving xmessage (%d)", r); 2.6693 + } 2.6694 + 2.6695 + use_console: 2.6696 #endif 2.6697 - } 2.6698 + 2.6699 + // All else has failed 2.6700 + if (strcmp(type, "ok") == 0) 2.6701 + t = ""; 2.6702 + else if (strcmp(type, "yesno") == 0) 2.6703 + t = "yn"; 2.6704 + else if (strcmp(type, "yesnocancel") == 0) 2.6705 + t = "ync"; 2.6706 + else 2.6707 + return luaL_error(L, "invalid popup type \"%s\"", type); 2.6708 + 2.6709 + fprintf(stderr, "Lua Message: %s\n", message); 2.6710 + 2.6711 + while (true) 2.6712 + { 2.6713 + char buffer[64]; 2.6714 + 2.6715 + // We don't want parameters 2.6716 + if (!t[0]) 2.6717 + { 2.6718 + fprintf(stderr, "[Press Enter]"); 2.6719 + fgets(buffer, sizeof(buffer), stdin); 2.6720 + 2.6721 + // We're done 2.6722 + return 0; 2.6723 + } 2.6724 + 2.6725 + fprintf(stderr, "(%s): ", t); 2.6726 + fgets(buffer, sizeof(buffer), stdin); 2.6727 + 2.6728 + // Check if the option is in the list 2.6729 + if (strchr(t, tolower(buffer[0]))) 2.6730 + { 2.6731 + switch (tolower(buffer[0])) 2.6732 + { 2.6733 + case 'y': 2.6734 + lua_pushstring(L, "yes"); 2.6735 + return 1; 2.6736 + case 'n': 2.6737 + lua_pushstring(L, "no"); 2.6738 + return 1; 2.6739 + case 'c': 2.6740 + lua_pushstring(L, "cancel"); 2.6741 + return 1; 2.6742 + default: 2.6743 + luaL_error(L, "internal logic error in console based prompts for gui.popup"); 2.6744 + } 2.6745 + } 2.6746 + 2.6747 + // We fell through, so we assume the user answered wrong and prompt again. 2.6748 + } 2.6749 + 2.6750 + // Nothing here, since the only way out is in the loop. 2.6751 +#endif 2.6752 +} 2.6753 2.6754 #if (defined(WIN32) && !defined(SDL)) 2.6755 - const char *s_keyToName[256] = 2.6756 - { 2.6757 - NULL, 2.6758 - "leftclick", 2.6759 - "rightclick", 2.6760 - NULL, 2.6761 - "middleclick", 2.6762 - NULL, 2.6763 - NULL, 2.6764 - NULL, 2.6765 - "backspace", 2.6766 - "tab", 2.6767 - NULL, 2.6768 - NULL, 2.6769 - NULL, 2.6770 - "enter", 2.6771 - NULL, 2.6772 - NULL, 2.6773 - "shift", // 0x10 2.6774 - "control", 2.6775 - "alt", 2.6776 - "pause", 2.6777 - "capslock", 2.6778 - NULL, 2.6779 - NULL, 2.6780 - NULL, 2.6781 - NULL, 2.6782 - NULL, 2.6783 - NULL, 2.6784 - "escape", 2.6785 - NULL, 2.6786 - NULL, 2.6787 - NULL, 2.6788 - NULL, 2.6789 - "space", // 0x20 2.6790 - "pageup", 2.6791 - "pagedown", 2.6792 - "end", 2.6793 - "home", 2.6794 - "left", 2.6795 - "up", 2.6796 - "right", 2.6797 - "down", 2.6798 - NULL, 2.6799 - NULL, 2.6800 - NULL, 2.6801 - NULL, 2.6802 - "insert", 2.6803 - "delete", 2.6804 - NULL, 2.6805 - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 2.6806 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6807 - "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", 2.6808 - "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", 2.6809 - "U", "V", "W", "X", "Y", "Z", 2.6810 - NULL, 2.6811 - NULL, 2.6812 - NULL, 2.6813 - NULL, 2.6814 - NULL, 2.6815 - "numpad0", "numpad1", "numpad2", "numpad3", "numpad4", "numpad5", "numpad6", "numpad7", "numpad8", "numpad9", 2.6816 - "numpad*", "numpad+", 2.6817 - NULL, 2.6818 - "numpad-", "numpad.", "numpad/", 2.6819 - "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", 2.6820 - "F12", 2.6821 - "F13", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23", 2.6822 - "F24", 2.6823 - NULL, 2.6824 - NULL, 2.6825 - NULL, 2.6826 - NULL, 2.6827 - NULL, 2.6828 - NULL, 2.6829 - NULL, 2.6830 - NULL, 2.6831 - "numlock", 2.6832 - "scrolllock", 2.6833 - NULL, // 0x92 2.6834 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6835 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6836 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6837 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6838 - NULL, // 0xB9 2.6839 - "semicolon", 2.6840 - "plus", 2.6841 - "comma", 2.6842 - "minus", 2.6843 - "period", 2.6844 - "slash", 2.6845 - "tilde", 2.6846 - NULL, // 0xC1 2.6847 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6848 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6849 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6850 - NULL, // 0xDA 2.6851 - "leftbracket", 2.6852 - "backslash", 2.6853 - "rightbracket", 2.6854 - "quote", 2.6855 - }; 2.6856 +const char *s_keyToName[256] = 2.6857 + { 2.6858 + NULL, 2.6859 + "leftclick", 2.6860 + "rightclick", 2.6861 + NULL, 2.6862 + "middleclick", 2.6863 + NULL, 2.6864 + NULL, 2.6865 + NULL, 2.6866 + "backspace", 2.6867 + "tab", 2.6868 + NULL, 2.6869 + NULL, 2.6870 + NULL, 2.6871 + "enter", 2.6872 + NULL, 2.6873 + NULL, 2.6874 + "shift", // 0x10 2.6875 + "control", 2.6876 + "alt", 2.6877 + "pause", 2.6878 + "capslock", 2.6879 + NULL, 2.6880 + NULL, 2.6881 + NULL, 2.6882 + NULL, 2.6883 + NULL, 2.6884 + NULL, 2.6885 + "escape", 2.6886 + NULL, 2.6887 + NULL, 2.6888 + NULL, 2.6889 + NULL, 2.6890 + "space", // 0x20 2.6891 + "pageup", 2.6892 + "pagedown", 2.6893 + "end", 2.6894 + "home", 2.6895 + "left", 2.6896 + "up", 2.6897 + "right", 2.6898 + "down", 2.6899 + NULL, 2.6900 + NULL, 2.6901 + NULL, 2.6902 + NULL, 2.6903 + "insert", 2.6904 + "delete", 2.6905 + NULL, 2.6906 + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 2.6907 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6908 + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", 2.6909 + "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", 2.6910 + "U", "V", "W", "X", "Y", "Z", 2.6911 + NULL, 2.6912 + NULL, 2.6913 + NULL, 2.6914 + NULL, 2.6915 + NULL, 2.6916 + "numpad0", "numpad1", "numpad2", "numpad3", "numpad4", "numpad5", "numpad6", "numpad7", "numpad8", "numpad9", 2.6917 + "numpad*", "numpad+", 2.6918 + NULL, 2.6919 + "numpad-", "numpad.", "numpad/", 2.6920 + "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", 2.6921 + "F12", 2.6922 + "F13", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23", 2.6923 + "F24", 2.6924 + NULL, 2.6925 + NULL, 2.6926 + NULL, 2.6927 + NULL, 2.6928 + NULL, 2.6929 + NULL, 2.6930 + NULL, 2.6931 + NULL, 2.6932 + "numlock", 2.6933 + "scrolllock", 2.6934 + NULL, // 0x92 2.6935 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6936 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6937 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6938 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6939 + NULL, // 0xB9 2.6940 + "semicolon", 2.6941 + "plus", 2.6942 + "comma", 2.6943 + "minus", 2.6944 + "period", 2.6945 + "slash", 2.6946 + "tilde", 2.6947 + NULL, // 0xC1 2.6948 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6949 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6950 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.6951 + NULL, // 0xDA 2.6952 + "leftbracket", 2.6953 + "backslash", 2.6954 + "rightbracket", 2.6955 + "quote", 2.6956 + }; 2.6957 #endif 2.6958 2.6959 // input.get() 2.6960 @@ -3810,412 +3810,412 @@ 2.6961 // and has the mouse at the bottom-right corner of the game screen, 2.6962 2.6963 // then this would return {W=true, leftclick=true, xmouse=255, ymouse=223} 2.6964 - static int input_getcurrentinputstatus(lua_State *L) 2.6965 - { 2.6966 - lua_newtable(L); 2.6967 +static int input_getcurrentinputstatus(lua_State *L) 2.6968 +{ 2.6969 + lua_newtable(L); 2.6970 2.6971 #if (defined(WIN32) && !defined(SDL)) 2.6972 - // keyboard and mouse button status 2.6973 - { 2.6974 - unsigned char keys[256]; 2.6975 - if (true /*!GUI.BackgroundInput*/) // TODO: background input 2.6976 - { 2.6977 - if (GetKeyboardState(keys)) 2.6978 - { 2.6979 - for (int i = 1; i < 255; i++) 2.6980 - { 2.6981 - int mask = (i == VK_CAPITAL || i == VK_NUMLOCK || i == VK_SCROLL) ? 0x01 : 0x80; 2.6982 - if (keys[i] & mask) 2.6983 - { 2.6984 - const char *name = s_keyToName[i]; 2.6985 - if (name) 2.6986 - { 2.6987 - lua_pushboolean(L, true); 2.6988 - lua_setfield(L, -2, name); 2.6989 - } 2.6990 - } 2.6991 - } 2.6992 - } 2.6993 - } 2.6994 - else // use a slightly different method that will detect background input: 2.6995 - { 2.6996 - for (int i = 1; i < 255; i++) 2.6997 - { 2.6998 - const char *name = s_keyToName[i]; 2.6999 - if (name) 2.7000 - { 2.7001 - int active; 2.7002 - if (i == VK_CAPITAL || i == VK_NUMLOCK || i == VK_SCROLL) 2.7003 - active = GetKeyState(i) & 0x01; 2.7004 - else 2.7005 - active = GetAsyncKeyState(i) & 0x8000; 2.7006 - if (active) 2.7007 - { 2.7008 - lua_pushboolean(L, true); 2.7009 - lua_setfield(L, -2, name); 2.7010 - } 2.7011 - } 2.7012 - } 2.7013 - } 2.7014 - } 2.7015 - 2.7016 - // mouse position in game screen pixel coordinates 2.7017 - { 2.7018 - POINT mouse; 2.7019 - 2.7020 - int xofs = 0, yofs = 0, width = 240, height = 160; 2.7021 - if (!systemIsRunningGBA()) 2.7022 - { 2.7023 - if (gbBorderOn) 2.7024 - width = 256, height = 224, xofs = 48, yofs = 40; 2.7025 - else 2.7026 - width = 160, height = 144; 2.7027 - } 2.7028 - 2.7029 - GetCursorPos(&mouse); 2.7030 - AfxGetApp()->m_pMainWnd->ScreenToClient(&mouse); 2.7031 - 2.7032 - // game screen is always fully stretched to window size, 2.7033 - // with no aspect rate correction, or something like that. 2.7034 - RECT clientRect; 2.7035 - AfxGetApp()->m_pMainWnd->GetClientRect(&clientRect); 2.7036 - 2.7037 - int wndWidth = clientRect.right - clientRect.left; 2.7038 - int wndHeight = clientRect.bottom - clientRect.top; 2.7039 - mouse.x = (LONG) (mouse.x * ((float)width / wndWidth)) - xofs; 2.7040 - mouse.y = (LONG) (mouse.y * ((float)height / wndHeight)) - yofs; 2.7041 - 2.7042 - lua_pushinteger(L, mouse.x); 2.7043 - lua_setfield(L, -2, "xmouse"); 2.7044 - lua_pushinteger(L, mouse.y); 2.7045 - lua_setfield(L, -2, "ymouse"); 2.7046 - } 2.7047 + // keyboard and mouse button status 2.7048 + { 2.7049 + unsigned char keys[256]; 2.7050 + if (true /*!GUI.BackgroundInput*/) // TODO: background input 2.7051 + { 2.7052 + if (GetKeyboardState(keys)) 2.7053 + { 2.7054 + for (int i = 1; i < 255; i++) 2.7055 + { 2.7056 + int mask = (i == VK_CAPITAL || i == VK_NUMLOCK || i == VK_SCROLL) ? 0x01 : 0x80; 2.7057 + if (keys[i] & mask) 2.7058 + { 2.7059 + const char *name = s_keyToName[i]; 2.7060 + if (name) 2.7061 + { 2.7062 + lua_pushboolean(L, true); 2.7063 + lua_setfield(L, -2, name); 2.7064 + } 2.7065 + } 2.7066 + } 2.7067 + } 2.7068 + } 2.7069 + else // use a slightly different method that will detect background input: 2.7070 + { 2.7071 + for (int i = 1; i < 255; i++) 2.7072 + { 2.7073 + const char *name = s_keyToName[i]; 2.7074 + if (name) 2.7075 + { 2.7076 + int active; 2.7077 + if (i == VK_CAPITAL || i == VK_NUMLOCK || i == VK_SCROLL) 2.7078 + active = GetKeyState(i) & 0x01; 2.7079 + else 2.7080 + active = GetAsyncKeyState(i) & 0x8000; 2.7081 + if (active) 2.7082 + { 2.7083 + lua_pushboolean(L, true); 2.7084 + lua_setfield(L, -2, name); 2.7085 + } 2.7086 + } 2.7087 + } 2.7088 + } 2.7089 + } 2.7090 + 2.7091 + // mouse position in game screen pixel coordinates 2.7092 + { 2.7093 + POINT mouse; 2.7094 + 2.7095 + int xofs = 0, yofs = 0, width = 240, height = 160; 2.7096 + if (!systemIsRunningGBA()) 2.7097 + { 2.7098 + if (gbBorderOn) 2.7099 + width = 256, height = 224, xofs = 48, yofs = 40; 2.7100 + else 2.7101 + width = 160, height = 144; 2.7102 + } 2.7103 + 2.7104 + GetCursorPos(&mouse); 2.7105 + AfxGetApp()->m_pMainWnd->ScreenToClient(&mouse); 2.7106 + 2.7107 + // game screen is always fully stretched to window size, 2.7108 + // with no aspect rate correction, or something like that. 2.7109 + RECT clientRect; 2.7110 + AfxGetApp()->m_pMainWnd->GetClientRect(&clientRect); 2.7111 + 2.7112 + int wndWidth = clientRect.right - clientRect.left; 2.7113 + int wndHeight = clientRect.bottom - clientRect.top; 2.7114 + mouse.x = (LONG) (mouse.x * ((float)width / wndWidth)) - xofs; 2.7115 + mouse.y = (LONG) (mouse.y * ((float)height / wndHeight)) - yofs; 2.7116 + 2.7117 + lua_pushinteger(L, mouse.x); 2.7118 + lua_setfield(L, -2, "xmouse"); 2.7119 + lua_pushinteger(L, mouse.y); 2.7120 + lua_setfield(L, -2, "ymouse"); 2.7121 + } 2.7122 2.7123 #else 2.7124 - // NYI (well, return an empty table) 2.7125 + // NYI (well, return an empty table) 2.7126 #endif 2.7127 - return 1; 2.7128 - } 2.7129 - 2.7130 - static int avi_framecount(lua_State *L) 2.7131 - { 2.7132 - #ifdef WIN32 2.7133 - if (theApp.aviRecorder != NULL) 2.7134 - { 2.7135 - lua_pushinteger(L, theApp.aviRecorder->videoFrames()); 2.7136 - } 2.7137 - else 2.7138 - #endif 2.7139 - { 2.7140 - lua_pushinteger(L, 0); 2.7141 - } 2.7142 - return 1; 2.7143 - } 2.7144 - 2.7145 - static int avi_pause(lua_State *L) 2.7146 - { 2.7147 - #ifdef WIN32 2.7148 - if (theApp.aviRecorder != NULL) 2.7149 - theApp.aviRecorder->Pause(true); 2.7150 - #endif 2.7151 - return 1; 2.7152 - } 2.7153 - 2.7154 - static int avi_resume(lua_State *L) 2.7155 - { 2.7156 - #ifdef WIN32 2.7157 - if (theApp.aviRecorder != NULL) 2.7158 - theApp.aviRecorder->Pause(false); 2.7159 - #endif 2.7160 - return 1; 2.7161 - } 2.7162 - 2.7163 - static int sound_get(lua_State *L) 2.7164 - { 2.7165 - extern int32 soundLevel1; 2.7166 - extern int32 soundLevel2; 2.7167 - extern int32 soundBalance; 2.7168 - extern int32 soundMasterOn; 2.7169 - extern int32 soundVIN; 2.7170 - extern int32 sound1On; 2.7171 - extern int32 sound1EnvelopeVolume; 2.7172 - extern int32 sound2On; 2.7173 - extern int32 sound2EnvelopeVolume; 2.7174 - extern int32 sound3On; 2.7175 - extern int32 sound3OutputLevel; 2.7176 - extern int32 sound3Bank; 2.7177 - extern int32 sound3DataSize; 2.7178 - extern int32 sound3ForcedOutput; 2.7179 - extern int32 sound4On; 2.7180 - extern int32 sound4EnvelopeVolume; 2.7181 - extern u8 sound3WaveRam[0x20]; 2.7182 - 2.7183 - int freqReg; 2.7184 - double freq; 2.7185 - double leftvolscale; 2.7186 - double rightvolscale; 2.7187 - double panpot; 2.7188 - bool gba = systemIsRunningGBA(); 2.7189 - u8* gbMem = gba ? ioMem : gbMemory; 2.7190 - const int rNR10 = gba ? 0x60 : 0xff10; 2.7191 - const int rNR11 = gba ? 0x62 : 0xff11; 2.7192 - const int rNR12 = gba ? 0x63 : 0xff12; 2.7193 - const int rNR13 = gba ? 0x64 : 0xff13; 2.7194 - const int rNR14 = gba ? 0x65 : 0xff14; 2.7195 - const int rNR21 = gba ? 0x68 : 0xff16; 2.7196 - const int rNR22 = gba ? 0x69 : 0xff17; 2.7197 - const int rNR23 = gba ? 0x6c : 0xff18; 2.7198 - const int rNR24 = gba ? 0x6d : 0xff19; 2.7199 - const int rNR30 = gba ? 0x70 : 0xff1a; 2.7200 - const int rNR31 = gba ? 0x72 : 0xff1b; 2.7201 - const int rNR32 = gba ? 0x73 : 0xff1c; 2.7202 - const int rNR33 = gba ? 0x74 : 0xff1d; 2.7203 - const int rNR34 = gba ? 0x75 : 0xff1e; 2.7204 - const int rNR41 = gba ? 0x78 : 0xff20; 2.7205 - const int rNR42 = gba ? 0x79 : 0xff21; 2.7206 - const int rNR43 = gba ? 0x7c : 0xff22; 2.7207 - const int rNR44 = gba ? 0x7d : 0xff23; 2.7208 - const int rNR50 = gba ? 0x80 : 0xff24; 2.7209 - const int rNR51 = gba ? 0x81 : 0xff25; 2.7210 - const int rNR52 = gba ? 0x84 : 0xff26; 2.7211 - const int rWAVE_RAM = gba ? 0x90 : 0xff30; 2.7212 - 2.7213 - const int32 _soundVIN = 0x88; // gba ? 0x88 : soundVIN; 2.7214 - const bool soundVINLeft = ((_soundVIN & 0x80) != 0); 2.7215 - const bool soundVINRight = ((_soundVIN & 0x08) != 0); 2.7216 - 2.7217 - lua_newtable(L); 2.7218 - 2.7219 - // square1 2.7220 - lua_newtable(L); 2.7221 - if(sound1On == 0 || soundMasterOn == 0) 2.7222 - { 2.7223 - lua_pushnumber(L, 0.0); 2.7224 - panpot = 0.5; 2.7225 - } 2.7226 - else 2.7227 - { 2.7228 - double envVolume = sound1EnvelopeVolume / 15.0; 2.7229 - if (soundVINLeft && (soundBalance & 0x10) != 0) 2.7230 - leftvolscale = ((soundLevel2 / 7.0) * envVolume); 2.7231 - else 2.7232 - leftvolscale = 0.0; 2.7233 - if (soundVINRight && (soundBalance & 0x01) != 0) 2.7234 - rightvolscale = ((soundLevel1 / 7.0) * envVolume); 2.7235 - else 2.7236 - rightvolscale = 0.0; 2.7237 - if ((leftvolscale + rightvolscale) != 0) 2.7238 - panpot = rightvolscale / (leftvolscale + rightvolscale); 2.7239 - else 2.7240 - panpot = 0.5; 2.7241 - lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 2.7242 - } 2.7243 - lua_setfield(L, -2, "volume"); 2.7244 - lua_pushnumber(L, panpot); 2.7245 - lua_setfield(L, -2, "panpot"); 2.7246 - freqReg = (((int)(gbMem[rNR14] & 7) << 8) | gbMem[rNR13]); 2.7247 - freq = 131072.0 / (2048 - freqReg); 2.7248 - lua_pushnumber(L, freq); 2.7249 - lua_setfield(L, -2, "frequency"); 2.7250 - lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 2.7251 - lua_setfield(L, -2, "midikey"); 2.7252 - lua_pushinteger(L, (gbMem[rNR11] & 0xC0) >> 6); 2.7253 - lua_setfield(L, -2, "duty"); 2.7254 - lua_newtable(L); 2.7255 - lua_pushinteger(L, freqReg); 2.7256 - lua_setfield(L, -2, "frequency"); 2.7257 - lua_setfield(L, -2, "regs"); 2.7258 - lua_setfield(L, -2, "square1"); 2.7259 - // square2 2.7260 - lua_newtable(L); 2.7261 - if(sound2On == 0 || soundMasterOn == 0) 2.7262 - { 2.7263 - lua_pushnumber(L, 0.0); 2.7264 - panpot = 0.5; 2.7265 - } 2.7266 - else 2.7267 - { 2.7268 - double envVolume = sound2EnvelopeVolume / 15.0; 2.7269 - if (soundVINLeft && (soundBalance & 0x20) != 0) 2.7270 - leftvolscale = ((soundLevel2 / 7.0) * envVolume); 2.7271 - else 2.7272 - leftvolscale = 0.0; 2.7273 - if (soundVINRight && (soundBalance & 0x02) != 0) 2.7274 - rightvolscale = ((soundLevel1 / 7.0) * envVolume); 2.7275 - else 2.7276 - rightvolscale = 0.0; 2.7277 - if ((leftvolscale + rightvolscale) != 0) 2.7278 - panpot = rightvolscale / (leftvolscale + rightvolscale); 2.7279 - else 2.7280 - panpot = 0.5; 2.7281 - lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 2.7282 - } 2.7283 - lua_setfield(L, -2, "volume"); 2.7284 - lua_pushnumber(L, panpot); 2.7285 - lua_setfield(L, -2, "panpot"); 2.7286 - freqReg = (((int)(gbMem[rNR24] & 7) << 8) | gbMem[rNR23]); 2.7287 - freq = 131072.0 / (2048 - freqReg); 2.7288 - lua_pushnumber(L, freq); 2.7289 - lua_setfield(L, -2, "frequency"); 2.7290 - lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 2.7291 - lua_setfield(L, -2, "midikey"); 2.7292 - lua_pushinteger(L, (gbMem[rNR21] & 0xC0) >> 6); 2.7293 - lua_setfield(L, -2, "duty"); 2.7294 - lua_newtable(L); 2.7295 - lua_pushinteger(L, freqReg); 2.7296 - lua_setfield(L, -2, "frequency"); 2.7297 - lua_setfield(L, -2, "regs"); 2.7298 - lua_setfield(L, -2, "square2"); 2.7299 - // wavememory 2.7300 - lua_newtable(L); 2.7301 - if(sound3On == 0 || soundMasterOn == 0) 2.7302 - { 2.7303 - lua_pushnumber(L, 0.0); 2.7304 - panpot = 0.5; 2.7305 - } 2.7306 - else 2.7307 - { 2.7308 - double envVolume; 2.7309 - if (gba && sound3ForcedOutput != 0) 2.7310 - envVolume = 0.75; 2.7311 - else 2.7312 - { 2.7313 - double volTable[4] = { 0.0, 1.0, 0.5, 0.25 }; 2.7314 - envVolume = volTable[sound3OutputLevel & 3]; 2.7315 - } 2.7316 - 2.7317 - if (soundVINLeft && (soundBalance & 0x40) != 0) 2.7318 - leftvolscale = ((soundLevel2 / 7.0) * envVolume); 2.7319 - else 2.7320 - leftvolscale = 0.0; 2.7321 - if (soundVINRight && (soundBalance & 0x04) != 0) 2.7322 - rightvolscale = ((soundLevel1 / 7.0) * envVolume); 2.7323 - else 2.7324 - rightvolscale = 0.0; 2.7325 - if ((leftvolscale + rightvolscale) != 0) 2.7326 - panpot = rightvolscale / (leftvolscale + rightvolscale); 2.7327 - else 2.7328 - panpot = 0.5; 2.7329 - lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 2.7330 - } 2.7331 - lua_setfield(L, -2, "volume"); 2.7332 - lua_pushnumber(L, panpot); 2.7333 - lua_setfield(L, -2, "panpot"); 2.7334 - int waveMemSamples = 32; 2.7335 - if (gba) 2.7336 - { 2.7337 - lua_pushlstring(L, (const char *) &sound3WaveRam[sound3Bank * 0x10], sound3DataSize ? 0x20 : 0x10); 2.7338 - waveMemSamples = sound3DataSize ? 64 : 32; 2.7339 - } 2.7340 - else 2.7341 - { 2.7342 - lua_pushlstring(L, (const char *) &gbMem[rWAVE_RAM], 0x10); 2.7343 - } 2.7344 - lua_setfield(L, -2, "waveform"); 2.7345 - freqReg = (((int)(gbMem[rNR34] & 7) << 8) | gbMem[rNR33]); 2.7346 - freq = 2097152.0 / (waveMemSamples * (2048 - freqReg)); 2.7347 - lua_pushnumber(L, freq); 2.7348 - lua_setfield(L, -2, "frequency"); 2.7349 - lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 2.7350 - lua_setfield(L, -2, "midikey"); 2.7351 - lua_newtable(L); 2.7352 - lua_pushinteger(L, freqReg); 2.7353 - lua_setfield(L, -2, "frequency"); 2.7354 - lua_setfield(L, -2, "regs"); 2.7355 - lua_setfield(L, -2, "wavememory"); 2.7356 - // noise 2.7357 - lua_newtable(L); 2.7358 - if(sound4On == 0 || soundMasterOn == 0) 2.7359 - { 2.7360 - lua_pushnumber(L, 0.0); 2.7361 - panpot = 0.5; 2.7362 - } 2.7363 - else 2.7364 - { 2.7365 - double envVolume = sound4EnvelopeVolume / 15.0; 2.7366 - if (soundVINLeft && (soundBalance & 0x80) != 0) 2.7367 - leftvolscale = ((soundLevel2 / 7.0) * envVolume); 2.7368 - else 2.7369 - leftvolscale = 0.0; 2.7370 - if (soundVINRight && (soundBalance & 0x08) != 0) 2.7371 - rightvolscale = ((soundLevel1 / 7.0) * envVolume); 2.7372 - else 2.7373 - rightvolscale = 0.0; 2.7374 - if ((leftvolscale + rightvolscale) != 0) 2.7375 - panpot = rightvolscale / (leftvolscale + rightvolscale); 2.7376 - else 2.7377 - panpot = 0.5; 2.7378 - lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 2.7379 - } 2.7380 - lua_setfield(L, -2, "volume"); 2.7381 - lua_pushnumber(L, panpot); 2.7382 - lua_setfield(L, -2, "panpot"); 2.7383 - const int gbNoiseFreqTable[8] = { 1, 2, 4, 6, 8, 10, 12, 14 }; 2.7384 - freqReg = gbNoiseFreqTable[gbMem[rNR43] & 7] << (1 + (gbMem[rNR43] >> 4)); 2.7385 - lua_pushboolean(L, (gbMem[rNR43] & 8) != 0); 2.7386 - lua_setfield(L, -2, "short"); 2.7387 - freq = 1048576.0 / freqReg; 2.7388 - lua_pushnumber(L, freq); 2.7389 - lua_setfield(L, -2, "frequency"); 2.7390 - lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 2.7391 - lua_setfield(L, -2, "midikey"); 2.7392 - lua_newtable(L); 2.7393 - lua_pushinteger(L, freqReg); 2.7394 - lua_setfield(L, -2, "frequency"); 2.7395 - lua_setfield(L, -2, "regs"); 2.7396 - lua_setfield(L, -2, "noise"); 2.7397 - 2.7398 - return 1; 2.7399 - } 2.7400 + return 1; 2.7401 +} 2.7402 + 2.7403 +static int avi_framecount(lua_State *L) 2.7404 +{ 2.7405 +#ifdef WIN32 2.7406 + if (theApp.aviRecorder != NULL) 2.7407 + { 2.7408 + lua_pushinteger(L, theApp.aviRecorder->videoFrames()); 2.7409 + } 2.7410 + else 2.7411 +#endif 2.7412 + { 2.7413 + lua_pushinteger(L, 0); 2.7414 + } 2.7415 + return 1; 2.7416 +} 2.7417 + 2.7418 +static int avi_pause(lua_State *L) 2.7419 +{ 2.7420 +#ifdef WIN32 2.7421 + if (theApp.aviRecorder != NULL) 2.7422 + theApp.aviRecorder->Pause(true); 2.7423 +#endif 2.7424 + return 1; 2.7425 +} 2.7426 + 2.7427 +static int avi_resume(lua_State *L) 2.7428 +{ 2.7429 +#ifdef WIN32 2.7430 + if (theApp.aviRecorder != NULL) 2.7431 + theApp.aviRecorder->Pause(false); 2.7432 +#endif 2.7433 + return 1; 2.7434 +} 2.7435 + 2.7436 +static int sound_get(lua_State *L) 2.7437 +{ 2.7438 + extern int32 soundLevel1; 2.7439 + extern int32 soundLevel2; 2.7440 + extern int32 soundBalance; 2.7441 + extern int32 soundMasterOn; 2.7442 + extern int32 soundVIN; 2.7443 + extern int32 sound1On; 2.7444 + extern int32 sound1EnvelopeVolume; 2.7445 + extern int32 sound2On; 2.7446 + extern int32 sound2EnvelopeVolume; 2.7447 + extern int32 sound3On; 2.7448 + extern int32 sound3OutputLevel; 2.7449 + extern int32 sound3Bank; 2.7450 + extern int32 sound3DataSize; 2.7451 + extern int32 sound3ForcedOutput; 2.7452 + extern int32 sound4On; 2.7453 + extern int32 sound4EnvelopeVolume; 2.7454 + extern u8 sound3WaveRam[0x20]; 2.7455 + 2.7456 + int freqReg; 2.7457 + double freq; 2.7458 + double leftvolscale; 2.7459 + double rightvolscale; 2.7460 + double panpot; 2.7461 + bool gba = systemIsRunningGBA(); 2.7462 + u8* gbMem = gba ? ioMem : gbMemory; 2.7463 + const int rNR10 = gba ? 0x60 : 0xff10; 2.7464 + const int rNR11 = gba ? 0x62 : 0xff11; 2.7465 + const int rNR12 = gba ? 0x63 : 0xff12; 2.7466 + const int rNR13 = gba ? 0x64 : 0xff13; 2.7467 + const int rNR14 = gba ? 0x65 : 0xff14; 2.7468 + const int rNR21 = gba ? 0x68 : 0xff16; 2.7469 + const int rNR22 = gba ? 0x69 : 0xff17; 2.7470 + const int rNR23 = gba ? 0x6c : 0xff18; 2.7471 + const int rNR24 = gba ? 0x6d : 0xff19; 2.7472 + const int rNR30 = gba ? 0x70 : 0xff1a; 2.7473 + const int rNR31 = gba ? 0x72 : 0xff1b; 2.7474 + const int rNR32 = gba ? 0x73 : 0xff1c; 2.7475 + const int rNR33 = gba ? 0x74 : 0xff1d; 2.7476 + const int rNR34 = gba ? 0x75 : 0xff1e; 2.7477 + const int rNR41 = gba ? 0x78 : 0xff20; 2.7478 + const int rNR42 = gba ? 0x79 : 0xff21; 2.7479 + const int rNR43 = gba ? 0x7c : 0xff22; 2.7480 + const int rNR44 = gba ? 0x7d : 0xff23; 2.7481 + const int rNR50 = gba ? 0x80 : 0xff24; 2.7482 + const int rNR51 = gba ? 0x81 : 0xff25; 2.7483 + const int rNR52 = gba ? 0x84 : 0xff26; 2.7484 + const int rWAVE_RAM = gba ? 0x90 : 0xff30; 2.7485 + 2.7486 + const int32 _soundVIN = 0x88; // gba ? 0x88 : soundVIN; 2.7487 + const bool soundVINLeft = ((_soundVIN & 0x80) != 0); 2.7488 + const bool soundVINRight = ((_soundVIN & 0x08) != 0); 2.7489 + 2.7490 + lua_newtable(L); 2.7491 + 2.7492 + // square1 2.7493 + lua_newtable(L); 2.7494 + if(sound1On == 0 || soundMasterOn == 0) 2.7495 + { 2.7496 + lua_pushnumber(L, 0.0); 2.7497 + panpot = 0.5; 2.7498 + } 2.7499 + else 2.7500 + { 2.7501 + double envVolume = sound1EnvelopeVolume / 15.0; 2.7502 + if (soundVINLeft && (soundBalance & 0x10) != 0) 2.7503 + leftvolscale = ((soundLevel2 / 7.0) * envVolume); 2.7504 + else 2.7505 + leftvolscale = 0.0; 2.7506 + if (soundVINRight && (soundBalance & 0x01) != 0) 2.7507 + rightvolscale = ((soundLevel1 / 7.0) * envVolume); 2.7508 + else 2.7509 + rightvolscale = 0.0; 2.7510 + if ((leftvolscale + rightvolscale) != 0) 2.7511 + panpot = rightvolscale / (leftvolscale + rightvolscale); 2.7512 + else 2.7513 + panpot = 0.5; 2.7514 + lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 2.7515 + } 2.7516 + lua_setfield(L, -2, "volume"); 2.7517 + lua_pushnumber(L, panpot); 2.7518 + lua_setfield(L, -2, "panpot"); 2.7519 + freqReg = (((int)(gbMem[rNR14] & 7) << 8) | gbMem[rNR13]); 2.7520 + freq = 131072.0 / (2048 - freqReg); 2.7521 + lua_pushnumber(L, freq); 2.7522 + lua_setfield(L, -2, "frequency"); 2.7523 + lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 2.7524 + lua_setfield(L, -2, "midikey"); 2.7525 + lua_pushinteger(L, (gbMem[rNR11] & 0xC0) >> 6); 2.7526 + lua_setfield(L, -2, "duty"); 2.7527 + lua_newtable(L); 2.7528 + lua_pushinteger(L, freqReg); 2.7529 + lua_setfield(L, -2, "frequency"); 2.7530 + lua_setfield(L, -2, "regs"); 2.7531 + lua_setfield(L, -2, "square1"); 2.7532 + // square2 2.7533 + lua_newtable(L); 2.7534 + if(sound2On == 0 || soundMasterOn == 0) 2.7535 + { 2.7536 + lua_pushnumber(L, 0.0); 2.7537 + panpot = 0.5; 2.7538 + } 2.7539 + else 2.7540 + { 2.7541 + double envVolume = sound2EnvelopeVolume / 15.0; 2.7542 + if (soundVINLeft && (soundBalance & 0x20) != 0) 2.7543 + leftvolscale = ((soundLevel2 / 7.0) * envVolume); 2.7544 + else 2.7545 + leftvolscale = 0.0; 2.7546 + if (soundVINRight && (soundBalance & 0x02) != 0) 2.7547 + rightvolscale = ((soundLevel1 / 7.0) * envVolume); 2.7548 + else 2.7549 + rightvolscale = 0.0; 2.7550 + if ((leftvolscale + rightvolscale) != 0) 2.7551 + panpot = rightvolscale / (leftvolscale + rightvolscale); 2.7552 + else 2.7553 + panpot = 0.5; 2.7554 + lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 2.7555 + } 2.7556 + lua_setfield(L, -2, "volume"); 2.7557 + lua_pushnumber(L, panpot); 2.7558 + lua_setfield(L, -2, "panpot"); 2.7559 + freqReg = (((int)(gbMem[rNR24] & 7) << 8) | gbMem[rNR23]); 2.7560 + freq = 131072.0 / (2048 - freqReg); 2.7561 + lua_pushnumber(L, freq); 2.7562 + lua_setfield(L, -2, "frequency"); 2.7563 + lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 2.7564 + lua_setfield(L, -2, "midikey"); 2.7565 + lua_pushinteger(L, (gbMem[rNR21] & 0xC0) >> 6); 2.7566 + lua_setfield(L, -2, "duty"); 2.7567 + lua_newtable(L); 2.7568 + lua_pushinteger(L, freqReg); 2.7569 + lua_setfield(L, -2, "frequency"); 2.7570 + lua_setfield(L, -2, "regs"); 2.7571 + lua_setfield(L, -2, "square2"); 2.7572 + // wavememory 2.7573 + lua_newtable(L); 2.7574 + if(sound3On == 0 || soundMasterOn == 0) 2.7575 + { 2.7576 + lua_pushnumber(L, 0.0); 2.7577 + panpot = 0.5; 2.7578 + } 2.7579 + else 2.7580 + { 2.7581 + double envVolume; 2.7582 + if (gba && sound3ForcedOutput != 0) 2.7583 + envVolume = 0.75; 2.7584 + else 2.7585 + { 2.7586 + double volTable[4] = { 0.0, 1.0, 0.5, 0.25 }; 2.7587 + envVolume = volTable[sound3OutputLevel & 3]; 2.7588 + } 2.7589 + 2.7590 + if (soundVINLeft && (soundBalance & 0x40) != 0) 2.7591 + leftvolscale = ((soundLevel2 / 7.0) * envVolume); 2.7592 + else 2.7593 + leftvolscale = 0.0; 2.7594 + if (soundVINRight && (soundBalance & 0x04) != 0) 2.7595 + rightvolscale = ((soundLevel1 / 7.0) * envVolume); 2.7596 + else 2.7597 + rightvolscale = 0.0; 2.7598 + if ((leftvolscale + rightvolscale) != 0) 2.7599 + panpot = rightvolscale / (leftvolscale + rightvolscale); 2.7600 + else 2.7601 + panpot = 0.5; 2.7602 + lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 2.7603 + } 2.7604 + lua_setfield(L, -2, "volume"); 2.7605 + lua_pushnumber(L, panpot); 2.7606 + lua_setfield(L, -2, "panpot"); 2.7607 + int waveMemSamples = 32; 2.7608 + if (gba) 2.7609 + { 2.7610 + lua_pushlstring(L, (const char *) &sound3WaveRam[sound3Bank * 0x10], sound3DataSize ? 0x20 : 0x10); 2.7611 + waveMemSamples = sound3DataSize ? 64 : 32; 2.7612 + } 2.7613 + else 2.7614 + { 2.7615 + lua_pushlstring(L, (const char *) &gbMem[rWAVE_RAM], 0x10); 2.7616 + } 2.7617 + lua_setfield(L, -2, "waveform"); 2.7618 + freqReg = (((int)(gbMem[rNR34] & 7) << 8) | gbMem[rNR33]); 2.7619 + freq = 2097152.0 / (waveMemSamples * (2048 - freqReg)); 2.7620 + lua_pushnumber(L, freq); 2.7621 + lua_setfield(L, -2, "frequency"); 2.7622 + lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 2.7623 + lua_setfield(L, -2, "midikey"); 2.7624 + lua_newtable(L); 2.7625 + lua_pushinteger(L, freqReg); 2.7626 + lua_setfield(L, -2, "frequency"); 2.7627 + lua_setfield(L, -2, "regs"); 2.7628 + lua_setfield(L, -2, "wavememory"); 2.7629 + // noise 2.7630 + lua_newtable(L); 2.7631 + if(sound4On == 0 || soundMasterOn == 0) 2.7632 + { 2.7633 + lua_pushnumber(L, 0.0); 2.7634 + panpot = 0.5; 2.7635 + } 2.7636 + else 2.7637 + { 2.7638 + double envVolume = sound4EnvelopeVolume / 15.0; 2.7639 + if (soundVINLeft && (soundBalance & 0x80) != 0) 2.7640 + leftvolscale = ((soundLevel2 / 7.0) * envVolume); 2.7641 + else 2.7642 + leftvolscale = 0.0; 2.7643 + if (soundVINRight && (soundBalance & 0x08) != 0) 2.7644 + rightvolscale = ((soundLevel1 / 7.0) * envVolume); 2.7645 + else 2.7646 + rightvolscale = 0.0; 2.7647 + if ((leftvolscale + rightvolscale) != 0) 2.7648 + panpot = rightvolscale / (leftvolscale + rightvolscale); 2.7649 + else 2.7650 + panpot = 0.5; 2.7651 + lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 2.7652 + } 2.7653 + lua_setfield(L, -2, "volume"); 2.7654 + lua_pushnumber(L, panpot); 2.7655 + lua_setfield(L, -2, "panpot"); 2.7656 + const int gbNoiseFreqTable[8] = { 1, 2, 4, 6, 8, 10, 12, 14 }; 2.7657 + freqReg = gbNoiseFreqTable[gbMem[rNR43] & 7] << (1 + (gbMem[rNR43] >> 4)); 2.7658 + lua_pushboolean(L, (gbMem[rNR43] & 8) != 0); 2.7659 + lua_setfield(L, -2, "short"); 2.7660 + freq = 1048576.0 / freqReg; 2.7661 + lua_pushnumber(L, freq); 2.7662 + lua_setfield(L, -2, "frequency"); 2.7663 + lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 2.7664 + lua_setfield(L, -2, "midikey"); 2.7665 + lua_newtable(L); 2.7666 + lua_pushinteger(L, freqReg); 2.7667 + lua_setfield(L, -2, "frequency"); 2.7668 + lua_setfield(L, -2, "regs"); 2.7669 + lua_setfield(L, -2, "noise"); 2.7670 + 2.7671 + return 1; 2.7672 +} 2.7673 2.7674 // same as math.random, but uses SFMT instead of C rand() 2.7675 // FIXME: this function doesn't care multi-instance, 2.7676 2.7677 // original math.random either though (Lua 5.1) 2.7678 - static int sfmt_random(lua_State *L) 2.7679 - { 2.7680 - lua_Number r = (lua_Number) genrand_real2(); 2.7681 - switch (lua_gettop(L)) 2.7682 - { // check number of arguments 2.7683 - case 0: 2.7684 - { // no arguments 2.7685 - lua_pushnumber(L, r); // Number between 0 and 1 2.7686 - break; 2.7687 - } 2.7688 - 2.7689 - case 1: 2.7690 - { // only upper limit 2.7691 - int u = luaL_checkint(L, 1); 2.7692 - luaL_argcheck(L, 1 <= u, 1, "interval is empty"); 2.7693 - lua_pushnumber(L, floor(r * u) + 1); // int between 1 and `u' 2.7694 - break; 2.7695 - } 2.7696 - 2.7697 - case 2: 2.7698 - { // lower and upper limits 2.7699 - int l = luaL_checkint(L, 1); 2.7700 - int u = luaL_checkint(L, 2); 2.7701 - luaL_argcheck(L, l <= u, 2, "interval is empty"); 2.7702 - lua_pushnumber(L, floor(r * (u - l + 1)) + l); // int between `l' and `u' 2.7703 - break; 2.7704 - } 2.7705 - 2.7706 - default: 2.7707 - return luaL_error(L, "wrong number of arguments"); 2.7708 - } 2.7709 - 2.7710 - return 1; 2.7711 - } 2.7712 +static int sfmt_random(lua_State *L) 2.7713 +{ 2.7714 + lua_Number r = (lua_Number) genrand_real2(); 2.7715 + switch (lua_gettop(L)) 2.7716 + { // check number of arguments 2.7717 + case 0: 2.7718 + { // no arguments 2.7719 + lua_pushnumber(L, r); // Number between 0 and 1 2.7720 + break; 2.7721 + } 2.7722 + 2.7723 + case 1: 2.7724 + { // only upper limit 2.7725 + int u = luaL_checkint(L, 1); 2.7726 + luaL_argcheck(L, 1 <= u, 1, "interval is empty"); 2.7727 + lua_pushnumber(L, floor(r * u) + 1); // int between 1 and `u' 2.7728 + break; 2.7729 + } 2.7730 + 2.7731 + case 2: 2.7732 + { // lower and upper limits 2.7733 + int l = luaL_checkint(L, 1); 2.7734 + int u = luaL_checkint(L, 2); 2.7735 + luaL_argcheck(L, l <= u, 2, "interval is empty"); 2.7736 + lua_pushnumber(L, floor(r * (u - l + 1)) + l); // int between `l' and `u' 2.7737 + break; 2.7738 + } 2.7739 + 2.7740 + default: 2.7741 + return luaL_error(L, "wrong number of arguments"); 2.7742 + } 2.7743 + 2.7744 + return 1; 2.7745 +} 2.7746 2.7747 // same as math.randomseed, but uses SFMT instead of C srand() 2.7748 // FIXME: this function doesn't care multi-instance, 2.7749 2.7750 // original math.randomseed either though (Lua 5.1) 2.7751 - static int sfmt_randomseed(lua_State *L) 2.7752 - { 2.7753 - init_gen_rand(luaL_checkint(L, 1)); 2.7754 - return 0; 2.7755 - } 2.7756 +static int sfmt_randomseed(lua_State *L) 2.7757 +{ 2.7758 + init_gen_rand(luaL_checkint(L, 1)); 2.7759 + return 0; 2.7760 +} 2.7761 2.7762 // the following bit operations are ported from LuaBitOp 1.0.1, 2.7763 // because it can handle the sign bit (bit 31) correctly. 2.7764 @@ -4250,123 +4250,123 @@ 2.7765 2.7766 #ifdef _MSC_VER 2.7767 /* MSVC is stuck in the last century and doesn't have C99's stdint.h. */ 2.7768 - typedef __int32 int32_t; 2.7769 - typedef unsigned __int32 uint32_t; 2.7770 - typedef unsigned __int64 uint64_t; 2.7771 +typedef __int32 int32_t; 2.7772 +typedef unsigned __int32 uint32_t; 2.7773 +typedef unsigned __int64 uint64_t; 2.7774 #else 2.7775 #include <stdint.h> 2.7776 #endif 2.7777 2.7778 - typedef int32_t SBits; 2.7779 - typedef uint32_t UBits; 2.7780 - 2.7781 - typedef union 2.7782 - { 2.7783 - lua_Number n; 2.7784 +typedef int32_t SBits; 2.7785 +typedef uint32_t UBits; 2.7786 + 2.7787 +typedef union 2.7788 +{ 2.7789 + lua_Number n; 2.7790 #ifdef LUA_NUMBER_DOUBLE 2.7791 - uint64_t b; 2.7792 + uint64_t b; 2.7793 #else 2.7794 - UBits b; 2.7795 + UBits b; 2.7796 #endif 2.7797 - } BitNum; 2.7798 +} BitNum; 2.7799 2.7800 /* Convert argument to bit type. */ 2.7801 - static UBits barg(lua_State *L, int idx) 2.7802 - { 2.7803 - BitNum bn; 2.7804 - UBits b; 2.7805 - bn.n = lua_tonumber(L, idx); 2.7806 +static UBits barg(lua_State *L, int idx) 2.7807 +{ 2.7808 + BitNum bn; 2.7809 + UBits b; 2.7810 + bn.n = lua_tonumber(L, idx); 2.7811 #if defined(LUA_NUMBER_DOUBLE) 2.7812 - bn.n += 6755399441055744.0; /* 2^52+2^51 */ 2.7813 + bn.n += 6755399441055744.0; /* 2^52+2^51 */ 2.7814 #ifdef SWAPPED_DOUBLE 2.7815 - b = (UBits)(bn.b >> 32); 2.7816 + b = (UBits)(bn.b >> 32); 2.7817 #else 2.7818 - b = (UBits)(bn.b & 0xffffffff); 2.7819 + b = (UBits)(bn.b & 0xffffffff); 2.7820 #endif 2.7821 -#elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \ 2.7822 - defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \ 2.7823 - defined(LUA_NUMBER_LLONG) 2.7824 - if (sizeof(UBits) == sizeof(lua_Number)) 2.7825 - b = bn.b; 2.7826 - else 2.7827 - b = (UBits)(SBits)bn.n; 2.7828 +#elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \ 2.7829 + defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \ 2.7830 + defined(LUA_NUMBER_LLONG) 2.7831 + if (sizeof(UBits) == sizeof(lua_Number)) 2.7832 + b = bn.b; 2.7833 + else 2.7834 + b = (UBits)(SBits)bn.n; 2.7835 #elif defined(LUA_NUMBER_FLOAT) 2.7836 #error "A 'float' lua_Number type is incompatible with this library" 2.7837 #else 2.7838 #error "Unknown number type, check LUA_NUMBER_* in luaconf.h" 2.7839 #endif 2.7840 - if (b == 0 && !lua_isnumber(L, idx)) 2.7841 - luaL_typerror(L, idx, "number"); 2.7842 - return b; 2.7843 - } 2.7844 + if (b == 0 && !lua_isnumber(L, idx)) 2.7845 + luaL_typerror(L, idx, "number"); 2.7846 + return b; 2.7847 +} 2.7848 2.7849 /* Return bit type. */ 2.7850 #define BRET(b) lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1; 2.7851 2.7852 - static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) } 2.7853 - static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) } 2.7854 - 2.7855 -#define BIT_OP(func, opr) \ 2.7856 - static int func(lua_State * L) { int i; UBits b = barg(L, 1); \ 2.7857 - for (i = lua_gettop(L); i > 1; i--) \ 2.7858 - b opr barg(L, i); BRET(b) } 2.7859 - BIT_OP(bit_band, &= ) 2.7860 - BIT_OP(bit_bor, |= ) 2.7861 - BIT_OP(bit_bxor, ^= ) 2.7862 +static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) } 2.7863 +static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) } 2.7864 + 2.7865 +#define BIT_OP(func, opr) \ 2.7866 + static int func(lua_State * L) { int i; UBits b = barg(L, 1); \ 2.7867 + for (i = lua_gettop(L); i > 1; i--) \ 2.7868 + b opr barg(L, i); BRET(b) } 2.7869 +BIT_OP(bit_band, &= ) 2.7870 +BIT_OP(bit_bor, |= ) 2.7871 +BIT_OP(bit_bxor, ^= ) 2.7872 2.7873 #define bshl(b, n) (b << n) 2.7874 #define bshr(b, n) (b >> n) 2.7875 #define bsar(b, n) ((SBits)b >> n) 2.7876 #define brol(b, n) ((b << n) | (b >> (32 - n))) 2.7877 #define bror(b, n) ((b << (32 - n)) | (b >> n)) 2.7878 -#define BIT_SH(func, fn) \ 2.7879 - static int func(lua_State * L) { \ 2.7880 - UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) } 2.7881 - BIT_SH(bit_lshift, bshl) 2.7882 - BIT_SH(bit_rshift, bshr) 2.7883 - BIT_SH(bit_arshift, bsar) 2.7884 - BIT_SH(bit_rol, brol) 2.7885 - BIT_SH(bit_ror, bror) 2.7886 - 2.7887 - static int bit_bswap(lua_State *L) 2.7888 - { 2.7889 - UBits b = barg(L, 1); 2.7890 - b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24); 2.7891 - BRET(b) 2.7892 - } 2.7893 - 2.7894 - static int bit_tohex(lua_State *L) 2.7895 - { 2.7896 - UBits b = barg(L, 1); 2.7897 - SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2); 2.7898 - const char *hexdigits = "0123456789abcdef"; 2.7899 - char buf[8]; 2.7900 - int i; 2.7901 - if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } 2.7902 - if (n > 8) n = 8; 2.7903 - for (i = (int)n; --i >= 0; ) 2.7904 - { 2.7905 - buf[i] = hexdigits[b & 15]; b >>= 4; 2.7906 - } 2.7907 - lua_pushlstring(L, buf, (size_t)n); 2.7908 - return 1; 2.7909 - } 2.7910 - 2.7911 - static const struct luaL_Reg bit_funcs[] = { 2.7912 - { "tobit", bit_tobit }, 2.7913 - { "bnot", bit_bnot }, 2.7914 - { "band", bit_band }, 2.7915 - { "bor", bit_bor }, 2.7916 - { "bxor", bit_bxor }, 2.7917 - { "lshift", bit_lshift }, 2.7918 - { "rshift", bit_rshift }, 2.7919 - { "arshift", bit_arshift }, 2.7920 - { "rol", bit_rol }, 2.7921 - { "ror", bit_ror }, 2.7922 - { "bswap", bit_bswap }, 2.7923 - { "tohex", bit_tohex }, 2.7924 - { NULL, NULL } 2.7925 - }; 2.7926 +#define BIT_SH(func, fn) \ 2.7927 + static int func(lua_State * L) { \ 2.7928 + UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) } 2.7929 +BIT_SH(bit_lshift, bshl) 2.7930 +BIT_SH(bit_rshift, bshr) 2.7931 +BIT_SH(bit_arshift, bsar) 2.7932 +BIT_SH(bit_rol, brol) 2.7933 +BIT_SH(bit_ror, bror) 2.7934 + 2.7935 +static int bit_bswap(lua_State *L) 2.7936 +{ 2.7937 + UBits b = barg(L, 1); 2.7938 + b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24); 2.7939 + BRET(b) 2.7940 + } 2.7941 + 2.7942 +static int bit_tohex(lua_State *L) 2.7943 +{ 2.7944 + UBits b = barg(L, 1); 2.7945 + SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2); 2.7946 + const char *hexdigits = "0123456789abcdef"; 2.7947 + char buf[8]; 2.7948 + int i; 2.7949 + if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } 2.7950 + if (n > 8) n = 8; 2.7951 + for (i = (int)n; --i >= 0; ) 2.7952 + { 2.7953 + buf[i] = hexdigits[b & 15]; b >>= 4; 2.7954 + } 2.7955 + lua_pushlstring(L, buf, (size_t)n); 2.7956 + return 1; 2.7957 +} 2.7958 + 2.7959 +static const struct luaL_Reg bit_funcs[] = { 2.7960 + { "tobit", bit_tobit }, 2.7961 + { "bnot", bit_bnot }, 2.7962 + { "band", bit_band }, 2.7963 + { "bor", bit_bor }, 2.7964 + { "bxor", bit_bxor }, 2.7965 + { "lshift", bit_lshift }, 2.7966 + { "rshift", bit_rshift }, 2.7967 + { "arshift", bit_arshift }, 2.7968 + { "rol", bit_rol }, 2.7969 + { "ror", bit_ror }, 2.7970 + { "bswap", bit_bswap }, 2.7971 + { "tohex", bit_tohex }, 2.7972 + { NULL, NULL } 2.7973 +}; 2.7974 2.7975 /* Signed right-shifts are implementation-defined per C89/C99. 2.7976 ** But the de facto standard are arithmetic right-shifts on two's 2.7977 @@ -4374,364 +4374,364 @@ 2.7978 */ 2.7979 #define BAD_SAR (bsar(-8, 2) != (SBits) - 2) 2.7980 2.7981 - bool luabitop_validate(lua_State *L) // originally named as luaopen_bit 2.7982 - { 2.7983 - UBits b; 2.7984 - lua_pushnumber(L, (lua_Number)1437217655L); 2.7985 - b = barg(L, -1); 2.7986 - if (b != (UBits)1437217655L || BAD_SAR) /* Perform a simple self-test. */ 2.7987 - { 2.7988 - const char *msg = "compiled with incompatible luaconf.h"; 2.7989 +bool luabitop_validate(lua_State *L) // originally named as luaopen_bit 2.7990 +{ 2.7991 + UBits b; 2.7992 + lua_pushnumber(L, (lua_Number)1437217655L); 2.7993 + b = barg(L, -1); 2.7994 + if (b != (UBits)1437217655L || BAD_SAR) /* Perform a simple self-test. */ 2.7995 + { 2.7996 + const char *msg = "compiled with incompatible luaconf.h"; 2.7997 #ifdef LUA_NUMBER_DOUBLE 2.7998 #ifdef WIN32 2.7999 - if (b == (UBits)1610612736L) 2.8000 - msg = "use D3DCREATE_FPU_PRESERVE with DirectX"; 2.8001 + if (b == (UBits)1610612736L) 2.8002 + msg = "use D3DCREATE_FPU_PRESERVE with DirectX"; 2.8003 #endif 2.8004 - if (b == (UBits)1127743488L) 2.8005 - msg = "not compiled with SWAPPED_DOUBLE"; 2.8006 + if (b == (UBits)1127743488L) 2.8007 + msg = "not compiled with SWAPPED_DOUBLE"; 2.8008 #endif 2.8009 - if (BAD_SAR) 2.8010 - msg = "arithmetic right-shift broken"; 2.8011 - luaL_error(L, "bit library self-test failed (%s)", msg); 2.8012 - return false; 2.8013 - } 2.8014 - return true; 2.8015 - } 2.8016 + if (BAD_SAR) 2.8017 + msg = "arithmetic right-shift broken"; 2.8018 + luaL_error(L, "bit library self-test failed (%s)", msg); 2.8019 + return false; 2.8020 + } 2.8021 + return true; 2.8022 +} 2.8023 2.8024 // LuaBitOp ends here 2.8025 2.8026 - static int bit_bshift_emulua(lua_State *L) 2.8027 - { 2.8028 - int shift = luaL_checkinteger(L, 2); 2.8029 - if (shift < 0) 2.8030 - { 2.8031 - lua_pushinteger(L, -shift); 2.8032 - lua_replace(L, 2); 2.8033 - return bit_lshift(L); 2.8034 - } 2.8035 - else 2.8036 - return bit_rshift(L); 2.8037 - } 2.8038 - 2.8039 - static int bitbit(lua_State *L) 2.8040 - { 2.8041 - int rv = 0; 2.8042 - int numArgs = lua_gettop(L); 2.8043 - for (int i = 1; i <= numArgs; i++) 2.8044 - { 2.8045 - int where = luaL_checkinteger(L, i); 2.8046 - if (where >= 0 && where < 32) 2.8047 - rv |= (1 << where); 2.8048 - } 2.8049 - lua_settop(L, 0); 2.8050 - BRET(rv); 2.8051 - } 2.8052 +static int bit_bshift_emulua(lua_State *L) 2.8053 +{ 2.8054 + int shift = luaL_checkinteger(L, 2); 2.8055 + if (shift < 0) 2.8056 + { 2.8057 + lua_pushinteger(L, -shift); 2.8058 + lua_replace(L, 2); 2.8059 + return bit_lshift(L); 2.8060 + } 2.8061 + else 2.8062 + return bit_rshift(L); 2.8063 +} 2.8064 + 2.8065 +static int bitbit(lua_State *L) 2.8066 +{ 2.8067 + int rv = 0; 2.8068 + int numArgs = lua_gettop(L); 2.8069 + for (int i = 1; i <= numArgs; i++) 2.8070 + { 2.8071 + int where = luaL_checkinteger(L, i); 2.8072 + if (where >= 0 && where < 32) 2.8073 + rv |= (1 << where); 2.8074 + } 2.8075 + lua_settop(L, 0); 2.8076 + BRET(rv); 2.8077 +} 2.8078 2.8079 // The function called periodically to ensure Lua doesn't run amok. 2.8080 - static void VBALuaHookFunction(lua_State *L, lua_Debug *dbg) 2.8081 - { 2.8082 - if (numTries-- == 0) 2.8083 - { 2.8084 - int kill = 0; 2.8085 +static void VBALuaHookFunction(lua_State *L, lua_Debug *dbg) 2.8086 +{ 2.8087 + if (numTries-- == 0) 2.8088 + { 2.8089 + int kill = 0; 2.8090 2.8091 #if (defined(WIN32) && !defined(SDL)) 2.8092 - // Uh oh 2.8093 - theApp.winCheckFullscreen(); 2.8094 - systemSoundClearBuffer(); 2.8095 - int ret = AfxGetApp()->m_pMainWnd->MessageBox( 2.8096 - "The Lua script running has been running a long time. It may have gone crazy. Kill it?\n\n(No = don't check anymore either)", 2.8097 - "Lua Script Gone Nuts?", 2.8098 - MB_YESNO); 2.8099 - 2.8100 - if (ret == IDYES) 2.8101 - { 2.8102 - kill = 1; 2.8103 - } 2.8104 + // Uh oh 2.8105 + theApp.winCheckFullscreen(); 2.8106 + systemSoundClearBuffer(); 2.8107 + int ret = AfxGetApp()->m_pMainWnd->MessageBox( 2.8108 + "The Lua script running has been running a long time. It may have gone crazy. Kill it?\n\n(No = don't check anymore either)", 2.8109 + "Lua Script Gone Nuts?", 2.8110 + MB_YESNO); 2.8111 + 2.8112 + if (ret == IDYES) 2.8113 + { 2.8114 + kill = 1; 2.8115 + } 2.8116 2.8117 #else 2.8118 - fprintf( 2.8119 - stderr, 2.8120 - "The Lua script running has been running a long time.\nIt may have gone crazy. Kill it? (I won't ask again if you say No)\n"); 2.8121 - 2.8122 - char buffer[64]; 2.8123 - while (true) 2.8124 - { 2.8125 - fprintf(stderr, "(y/n): "); 2.8126 - fgets(buffer, sizeof(buffer), stdin); 2.8127 - if (buffer[0] == 'y' || buffer[0] == 'Y') 2.8128 - { 2.8129 - kill = 1; 2.8130 - break; 2.8131 - } 2.8132 - 2.8133 - if (buffer[0] == 'n' || buffer[0] == 'N') 2.8134 - break; 2.8135 - } 2.8136 + fprintf( 2.8137 + stderr, 2.8138 + "The Lua script running has been running a long time.\nIt may have gone crazy. Kill it? (I won't ask again if you say No)\n"); 2.8139 + 2.8140 + char buffer[64]; 2.8141 + while (true) 2.8142 + { 2.8143 + fprintf(stderr, "(y/n): "); 2.8144 + fgets(buffer, sizeof(buffer), stdin); 2.8145 + if (buffer[0] == 'y' || buffer[0] == 'Y') 2.8146 + { 2.8147 + kill = 1; 2.8148 + break; 2.8149 + } 2.8150 + 2.8151 + if (buffer[0] == 'n' || buffer[0] == 'N') 2.8152 + break; 2.8153 + } 2.8154 #endif 2.8155 - if (kill) 2.8156 - { 2.8157 - luaL_error(L, "Killed by user request."); 2.8158 - VBALuaOnStop(); 2.8159 - } 2.8160 - 2.8161 - // else, kill the debug hook. 2.8162 - lua_sethook(L, NULL, 0, 0); 2.8163 - } 2.8164 - } 2.8165 - 2.8166 - static const struct luaL_reg vbalib[] = { 2.8167 - // {"speedmode", vba_speedmode}, // TODO: NYI 2.8168 - { "frameadvance", vba_frameadvance }, 2.8169 - { "pause", vba_pause }, 2.8170 - { "framecount", vba_framecount }, 2.8171 - { "lagcount", vba_getlagcount }, 2.8172 - { "lagged", vba_lagged }, 2.8173 - { "emulating", vba_emulating }, 2.8174 - { "registerbefore", vba_registerbefore }, 2.8175 - { "registerafter", vba_registerafter }, 2.8176 - { "registerexit", vba_registerexit }, 2.8177 - { "message", vba_message }, 2.8178 - { "print", print }, // sure, why not 2.8179 - { NULL, NULL } 2.8180 - }; 2.8181 - 2.8182 - static const struct luaL_reg memorylib[] = { 2.8183 - { "readbyte", memory_readbyte }, 2.8184 - { "readbytesigned", memory_readbytesigned }, 2.8185 - { "readword", memory_readword }, 2.8186 - { "readwordsigned", memory_readwordsigned }, 2.8187 - { "readdword", memory_readdword }, 2.8188 - { "readdwordsigned", memory_readdwordsigned }, 2.8189 - { "readbyterange", memory_readbyterange }, 2.8190 - { "writebyte", memory_writebyte }, 2.8191 - { "writeword", memory_writeword }, 2.8192 - { "writedword", memory_writedword }, 2.8193 - { "getregister", memory_getregister }, 2.8194 - { "setregister", memory_setregister }, 2.8195 - { "gbromreadbyte", memory_gbromreadbyte }, 2.8196 - { "gbromreadbytesigned", memory_gbromreadbytesigned }, 2.8197 - { "gbromreadword", memory_gbromreadword }, 2.8198 - { "gbromreadwordsigned", memory_gbromreadwordsigned }, 2.8199 - { "gbromreaddword", memory_gbromreaddword }, 2.8200 - { "gbromreaddwordsigned", memory_gbromreaddwordsigned }, 2.8201 - { "gbromreadbyterange", memory_gbromreadbyterange }, 2.8202 - 2.8203 - // alternate naming scheme for word and double-word and unsigned 2.8204 - { "readbyteunsigned", memory_readbyte }, 2.8205 - { "readwordunsigned", memory_readword }, 2.8206 - { "readdwordunsigned", memory_readdword }, 2.8207 - { "readshort", memory_readword }, 2.8208 - { "readshortunsigned", memory_readword }, 2.8209 - { "readshortsigned", memory_readwordsigned }, 2.8210 - { "readlong", memory_readdword }, 2.8211 - { "readlongunsigned", memory_readdword }, 2.8212 - { "readlongsigned", memory_readdwordsigned }, 2.8213 - { "writeshort", memory_writeword }, 2.8214 - { "writelong", memory_writedword }, 2.8215 - { "gbromreadbyteunsigned", memory_gbromreadbyte }, 2.8216 - { "gbromreadwordunsigned", memory_gbromreadword }, 2.8217 - { "gbromreaddwordunsigned", memory_gbromreaddword }, 2.8218 - { "gbromreadshort", memory_gbromreadword }, 2.8219 - { "gbromreadshortunsigned", memory_gbromreadword }, 2.8220 - { "gbromreadshortsigned", memory_gbromreadwordsigned }, 2.8221 - { "gbromreadlong", memory_gbromreaddword }, 2.8222 - { "gbromreadlongunsigned", memory_gbromreaddword }, 2.8223 - { "gbromreadlongsigned", memory_gbromreaddwordsigned }, 2.8224 - 2.8225 - // memory hooks 2.8226 - { "registerwrite", memory_registerwrite }, 2.8227 - //{"registerread", memory_registerread}, 2.8228 - { "registerexec", memory_registerexec }, 2.8229 - // alternate names 2.8230 - { "register", memory_registerwrite }, 2.8231 - { "registerrun", memory_registerexec }, 2.8232 - { "registerexecute", memory_registerexec }, 2.8233 - 2.8234 - { NULL, NULL } 2.8235 - }; 2.8236 - 2.8237 - static const struct luaL_reg joypadlib[] = { 2.8238 - { "get", joypad_get }, 2.8239 - { "getdown", joypad_getdown }, 2.8240 - { "getup", joypad_getup }, 2.8241 - { "set", joypad_set }, 2.8242 - 2.8243 - // alternative names 2.8244 - { "read", joypad_get }, 2.8245 - { "write", joypad_set }, 2.8246 - { "readdown", joypad_getdown }, 2.8247 - { "readup", joypad_getup }, 2.8248 - { NULL, NULL } 2.8249 - }; 2.8250 - 2.8251 - static const struct luaL_reg savestatelib[] = { 2.8252 - { "create", savestate_create }, 2.8253 - { "save", savestate_save }, 2.8254 - { "load", savestate_load }, 2.8255 - 2.8256 - { NULL, NULL } 2.8257 - }; 2.8258 - 2.8259 - static const struct luaL_reg movielib[] = { 2.8260 - { "active", movie_isactive }, 2.8261 - { "recording", movie_isrecording }, 2.8262 - { "playing", movie_isplaying }, 2.8263 - { "mode", movie_getmode }, 2.8264 - 2.8265 - { "length", movie_getlength }, 2.8266 - { "author", movie_getauthor }, 2.8267 - { "name", movie_getfilename }, 2.8268 - { "rerecordcount", movie_rerecordcount }, 2.8269 - { "setrerecordcount", movie_setrerecordcount }, 2.8270 - 2.8271 - { "rerecordcounting", movie_rerecordcounting }, 2.8272 - { "framecount", vba_framecount }, // for those familiar with 2.8273 - // other emulators that have 2.8274 - // movie.framecount() 2.8275 - // instead of 2.8276 - // emulatorname.framecount() 2.8277 - 2.8278 - { "stop", movie_stop }, 2.8279 - 2.8280 - // alternative names 2.8281 - { "close", movie_stop }, 2.8282 - { "getauthor", movie_getauthor }, 2.8283 - { "getname", movie_getfilename }, 2.8284 - { NULL, NULL } 2.8285 - }; 2.8286 - 2.8287 - static const struct luaL_reg guilib[] = { 2.8288 - { "register", gui_register }, 2.8289 - { "text", gui_text }, 2.8290 - { "box", gui_drawbox }, 2.8291 - { "line", gui_drawline }, 2.8292 - { "pixel", gui_drawpixel }, 2.8293 - { "opacity", gui_setopacity }, 2.8294 - { "transparency", gui_transparency }, 2.8295 - { "popup", gui_popup }, 2.8296 - { "parsecolor", gui_parsecolor }, 2.8297 - { "gdscreenshot", gui_gdscreenshot }, 2.8298 - { "gdoverlay", gui_gdoverlay }, 2.8299 - { "getpixel", gui_getpixel }, 2.8300 - 2.8301 - // alternative names 2.8302 - { "drawtext", gui_text }, 2.8303 - { "drawbox", gui_drawbox }, 2.8304 - { "drawline", gui_drawline }, 2.8305 - { "drawpixel", gui_drawpixel }, 2.8306 - { "setpixel", gui_drawpixel }, 2.8307 - { "writepixel", gui_drawpixel }, 2.8308 - { "rect", gui_drawbox }, 2.8309 - { "drawrect", gui_drawbox }, 2.8310 - { "drawimage", gui_gdoverlay }, 2.8311 - { "image", gui_gdoverlay }, 2.8312 - { "readpixel", gui_getpixel }, 2.8313 - { NULL, NULL } 2.8314 - }; 2.8315 - 2.8316 - static const struct luaL_reg inputlib[] = { 2.8317 - { "get", input_getcurrentinputstatus }, 2.8318 - 2.8319 - // alternative names 2.8320 - { "read", input_getcurrentinputstatus }, 2.8321 - { NULL, NULL } 2.8322 - }; 2.8323 - 2.8324 - static const struct luaL_reg soundlib[] = { 2.8325 - { "get", sound_get }, 2.8326 - 2.8327 - // alternative names 2.8328 - { NULL, NULL } 2.8329 - }; 2.8330 + if (kill) 2.8331 + { 2.8332 + luaL_error(L, "Killed by user request."); 2.8333 + VBALuaOnStop(); 2.8334 + } 2.8335 + 2.8336 + // else, kill the debug hook. 2.8337 + lua_sethook(L, NULL, 0, 0); 2.8338 + } 2.8339 +} 2.8340 + 2.8341 +static const struct luaL_reg vbalib[] = { 2.8342 + // {"speedmode", vba_speedmode}, // TODO: NYI 2.8343 + { "frameadvance", vba_frameadvance }, 2.8344 + { "pause", vba_pause }, 2.8345 + { "framecount", vba_framecount }, 2.8346 + { "lagcount", vba_getlagcount }, 2.8347 + { "lagged", vba_lagged }, 2.8348 + { "emulating", vba_emulating }, 2.8349 + { "registerbefore", vba_registerbefore }, 2.8350 + { "registerafter", vba_registerafter }, 2.8351 + { "registerexit", vba_registerexit }, 2.8352 + { "message", vba_message }, 2.8353 + { "print", print }, // sure, why not 2.8354 + { NULL, NULL } 2.8355 +}; 2.8356 + 2.8357 +static const struct luaL_reg memorylib[] = { 2.8358 + { "readbyte", memory_readbyte }, 2.8359 + { "readbytesigned", memory_readbytesigned }, 2.8360 + { "readword", memory_readword }, 2.8361 + { "readwordsigned", memory_readwordsigned }, 2.8362 + { "readdword", memory_readdword }, 2.8363 + { "readdwordsigned", memory_readdwordsigned }, 2.8364 + { "readbyterange", memory_readbyterange }, 2.8365 + { "writebyte", memory_writebyte }, 2.8366 + { "writeword", memory_writeword }, 2.8367 + { "writedword", memory_writedword }, 2.8368 + { "getregister", memory_getregister }, 2.8369 + { "setregister", memory_setregister }, 2.8370 + { "gbromreadbyte", memory_gbromreadbyte }, 2.8371 + { "gbromreadbytesigned", memory_gbromreadbytesigned }, 2.8372 + { "gbromreadword", memory_gbromreadword }, 2.8373 + { "gbromreadwordsigned", memory_gbromreadwordsigned }, 2.8374 + { "gbromreaddword", memory_gbromreaddword }, 2.8375 + { "gbromreaddwordsigned", memory_gbromreaddwordsigned }, 2.8376 + { "gbromreadbyterange", memory_gbromreadbyterange }, 2.8377 + 2.8378 + // alternate naming scheme for word and double-word and unsigned 2.8379 + { "readbyteunsigned", memory_readbyte }, 2.8380 + { "readwordunsigned", memory_readword }, 2.8381 + { "readdwordunsigned", memory_readdword }, 2.8382 + { "readshort", memory_readword }, 2.8383 + { "readshortunsigned", memory_readword }, 2.8384 + { "readshortsigned", memory_readwordsigned }, 2.8385 + { "readlong", memory_readdword }, 2.8386 + { "readlongunsigned", memory_readdword }, 2.8387 + { "readlongsigned", memory_readdwordsigned }, 2.8388 + { "writeshort", memory_writeword }, 2.8389 + { "writelong", memory_writedword }, 2.8390 + { "gbromreadbyteunsigned", memory_gbromreadbyte }, 2.8391 + { "gbromreadwordunsigned", memory_gbromreadword }, 2.8392 + { "gbromreaddwordunsigned", memory_gbromreaddword }, 2.8393 + { "gbromreadshort", memory_gbromreadword }, 2.8394 + { "gbromreadshortunsigned", memory_gbromreadword }, 2.8395 + { "gbromreadshortsigned", memory_gbromreadwordsigned }, 2.8396 + { "gbromreadlong", memory_gbromreaddword }, 2.8397 + { "gbromreadlongunsigned", memory_gbromreaddword }, 2.8398 + { "gbromreadlongsigned", memory_gbromreaddwordsigned }, 2.8399 + 2.8400 + // memory hooks 2.8401 + { "registerwrite", memory_registerwrite }, 2.8402 + //{"registerread", memory_registerread}, 2.8403 + { "registerexec", memory_registerexec }, 2.8404 + // alternate names 2.8405 + { "register", memory_registerwrite }, 2.8406 + { "registerrun", memory_registerexec }, 2.8407 + { "registerexecute", memory_registerexec }, 2.8408 + 2.8409 + { NULL, NULL } 2.8410 +}; 2.8411 + 2.8412 +static const struct luaL_reg joypadlib[] = { 2.8413 + { "get", joypad_get }, 2.8414 + { "getdown", joypad_getdown }, 2.8415 + { "getup", joypad_getup }, 2.8416 + { "set", joypad_set }, 2.8417 + 2.8418 + // alternative names 2.8419 + { "read", joypad_get }, 2.8420 + { "write", joypad_set }, 2.8421 + { "readdown", joypad_getdown }, 2.8422 + { "readup", joypad_getup }, 2.8423 + { NULL, NULL } 2.8424 +}; 2.8425 + 2.8426 +static const struct luaL_reg savestatelib[] = { 2.8427 + { "create", savestate_create }, 2.8428 + { "save", savestate_save }, 2.8429 + { "load", savestate_load }, 2.8430 + 2.8431 + { NULL, NULL } 2.8432 +}; 2.8433 + 2.8434 +static const struct luaL_reg movielib[] = { 2.8435 + { "active", movie_isactive }, 2.8436 + { "recording", movie_isrecording }, 2.8437 + { "playing", movie_isplaying }, 2.8438 + { "mode", movie_getmode }, 2.8439 + 2.8440 + { "length", movie_getlength }, 2.8441 + { "author", movie_getauthor }, 2.8442 + { "name", movie_getfilename }, 2.8443 + { "rerecordcount", movie_rerecordcount }, 2.8444 + { "setrerecordcount", movie_setrerecordcount }, 2.8445 + 2.8446 + { "rerecordcounting", movie_rerecordcounting }, 2.8447 + { "framecount", vba_framecount }, // for those familiar with 2.8448 + // other emulators that have 2.8449 + // movie.framecount() 2.8450 + // instead of 2.8451 + // emulatorname.framecount() 2.8452 + 2.8453 + { "stop", movie_stop }, 2.8454 + 2.8455 + // alternative names 2.8456 + { "close", movie_stop }, 2.8457 + { "getauthor", movie_getauthor }, 2.8458 + { "getname", movie_getfilename }, 2.8459 + { NULL, NULL } 2.8460 +}; 2.8461 + 2.8462 +static const struct luaL_reg guilib[] = { 2.8463 + { "register", gui_register }, 2.8464 + { "text", gui_text }, 2.8465 + { "box", gui_drawbox }, 2.8466 + { "line", gui_drawline }, 2.8467 + { "pixel", gui_drawpixel }, 2.8468 + { "opacity", gui_setopacity }, 2.8469 + { "transparency", gui_transparency }, 2.8470 + { "popup", gui_popup }, 2.8471 + { "parsecolor", gui_parsecolor }, 2.8472 + { "gdscreenshot", gui_gdscreenshot }, 2.8473 + { "gdoverlay", gui_gdoverlay }, 2.8474 + { "getpixel", gui_getpixel }, 2.8475 + 2.8476 + // alternative names 2.8477 + { "drawtext", gui_text }, 2.8478 + { "drawbox", gui_drawbox }, 2.8479 + { "drawline", gui_drawline }, 2.8480 + { "drawpixel", gui_drawpixel }, 2.8481 + { "setpixel", gui_drawpixel }, 2.8482 + { "writepixel", gui_drawpixel }, 2.8483 + { "rect", gui_drawbox }, 2.8484 + { "drawrect", gui_drawbox }, 2.8485 + { "drawimage", gui_gdoverlay }, 2.8486 + { "image", gui_gdoverlay }, 2.8487 + { "readpixel", gui_getpixel }, 2.8488 + { NULL, NULL } 2.8489 +}; 2.8490 + 2.8491 +static const struct luaL_reg inputlib[] = { 2.8492 + { "get", input_getcurrentinputstatus }, 2.8493 + 2.8494 + // alternative names 2.8495 + { "read", input_getcurrentinputstatus }, 2.8496 + { NULL, NULL } 2.8497 +}; 2.8498 + 2.8499 +static const struct luaL_reg soundlib[] = { 2.8500 + { "get", sound_get }, 2.8501 + 2.8502 + // alternative names 2.8503 + { NULL, NULL } 2.8504 +}; 2.8505 2.8506 // gocha: since vba dumps avi so badly, 2.8507 // I add avilib as a workaround for enhanced video encoding. 2.8508 - static const struct luaL_reg avilib[] = { 2.8509 - { "framecount", avi_framecount }, 2.8510 - { "pause", avi_pause }, 2.8511 - { "resume", avi_resume }, 2.8512 - { NULL, NULL } 2.8513 - }; 2.8514 - 2.8515 - void CallExitFunction(void) 2.8516 - { 2.8517 - if (!LUA) 2.8518 - return; 2.8519 - 2.8520 - lua_settop(LUA, 0); 2.8521 - lua_getfield(LUA, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEXIT]); 2.8522 - 2.8523 - int errorcode = 0; 2.8524 - if (lua_isfunction(LUA, -1)) 2.8525 - { 2.8526 - errorcode = lua_pcall(LUA, 0, 0, 0); 2.8527 - } 2.8528 - 2.8529 - if (errorcode) 2.8530 - HandleCallbackError(LUA); 2.8531 - } 2.8532 - 2.8533 - void VBALuaFrameBoundary(void) 2.8534 - { 2.8535 - // printf("Lua Frame\n"); 2.8536 - 2.8537 - lua_joypads_used = 0; 2.8538 - 2.8539 - // HA! 2.8540 - if (!LUA || !luaRunning) 2.8541 - return; 2.8542 - 2.8543 - // Our function needs calling 2.8544 - lua_settop(LUA, 0); 2.8545 - lua_getfield(LUA, LUA_REGISTRYINDEX, frameAdvanceThread); 2.8546 - 2.8547 - lua_State *thread = lua_tothread(LUA, 1); 2.8548 - 2.8549 - // Lua calling C must know that we're busy inside a frame boundary 2.8550 - frameBoundary = true; 2.8551 - frameAdvanceWaiting = false; 2.8552 - 2.8553 - numTries = 1000; 2.8554 - 2.8555 - int result = lua_resume(thread, 0); 2.8556 - 2.8557 - if (result == LUA_YIELD) 2.8558 - { 2.8559 - // Okay, we're fine with that. 2.8560 - } 2.8561 - else if (result != 0) 2.8562 - { 2.8563 - // Done execution by bad causes 2.8564 - VBALuaOnStop(); 2.8565 - lua_pushnil(LUA); 2.8566 - lua_setfield(LUA, LUA_REGISTRYINDEX, frameAdvanceThread); 2.8567 - lua_pushnil(LUA); 2.8568 - lua_setfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 2.8569 - 2.8570 - // Error? 2.8571 -//#if (defined(WIN32) && !defined(SDL)) 2.8572 -// info_print(info_uid, lua_tostring(thread, -1)); //Clear_Sound_Buffer(); 2.8573 -// AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(thread, -1), "Lua run error", MB_OK | MB_ICONSTOP); 2.8574 -//#else 2.8575 -// fprintf(stderr, "Lua thread bombed out: %s\n", lua_tostring(thread, -1)); 2.8576 -//#endif 2.8577 - printerror(thread, -1); 2.8578 - } 2.8579 - else 2.8580 - { 2.8581 - VBALuaOnStop(); 2.8582 - printf("Script died of natural causes.\n"); 2.8583 - } 2.8584 - 2.8585 - // Past here, VBA actually runs, so any Lua code is called mid-frame. We must 2.8586 - // not do anything too stupid, so let ourselves know. 2.8587 - frameBoundary = false; 2.8588 - 2.8589 - if (!frameAdvanceWaiting) 2.8590 - { 2.8591 - VBALuaOnStop(); 2.8592 - } 2.8593 - } 2.8594 +static const struct luaL_reg avilib[] = { 2.8595 + { "framecount", avi_framecount }, 2.8596 + { "pause", avi_pause }, 2.8597 + { "resume", avi_resume }, 2.8598 + { NULL, NULL } 2.8599 +}; 2.8600 + 2.8601 +void CallExitFunction(void) 2.8602 +{ 2.8603 + if (!LUA) 2.8604 + return; 2.8605 + 2.8606 + lua_settop(LUA, 0); 2.8607 + lua_getfield(LUA, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEXIT]); 2.8608 + 2.8609 + int errorcode = 0; 2.8610 + if (lua_isfunction(LUA, -1)) 2.8611 + { 2.8612 + errorcode = lua_pcall(LUA, 0, 0, 0); 2.8613 + } 2.8614 + 2.8615 + if (errorcode) 2.8616 + HandleCallbackError(LUA); 2.8617 +} 2.8618 + 2.8619 +void VBALuaFrameBoundary(void) 2.8620 +{ 2.8621 + // printf("Lua Frame\n"); 2.8622 + 2.8623 + lua_joypads_used = 0; 2.8624 + 2.8625 + // HA! 2.8626 + if (!LUA || !luaRunning) 2.8627 + return; 2.8628 + 2.8629 + // Our function needs calling 2.8630 + lua_settop(LUA, 0); 2.8631 + lua_getfield(LUA, LUA_REGISTRYINDEX, frameAdvanceThread); 2.8632 + 2.8633 + lua_State *thread = lua_tothread(LUA, 1); 2.8634 + 2.8635 + // Lua calling C must know that we're busy inside a frame boundary 2.8636 + frameBoundary = true; 2.8637 + frameAdvanceWaiting = false; 2.8638 + 2.8639 + numTries = 1000; 2.8640 + 2.8641 + int result = lua_resume(thread, 0); 2.8642 + 2.8643 + if (result == LUA_YIELD) 2.8644 + { 2.8645 + // Okay, we're fine with that. 2.8646 + } 2.8647 + else if (result != 0) 2.8648 + { 2.8649 + // Done execution by bad causes 2.8650 + VBALuaOnStop(); 2.8651 + lua_pushnil(LUA); 2.8652 + lua_setfield(LUA, LUA_REGISTRYINDEX, frameAdvanceThread); 2.8653 + lua_pushnil(LUA); 2.8654 + lua_setfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 2.8655 + 2.8656 + // Error? 2.8657 + //#if (defined(WIN32) && !defined(SDL)) 2.8658 + // info_print(info_uid, lua_tostring(thread, -1)); //Clear_Sound_Buffer(); 2.8659 + // AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(thread, -1), "Lua run error", MB_OK | MB_ICONSTOP); 2.8660 + //#else 2.8661 + // fprintf(stderr, "Lua thread bombed out: %s\n", lua_tostring(thread, -1)); 2.8662 + //#endif 2.8663 + printerror(thread, -1); 2.8664 + } 2.8665 + else 2.8666 + { 2.8667 + VBALuaOnStop(); 2.8668 + printf("Script died of natural causes.\n"); 2.8669 + } 2.8670 + 2.8671 + // Past here, VBA actually runs, so any Lua code is called mid-frame. We must 2.8672 + // not do anything too stupid, so let ourselves know. 2.8673 + frameBoundary = false; 2.8674 + 2.8675 + if (!frameAdvanceWaiting) 2.8676 + { 2.8677 + VBALuaOnStop(); 2.8678 + } 2.8679 +} 2.8680 2.8681 /** 2.8682 * Loads and runs the given Lua script. 2.8683 @@ -4740,165 +4740,165 @@ 2.8684 * 2.8685 * Returns true on success, false on failure. 2.8686 */ 2.8687 - int VBALoadLuaCode(const char *filename) 2.8688 - { 2.8689 - static bool sfmtInitialized = false; 2.8690 - if (!sfmtInitialized) 2.8691 - { 2.8692 - init_gen_rand((unsigned)time(NULL)); 2.8693 - sfmtInitialized = true; 2.8694 - } 2.8695 - 2.8696 - if (filename != luaScriptName) 2.8697 - { 2.8698 - if (luaScriptName) 2.8699 - free(luaScriptName); 2.8700 - luaScriptName = strdup(filename); 2.8701 - } 2.8702 - 2.8703 - //stop any lua we might already have had running 2.8704 - VBALuaStop(); 2.8705 - 2.8706 - // Set current directory from filename (for dofile) 2.8707 - char dir[_MAX_PATH]; 2.8708 - char *slash, *backslash; 2.8709 - strcpy(dir, filename); 2.8710 - slash = strrchr(dir, '/'); 2.8711 - backslash = strrchr(dir, '\\'); 2.8712 - if (!slash || (backslash && backslash < slash)) 2.8713 - slash = backslash; 2.8714 - if (slash) 2.8715 - { 2.8716 - slash[1] = '\0'; // keep slash itself for some reasons 2.8717 - chdir(dir); 2.8718 - } 2.8719 - 2.8720 - if (!LUA) 2.8721 - { 2.8722 - LUA = lua_open(); 2.8723 - luaL_openlibs(LUA); 2.8724 - 2.8725 - luaL_register(LUA, "emu", vbalib); // added for better cross-emulator compatibility 2.8726 - luaL_register(LUA, "vba", vbalib); // kept for backward compatibility 2.8727 - luaL_register(LUA, "memory", memorylib); 2.8728 - luaL_register(LUA, "joypad", joypadlib); 2.8729 - luaL_register(LUA, "savestate", savestatelib); 2.8730 - luaL_register(LUA, "movie", movielib); 2.8731 - luaL_register(LUA, "gui", guilib); 2.8732 - luaL_register(LUA, "input", inputlib); 2.8733 - luaL_register(LUA, "sound", soundlib); 2.8734 - luaL_register(LUA, "bit", bit_funcs); // LuaBitOp library 2.8735 - luaL_register(LUA, "avi", avilib); // workaround for enhanced video encoding 2.8736 - lua_settop(LUA, 0); // clean the stack, because each call to luaL_register leaves a table on top 2.8737 - 2.8738 - // register a few utility functions outside of libraries (in the global namespace) 2.8739 - lua_register(LUA, "print", print); 2.8740 - lua_register(LUA, "tostring", tostring); 2.8741 - lua_register(LUA, "addressof", addressof); 2.8742 - lua_register(LUA, "copytable", copytable); 2.8743 - 2.8744 - // old bit operation functions 2.8745 - lua_register(LUA, "AND", bit_band); 2.8746 - lua_register(LUA, "OR", bit_bor); 2.8747 - lua_register(LUA, "XOR", bit_bxor); 2.8748 - lua_register(LUA, "SHIFT", bit_bshift_emulua); 2.8749 - lua_register(LUA, "BIT", bitbit); 2.8750 - 2.8751 - luabitop_validate(LUA); 2.8752 - 2.8753 - lua_pushstring(LUA, "math"); 2.8754 - lua_gettable(LUA, LUA_GLOBALSINDEX); 2.8755 - lua_pushcfunction(LUA, sfmt_random); 2.8756 - lua_setfield(LUA, -2, "random"); 2.8757 - lua_pushcfunction(LUA, sfmt_randomseed); 2.8758 - lua_setfield(LUA, -2, "randomseed"); 2.8759 - lua_settop(LUA, 0); 2.8760 - 2.8761 - // push arrays for storing hook functions in 2.8762 - for (int i = 0; i < LUAMEMHOOK_COUNT; i++) 2.8763 - { 2.8764 - lua_newtable(LUA); 2.8765 - lua_setfield(LUA, LUA_REGISTRYINDEX, luaMemHookTypeStrings[i]); 2.8766 - } 2.8767 - } 2.8768 - 2.8769 - // We make our thread NOW because we want it at the bottom of the stack. 2.8770 - // If all goes wrong, we let the garbage collector remove it. 2.8771 - lua_State *thread = lua_newthread(LUA); 2.8772 - 2.8773 - // Load the data 2.8774 - int result = luaL_loadfile(LUA, filename); 2.8775 - 2.8776 - if (result) 2.8777 - { 2.8778 -//#if (defined(WIN32) && !defined(SDL)) 2.8779 -// info_print(info_uid, lua_tostring(LUA, -1)); //Clear_Sound_Buffer(); 2.8780 -// AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(LUA, -1), "Lua load error", MB_OK | MB_ICONSTOP); 2.8781 -//#else 2.8782 -// fprintf(stderr, "Failed to compile file: %s\n", lua_tostring(LUA, -1)); 2.8783 -//#endif 2.8784 - printerror(LUA, -1); 2.8785 - 2.8786 - // Wipe the stack. Our thread 2.8787 - lua_settop(LUA, 0); 2.8788 - return 0; // Oh shit. 2.8789 - } 2.8790 - 2.8791 - // Get our function into it 2.8792 - lua_xmove(LUA, thread, 1); 2.8793 - 2.8794 - // Save the thread to the registry. This is why I make the thread FIRST. 2.8795 - lua_setfield(LUA, LUA_REGISTRYINDEX, frameAdvanceThread); 2.8796 - 2.8797 - // Initialize settings 2.8798 - luaRunning = true; 2.8799 - skipRerecords = false; 2.8800 - numMemHooks = 0; 2.8801 - transparencyModifier = 255; // opaque 2.8802 - lua_joypads_used = 0; // not used 2.8803 - //wasPaused = systemIsPaused(); 2.8804 - //systemSetPause(false); 2.8805 - 2.8806 - // Set up our protection hook to be executed once every 10,000 bytecode instructions. 2.8807 - lua_sethook(thread, VBALuaHookFunction, LUA_MASKCOUNT, 10000); 2.8808 +int VBALoadLuaCode(const char *filename) 2.8809 +{ 2.8810 + static bool sfmtInitialized = false; 2.8811 + if (!sfmtInitialized) 2.8812 + { 2.8813 + init_gen_rand((unsigned)time(NULL)); 2.8814 + sfmtInitialized = true; 2.8815 + } 2.8816 + 2.8817 + if (filename != luaScriptName) 2.8818 + { 2.8819 + if (luaScriptName) 2.8820 + free(luaScriptName); 2.8821 + luaScriptName = strdup(filename); 2.8822 + } 2.8823 + 2.8824 + //stop any lua we might already have had running 2.8825 + VBALuaStop(); 2.8826 + 2.8827 + // Set current directory from filename (for dofile) 2.8828 + char dir[_MAX_PATH]; 2.8829 + char *slash, *backslash; 2.8830 + strcpy(dir, filename); 2.8831 + slash = strrchr(dir, '/'); 2.8832 + backslash = strrchr(dir, '\\'); 2.8833 + if (!slash || (backslash && backslash < slash)) 2.8834 + slash = backslash; 2.8835 + if (slash) 2.8836 + { 2.8837 + slash[1] = '\0'; // keep slash itself for some reasons 2.8838 + chdir(dir); 2.8839 + } 2.8840 + 2.8841 + if (!LUA) 2.8842 + { 2.8843 + LUA = lua_open(); 2.8844 + luaL_openlibs(LUA); 2.8845 + 2.8846 + luaL_register(LUA, "emu", vbalib); // added for better cross-emulator compatibility 2.8847 + luaL_register(LUA, "vba", vbalib); // kept for backward compatibility 2.8848 + luaL_register(LUA, "memory", memorylib); 2.8849 + luaL_register(LUA, "joypad", joypadlib); 2.8850 + luaL_register(LUA, "savestate", savestatelib); 2.8851 + luaL_register(LUA, "movie", movielib); 2.8852 + luaL_register(LUA, "gui", guilib); 2.8853 + luaL_register(LUA, "input", inputlib); 2.8854 + luaL_register(LUA, "sound", soundlib); 2.8855 + luaL_register(LUA, "bit", bit_funcs); // LuaBitOp library 2.8856 + luaL_register(LUA, "avi", avilib); // workaround for enhanced video encoding 2.8857 + lua_settop(LUA, 0); // clean the stack, because each call to luaL_register leaves a table on top 2.8858 + 2.8859 + // register a few utility functions outside of libraries (in the global namespace) 2.8860 + lua_register(LUA, "print", print); 2.8861 + lua_register(LUA, "tostring", tostring); 2.8862 + lua_register(LUA, "addressof", addressof); 2.8863 + lua_register(LUA, "copytable", copytable); 2.8864 + 2.8865 + // old bit operation functions 2.8866 + lua_register(LUA, "AND", bit_band); 2.8867 + lua_register(LUA, "OR", bit_bor); 2.8868 + lua_register(LUA, "XOR", bit_bxor); 2.8869 + lua_register(LUA, "SHIFT", bit_bshift_emulua); 2.8870 + lua_register(LUA, "BIT", bitbit); 2.8871 + 2.8872 + luabitop_validate(LUA); 2.8873 + 2.8874 + lua_pushstring(LUA, "math"); 2.8875 + lua_gettable(LUA, LUA_GLOBALSINDEX); 2.8876 + lua_pushcfunction(LUA, sfmt_random); 2.8877 + lua_setfield(LUA, -2, "random"); 2.8878 + lua_pushcfunction(LUA, sfmt_randomseed); 2.8879 + lua_setfield(LUA, -2, "randomseed"); 2.8880 + lua_settop(LUA, 0); 2.8881 + 2.8882 + // push arrays for storing hook functions in 2.8883 + for (int i = 0; i < LUAMEMHOOK_COUNT; i++) 2.8884 + { 2.8885 + lua_newtable(LUA); 2.8886 + lua_setfield(LUA, LUA_REGISTRYINDEX, luaMemHookTypeStrings[i]); 2.8887 + } 2.8888 + } 2.8889 + 2.8890 + // We make our thread NOW because we want it at the bottom of the stack. 2.8891 + // If all goes wrong, we let the garbage collector remove it. 2.8892 + lua_State *thread = lua_newthread(LUA); 2.8893 + 2.8894 + // Load the data 2.8895 + int result = luaL_loadfile(LUA, filename); 2.8896 + 2.8897 + if (result) 2.8898 + { 2.8899 + //#if (defined(WIN32) && !defined(SDL)) 2.8900 + // info_print(info_uid, lua_tostring(LUA, -1)); //Clear_Sound_Buffer(); 2.8901 + // AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(LUA, -1), "Lua load error", MB_OK | MB_ICONSTOP); 2.8902 + //#else 2.8903 + // fprintf(stderr, "Failed to compile file: %s\n", lua_tostring(LUA, -1)); 2.8904 + //#endif 2.8905 + printerror(LUA, -1); 2.8906 + 2.8907 + // Wipe the stack. Our thread 2.8908 + lua_settop(LUA, 0); 2.8909 + return 0; // Oh shit. 2.8910 + } 2.8911 + 2.8912 + // Get our function into it 2.8913 + lua_xmove(LUA, thread, 1); 2.8914 + 2.8915 + // Save the thread to the registry. This is why I make the thread FIRST. 2.8916 + lua_setfield(LUA, LUA_REGISTRYINDEX, frameAdvanceThread); 2.8917 + 2.8918 + // Initialize settings 2.8919 + luaRunning = true; 2.8920 + skipRerecords = false; 2.8921 + numMemHooks = 0; 2.8922 + transparencyModifier = 255; // opaque 2.8923 + lua_joypads_used = 0; // not used 2.8924 + //wasPaused = systemIsPaused(); 2.8925 + //systemSetPause(false); 2.8926 + 2.8927 + // Set up our protection hook to be executed once every 10,000 bytecode instructions. 2.8928 + lua_sethook(thread, VBALuaHookFunction, LUA_MASKCOUNT, 10000); 2.8929 2.8930 #ifdef WIN32 2.8931 - info_print = PrintToWindowConsole; 2.8932 - info_onstart = WinLuaOnStart; 2.8933 - info_onstop = WinLuaOnStop; 2.8934 - if (!LuaConsoleHWnd) 2.8935 - LuaConsoleHWnd = CreateDialog(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDD_LUA), 2.8936 - AfxGetMainWnd()->GetSafeHwnd(), (DLGPROC) DlgLuaScriptDialog); 2.8937 - info_uid = (int)LuaConsoleHWnd; 2.8938 + info_print = PrintToWindowConsole; 2.8939 + info_onstart = WinLuaOnStart; 2.8940 + info_onstop = WinLuaOnStop; 2.8941 + if (!LuaConsoleHWnd) 2.8942 + LuaConsoleHWnd = CreateDialog(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDD_LUA), 2.8943 + AfxGetMainWnd()->GetSafeHwnd(), (DLGPROC) DlgLuaScriptDialog); 2.8944 + info_uid = (int)LuaConsoleHWnd; 2.8945 #else 2.8946 - info_print = NULL; 2.8947 - info_onstart = NULL; 2.8948 - info_onstop = NULL; 2.8949 + info_print = NULL; 2.8950 + info_onstart = NULL; 2.8951 + info_onstop = NULL; 2.8952 #endif 2.8953 - if (info_onstart) 2.8954 - info_onstart(info_uid); 2.8955 - 2.8956 - // And run it right now. :) 2.8957 - VBALuaFrameBoundary(); 2.8958 - systemRenderFrame(); 2.8959 - 2.8960 - // We're done. 2.8961 - return 1; 2.8962 - } 2.8963 + if (info_onstart) 2.8964 + info_onstart(info_uid); 2.8965 + 2.8966 + // And run it right now. :) 2.8967 + VBALuaFrameBoundary(); 2.8968 + systemRenderFrame(); 2.8969 + 2.8970 + // We're done. 2.8971 + return 1; 2.8972 +} 2.8973 2.8974 /** 2.8975 * Equivalent to repeating the last VBALoadLuaCode() call. 2.8976 */ 2.8977 - int VBAReloadLuaCode(void) 2.8978 - { 2.8979 - if (!luaScriptName) 2.8980 - { 2.8981 - systemScreenMessage("There's no script to reload."); 2.8982 - return 0; 2.8983 - } 2.8984 - else 2.8985 - return VBALoadLuaCode(luaScriptName); 2.8986 - } 2.8987 +int VBAReloadLuaCode(void) 2.8988 +{ 2.8989 + if (!luaScriptName) 2.8990 + { 2.8991 + systemScreenMessage("There's no script to reload."); 2.8992 + return 0; 2.8993 + } 2.8994 + else 2.8995 + return VBALoadLuaCode(luaScriptName); 2.8996 +} 2.8997 2.8998 /** 2.8999 * Terminates a running Lua script by killing the whole Lua engine. 2.9000 @@ -4906,55 +4906,55 @@ 2.9001 * Always safe to call, except from within a lua call itself (duh). 2.9002 * 2.9003 */ 2.9004 - void VBALuaStop(void) 2.9005 - { 2.9006 - //already killed 2.9007 - if (!LUA) 2.9008 - return; 2.9009 - 2.9010 - //execute the user's shutdown callbacks 2.9011 - CallExitFunction(); 2.9012 - 2.9013 - /*info.*/ numMemHooks = 0; 2.9014 - for (int i = 0; i < LUAMEMHOOK_COUNT; i++) 2.9015 - CalculateMemHookRegions((LuaMemHookType)i); 2.9016 - 2.9017 - //sometimes iup uninitializes com 2.9018 - //MBG TODO - test whether this is really necessary. i dont think it is 2.9019 +void VBALuaStop(void) 2.9020 +{ 2.9021 + //already killed 2.9022 + if (!LUA) 2.9023 + return; 2.9024 + 2.9025 + //execute the user's shutdown callbacks 2.9026 + CallExitFunction(); 2.9027 + 2.9028 + /*info.*/ numMemHooks = 0; 2.9029 + for (int i = 0; i < LUAMEMHOOK_COUNT; i++) 2.9030 + CalculateMemHookRegions((LuaMemHookType)i); 2.9031 + 2.9032 + //sometimes iup uninitializes com 2.9033 + //MBG TODO - test whether this is really necessary. i dont think it is 2.9034 #if (defined(WIN32) && !defined(SDL)) 2.9035 - CoInitialize(0); 2.9036 + CoInitialize(0); 2.9037 #endif 2.9038 2.9039 - if (info_onstop) 2.9040 - info_onstop(info_uid); 2.9041 - 2.9042 - //lua_gc(LUA,LUA_GCCOLLECT,0); 2.9043 - lua_close(LUA); // this invokes our garbage collectors for us 2.9044 - LUA = NULL; 2.9045 - VBALuaOnStop(); 2.9046 - } 2.9047 + if (info_onstop) 2.9048 + info_onstop(info_uid); 2.9049 + 2.9050 + //lua_gc(LUA,LUA_GCCOLLECT,0); 2.9051 + lua_close(LUA); // this invokes our garbage collectors for us 2.9052 + LUA = NULL; 2.9053 + VBALuaOnStop(); 2.9054 +} 2.9055 2.9056 /** 2.9057 * Returns true if there is a Lua script running. 2.9058 * 2.9059 */ 2.9060 - int VBALuaRunning(void) 2.9061 - { 2.9062 - // FIXME: return false when no callback functions are registered. 2.9063 - return (int) (LUA != NULL); // should return true if callback functions are active. 2.9064 - } 2.9065 +int VBALuaRunning(void) 2.9066 +{ 2.9067 + // FIXME: return false when no callback functions are registered. 2.9068 + return (int) (LUA != NULL); // should return true if callback functions are active. 2.9069 +} 2.9070 2.9071 /** 2.9072 * Returns true if Lua would like to steal the given joypad control. 2.9073 * 2.9074 * Range is 0 through 3 2.9075 */ 2.9076 - int VBALuaUsingJoypad(int which) 2.9077 - { 2.9078 - if (which < 0 || which > 3) 2.9079 - which = systemGetDefaultJoypad(); 2.9080 - return lua_joypads_used & (1 << which); 2.9081 - } 2.9082 +int VBALuaUsingJoypad(int which) 2.9083 +{ 2.9084 + if (which < 0 || which > 3) 2.9085 + which = systemGetDefaultJoypad(); 2.9086 + return lua_joypads_used & (1 << which); 2.9087 +} 2.9088 2.9089 /** 2.9090 * Reads the buttons Lua is feeding for the given joypad, in the same 2.9091 @@ -4963,14 +4963,14 @@ 2.9092 * <del>This function must not be called more than once per frame. </del>Ideally exactly once 2.9093 * per frame (if VBALuaUsingJoypad says it's safe to do so) 2.9094 */ 2.9095 - int VBALuaReadJoypad(int which) 2.9096 - { 2.9097 - if (which < 0 || which > 3) 2.9098 - which = systemGetDefaultJoypad(); 2.9099 - 2.9100 - //lua_joypads_used &= ~(1 << which); 2.9101 - return lua_joypads[which]; 2.9102 - } 2.9103 +int VBALuaReadJoypad(int which) 2.9104 +{ 2.9105 + if (which < 0 || which > 3) 2.9106 + which = systemGetDefaultJoypad(); 2.9107 + 2.9108 + //lua_joypads_used &= ~(1 << which); 2.9109 + return lua_joypads[which]; 2.9110 +} 2.9111 2.9112 /** 2.9113 * If this function returns true, the movie code should NOT increment 2.9114 @@ -4978,125 +4978,125 @@ 2.9115 * 2.9116 * This function will not return true if a script is not running. 2.9117 */ 2.9118 - bool8 VBALuaRerecordCountSkip(void) 2.9119 - { 2.9120 - // FIXME: return true if (there are any active callback functions && skipRerecords) 2.9121 - return LUA && luaRunning && skipRerecords; 2.9122 - } 2.9123 +bool8 VBALuaRerecordCountSkip(void) 2.9124 +{ 2.9125 + // FIXME: return true if (there are any active callback functions && skipRerecords) 2.9126 + return LUA && luaRunning && skipRerecords; 2.9127 +} 2.9128 2.9129 /** 2.9130 * Given a screen with the indicated resolution, 2.9131 * draw the current GUI onto it. 2.9132 */ 2.9133 - void VBALuaGui(uint8 *screen, int ppl, int width, int height) 2.9134 - { 2.9135 - if (!LUA /* || !luaRunning*/) 2.9136 - return; 2.9137 - 2.9138 - // First, check if we're being called by anybody 2.9139 - lua_getfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 2.9140 - 2.9141 - if (lua_isfunction(LUA, -1)) 2.9142 - { 2.9143 - // We call it now 2.9144 - numTries = 1000; 2.9145 - 2.9146 - int ret = lua_pcall(LUA, 0, 0, 0); 2.9147 - if (ret != 0) 2.9148 - { 2.9149 - // This is grounds for trashing the function 2.9150 - // Note: This must be done before the messagebox pops up, 2.9151 - // otherwise the messagebox will cause a paint event which causes a weird 2.9152 - // infinite call sequence that makes Snes9x silently exit with error code 3, 2.9153 - // if a Lua GUI function crashes. (nitsuja) 2.9154 - lua_pushnil(LUA); 2.9155 - lua_setfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 2.9156 - 2.9157 -//#if (defined(WIN32) && !defined(SDL)) 2.9158 -// info_print(info_uid, lua_tostring(LUA, -1)); //AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(LUA, -1), "Lua Error 2.9159 -// in GUI function", MB_OK); 2.9160 -//#else 2.9161 -// fprintf(stderr, "Lua error in gui.register function: %s\n", lua_tostring(LUA, -1)); 2.9162 -//#endif 2.9163 - printerror(LUA, -1); 2.9164 - } 2.9165 - } 2.9166 - 2.9167 - // And wreak the stack 2.9168 - lua_settop(LUA, 0); 2.9169 - 2.9170 - if (!gui_used) 2.9171 - return; 2.9172 - 2.9173 - gui_used = false; 2.9174 - 2.9175 - int x, y; 2.9176 - 2.9177 - //int pitch = (((ppl * systemColorDepth + 7)>>3)+3)&~3; 2.9178 - int pitch = ppl * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); 2.9179 - 2.9180 - if (width > LUA_SCREEN_WIDTH) 2.9181 - width = LUA_SCREEN_WIDTH; 2.9182 - if (height > LUA_SCREEN_HEIGHT) 2.9183 - height = LUA_SCREEN_HEIGHT; 2.9184 - 2.9185 - GetColorFunc getColor; 2.9186 - SetColorFunc setColor; 2.9187 - getColorIOFunc(systemColorDepth, &getColor, &setColor); 2.9188 - 2.9189 - for (y = 0; y < height; y++) 2.9190 - { 2.9191 - uint8 *scr = &screen[y * pitch]; 2.9192 - for (x = 0; x < width; x++, scr += systemColorDepth / 8) 2.9193 - { 2.9194 - const uint8 gui_alpha = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4 + 3]; 2.9195 - if (gui_alpha == 0) 2.9196 - { 2.9197 - // do nothing 2.9198 - continue; 2.9199 - } 2.9200 - 2.9201 - const uint8 gui_red = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4 + 2]; 2.9202 - const uint8 gui_green = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4 + 1]; 2.9203 - const uint8 gui_blue = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4]; 2.9204 - int red, green, blue; 2.9205 - 2.9206 - if (gui_alpha == 255) 2.9207 - { 2.9208 - // direct copy 2.9209 - red = gui_red; 2.9210 - green = gui_green; 2.9211 - blue = gui_blue; 2.9212 - } 2.9213 - else 2.9214 - { 2.9215 - // alpha-blending 2.9216 - uint8 scr_red, scr_green, scr_blue; 2.9217 - getColor(scr, &scr_red, &scr_green, &scr_blue); 2.9218 - red = (((int)gui_red - scr_red) * gui_alpha / 255 + scr_red) & 255; 2.9219 - green = (((int)gui_green - scr_green) * gui_alpha / 255 + scr_green) & 255; 2.9220 - blue = (((int)gui_blue - scr_blue) * gui_alpha / 255 + scr_blue) & 255; 2.9221 - } 2.9222 - 2.9223 - setColor(scr, (uint8) red, (uint8) green, (uint8) blue); 2.9224 - } 2.9225 - } 2.9226 - 2.9227 - return; 2.9228 - } 2.9229 - 2.9230 - void VBALuaClearGui(void) 2.9231 - { 2.9232 - gui_used = false; 2.9233 - } 2.9234 - 2.9235 - lua_State *VBAGetLuaState() 2.9236 - { 2.9237 - return LUA; 2.9238 - } 2.9239 - 2.9240 - char *VBAGetLuaScriptName() 2.9241 - { 2.9242 - return luaScriptName; 2.9243 - } 2.9244 - 2.9245 +void VBALuaGui(uint8 *screen, int ppl, int width, int height) 2.9246 +{ 2.9247 + if (!LUA /* || !luaRunning*/) 2.9248 + return; 2.9249 + 2.9250 + // First, check if we're being called by anybody 2.9251 + lua_getfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 2.9252 + 2.9253 + if (lua_isfunction(LUA, -1)) 2.9254 + { 2.9255 + // We call it now 2.9256 + numTries = 1000; 2.9257 + 2.9258 + int ret = lua_pcall(LUA, 0, 0, 0); 2.9259 + if (ret != 0) 2.9260 + { 2.9261 + // This is grounds for trashing the function 2.9262 + // Note: This must be done before the messagebox pops up, 2.9263 + // otherwise the messagebox will cause a paint event which causes a weird 2.9264 + // infinite call sequence that makes Snes9x silently exit with error code 3, 2.9265 + // if a Lua GUI function crashes. (nitsuja) 2.9266 + lua_pushnil(LUA); 2.9267 + lua_setfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 2.9268 + 2.9269 + //#if (defined(WIN32) && !defined(SDL)) 2.9270 + // info_print(info_uid, lua_tostring(LUA, -1)); //AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(LUA, -1), "Lua Error 2.9271 + // in GUI function", MB_OK); 2.9272 + //#else 2.9273 + // fprintf(stderr, "Lua error in gui.register function: %s\n", lua_tostring(LUA, -1)); 2.9274 + //#endif 2.9275 + printerror(LUA, -1); 2.9276 + } 2.9277 + } 2.9278 + 2.9279 + // And wreak the stack 2.9280 + lua_settop(LUA, 0); 2.9281 + 2.9282 + if (!gui_used) 2.9283 + return; 2.9284 + 2.9285 + gui_used = false; 2.9286 + 2.9287 + int x, y; 2.9288 + 2.9289 + //int pitch = (((ppl * systemColorDepth + 7)>>3)+3)&~3; 2.9290 + int pitch = ppl * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); 2.9291 + 2.9292 + if (width > LUA_SCREEN_WIDTH) 2.9293 + width = LUA_SCREEN_WIDTH; 2.9294 + if (height > LUA_SCREEN_HEIGHT) 2.9295 + height = LUA_SCREEN_HEIGHT; 2.9296 + 2.9297 + GetColorFunc getColor; 2.9298 + SetColorFunc setColor; 2.9299 + getColorIOFunc(systemColorDepth, &getColor, &setColor); 2.9300 + 2.9301 + for (y = 0; y < height; y++) 2.9302 + { 2.9303 + uint8 *scr = &screen[y * pitch]; 2.9304 + for (x = 0; x < width; x++, scr += systemColorDepth / 8) 2.9305 + { 2.9306 + const uint8 gui_alpha = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4 + 3]; 2.9307 + if (gui_alpha == 0) 2.9308 + { 2.9309 + // do nothing 2.9310 + continue; 2.9311 + } 2.9312 + 2.9313 + const uint8 gui_red = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4 + 2]; 2.9314 + const uint8 gui_green = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4 + 1]; 2.9315 + const uint8 gui_blue = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4]; 2.9316 + int red, green, blue; 2.9317 + 2.9318 + if (gui_alpha == 255) 2.9319 + { 2.9320 + // direct copy 2.9321 + red = gui_red; 2.9322 + green = gui_green; 2.9323 + blue = gui_blue; 2.9324 + } 2.9325 + else 2.9326 + { 2.9327 + // alpha-blending 2.9328 + uint8 scr_red, scr_green, scr_blue; 2.9329 + getColor(scr, &scr_red, &scr_green, &scr_blue); 2.9330 + red = (((int)gui_red - scr_red) * gui_alpha / 255 + scr_red) & 255; 2.9331 + green = (((int)gui_green - scr_green) * gui_alpha / 255 + scr_green) & 255; 2.9332 + blue = (((int)gui_blue - scr_blue) * gui_alpha / 255 + scr_blue) & 255; 2.9333 + } 2.9334 + 2.9335 + setColor(scr, (uint8) red, (uint8) green, (uint8) blue); 2.9336 + } 2.9337 + } 2.9338 + 2.9339 + return; 2.9340 +} 2.9341 + 2.9342 +void VBALuaClearGui(void) 2.9343 +{ 2.9344 + gui_used = false; 2.9345 +} 2.9346 + 2.9347 +lua_State *VBAGetLuaState() 2.9348 +{ 2.9349 + return LUA; 2.9350 +} 2.9351 + 2.9352 +char *VBAGetLuaScriptName() 2.9353 +{ 2.9354 + return luaScriptName; 2.9355 +} 2.9356 +