Mercurial > vba-clojure
diff src/common/lua-engine.cpp @ 24:59790d015f25 works-incomplete
checkpoint
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sun, 04 Mar 2012 17:50:56 -0600 |
parents | bf9169ad4222 |
children |
line wrap: on
line diff
1.1 --- a/src/common/lua-engine.cpp Sun Mar 04 17:38:32 2012 -0600 1.2 +++ b/src/common/lua-engine.cpp Sun Mar 04 17:50:56 2012 -0600 1.3 @@ -15,20 +15,20 @@ 1.4 using namespace std; 1.5 1.6 #ifdef __linux 1.7 - #include <unistd.h> // for unlink 1.8 - #include <sys/types.h> 1.9 - #include <sys/wait.h> 1.10 +#include <unistd.h> // for unlink 1.11 +#include <sys/types.h> 1.12 +#include <sys/wait.h> 1.13 #endif 1.14 #if (defined(WIN32) && !defined(SDL)) 1.15 - #include <direct.h> 1.16 - #include "../win32/stdafx.h" 1.17 - #include "../win32/Input.h" 1.18 - #include "../win32/MainWnd.h" 1.19 - #include "../win32/VBA.h" 1.20 - #include "../win32/LuaOpenDialog.h" 1.21 +#include <direct.h> 1.22 +#include "../win32/stdafx.h" 1.23 +#include "../win32/Input.h" 1.24 +#include "../win32/MainWnd.h" 1.25 +#include "../win32/VBA.h" 1.26 +#include "../win32/LuaOpenDialog.h" 1.27 #else 1.28 - #define stricmp strcasecmp 1.29 - #define strnicmp strncasecmp 1.30 +#define stricmp strcasecmp 1.31 +#define strnicmp strncasecmp 1.32 #endif 1.33 1.34 #include "../Port.h" 1.35 @@ -64,7 +64,7 @@ 1.36 static int info_uid; 1.37 1.38 #ifndef countof 1.39 - #define countof(a) (sizeof(a) / sizeof(a[0])) 1.40 +#define countof(a) (sizeof(a) / sizeof(a[0])) 1.41 #endif 1.42 1.43 static lua_State *LUA; 1.44 @@ -114,37 +114,37 @@ 1.45 1.46 // Look in inputglobal.h for macros named like BUTTON_MASK_UP to determine the order. 1.47 static const char *button_mappings[] = { 1.48 - "A", "B", "select", "start", "right", "left", "up", "down", "R", "L" 1.49 + "A", "B", "select", "start", "right", "left", "up", "down", "R", "L" 1.50 }; 1.51 1.52 #ifdef _MSC_VER 1.53 - #define snprintf _snprintf 1.54 - #define vscprintf _vscprintf 1.55 +#define snprintf _snprintf 1.56 +#define vscprintf _vscprintf 1.57 #else 1.58 - #define stricmp strcasecmp 1.59 - #define strnicmp strncasecmp 1.60 - #define __forceinline __attribute__((always_inline)) 1.61 +#define stricmp strcasecmp 1.62 +#define strnicmp strncasecmp 1.63 +#define __forceinline __attribute__((always_inline)) 1.64 #endif 1.65 1.66 static const char *luaCallIDStrings[] = 1.67 -{ 1.68 - "CALL_BEFOREEMULATION", 1.69 - "CALL_AFTEREMULATION", 1.70 - "CALL_BEFOREEXIT" 1.71 -}; 1.72 + { 1.73 + "CALL_BEFOREEMULATION", 1.74 + "CALL_AFTEREMULATION", 1.75 + "CALL_BEFOREEXIT" 1.76 + }; 1.77 1.78 //make sure we have the right number of strings 1.79 CTASSERT(sizeof(luaCallIDStrings) / sizeof(*luaCallIDStrings) == LUACALL_COUNT) 1.80 1.81 static const char *luaMemHookTypeStrings [] = 1.82 { 1.83 - "MEMHOOK_WRITE", 1.84 - "MEMHOOK_READ", 1.85 - "MEMHOOK_EXEC", 1.86 - 1.87 - "MEMHOOK_WRITE_SUB", 1.88 - "MEMHOOK_READ_SUB", 1.89 - "MEMHOOK_EXEC_SUB", 1.90 + "MEMHOOK_WRITE", 1.91 + "MEMHOOK_READ", 1.92 + "MEMHOOK_EXEC", 1.93 + 1.94 + "MEMHOOK_WRITE_SUB", 1.95 + "MEMHOOK_READ_SUB", 1.96 + "MEMHOOK_EXEC_SUB", 1.97 }; 1.98 1.99 //make sure we have the right number of strings 1.100 @@ -156,88 +156,88 @@ 1.101 // GBA memory I/O functions copied from win32/MemoryViewerDlg.cpp 1.102 static inline u8 CPUReadByteQuick(u32 addr) 1.103 { 1.104 - return ::map[addr >> 24].address[addr & ::map[addr >> 24].mask]; 1.105 + return ::map[addr >> 24].address[addr & ::map[addr >> 24].mask]; 1.106 } 1.107 1.108 static inline void CPUWriteByteQuick(u32 addr, u8 b) 1.109 { 1.110 - ::map[addr >> 24].address[addr & ::map[addr >> 24].mask] = b; 1.111 + ::map[addr >> 24].address[addr & ::map[addr >> 24].mask] = b; 1.112 } 1.113 1.114 static inline u16 CPUReadHalfWordQuick(u32 addr) 1.115 { 1.116 - return *((u16 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]); 1.117 + return *((u16 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]); 1.118 } 1.119 1.120 static inline void CPUWriteHalfWordQuick(u32 addr, u16 b) 1.121 { 1.122 - *((u16 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]) = b; 1.123 + *((u16 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]) = b; 1.124 } 1.125 1.126 static inline u32 CPUReadMemoryQuick(u32 addr) 1.127 { 1.128 - return *((u32 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]); 1.129 + return *((u32 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]); 1.130 } 1.131 1.132 static inline void CPUWriteMemoryQuick(u32 addr, u32 b) 1.133 { 1.134 - *((u32 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]) = b; 1.135 + *((u32 *) &::map[addr >> 24].address[addr & ::map[addr >> 24].mask]) = b; 1.136 } 1.137 1.138 // GB 1.139 static inline u8 gbReadMemoryQuick8(u16 addr) 1.140 { 1.141 - return gbReadMemoryQuick(addr); 1.142 + return gbReadMemoryQuick(addr); 1.143 } 1.144 1.145 static inline void gbWriteMemoryQuick8(u16 addr, u8 b) 1.146 { 1.147 - gbWriteMemoryQuick(addr, b); 1.148 + gbWriteMemoryQuick(addr, b); 1.149 } 1.150 1.151 static inline u16 gbReadMemoryQuick16(u16 addr) 1.152 { 1.153 - return (gbReadMemoryQuick(addr + 1) << 8) | gbReadMemoryQuick(addr); 1.154 + return (gbReadMemoryQuick(addr + 1) << 8) | gbReadMemoryQuick(addr); 1.155 } 1.156 1.157 static inline void gbWriteMemoryQuick16(u16 addr, u16 b) 1.158 { 1.159 - gbWriteMemoryQuick(addr, b & 0xff); 1.160 - gbWriteMemoryQuick(addr + 1, (b >> 8) & 0xff); 1.161 + gbWriteMemoryQuick(addr, b & 0xff); 1.162 + gbWriteMemoryQuick(addr + 1, (b >> 8) & 0xff); 1.163 } 1.164 1.165 static inline u32 gbReadMemoryQuick32(u16 addr) 1.166 { 1.167 - return (gbReadMemoryQuick(addr + 3) << 24) | 1.168 - (gbReadMemoryQuick(addr + 2) << 16) | 1.169 - (gbReadMemoryQuick(addr + 1) << 8) | 1.170 - gbReadMemoryQuick(addr); 1.171 + return (gbReadMemoryQuick(addr + 3) << 24) | 1.172 + (gbReadMemoryQuick(addr + 2) << 16) | 1.173 + (gbReadMemoryQuick(addr + 1) << 8) | 1.174 + gbReadMemoryQuick(addr); 1.175 } 1.176 1.177 static inline void gbWriteMemoryQuick32(u16 addr, u32 b) 1.178 { 1.179 - gbWriteMemoryQuick(addr, b & 0xff); 1.180 - gbWriteMemoryQuick(addr + 1, (b >> 8) & 0xff); 1.181 - gbWriteMemoryQuick(addr + 2, (b >> 16) & 0xff); 1.182 - gbWriteMemoryQuick(addr + 1, (b >> 24) & 0xff); 1.183 + gbWriteMemoryQuick(addr, b & 0xff); 1.184 + gbWriteMemoryQuick(addr + 1, (b >> 8) & 0xff); 1.185 + gbWriteMemoryQuick(addr + 2, (b >> 16) & 0xff); 1.186 + gbWriteMemoryQuick(addr + 1, (b >> 24) & 0xff); 1.187 } 1.188 1.189 static inline u8 gbReadROMQuick8(u32 addr) 1.190 { 1.191 - return gbReadROMQuick(addr & gbRomSizeMask); 1.192 + return gbReadROMQuick(addr & gbRomSizeMask); 1.193 } 1.194 1.195 static inline u8 gbReadROMQuick16(u32 addr) 1.196 { 1.197 - return (gbReadROMQuick(addr+1 & gbRomSizeMask) << 8) | gbReadROMQuick(addr & gbRomSizeMask); 1.198 + return (gbReadROMQuick(addr+1 & gbRomSizeMask) << 8) | gbReadROMQuick(addr & gbRomSizeMask); 1.199 } 1.200 1.201 static inline u8 gbReadROMQuick32(u32 addr) 1.202 { 1.203 - return (gbReadROMQuick(addr+3 & gbRomSizeMask) << 24) | 1.204 - (gbReadROMQuick(addr+2 & gbRomSizeMask) << 16) | 1.205 - (gbReadROMQuick(addr+1 & gbRomSizeMask) << 8) | 1.206 - gbReadROMQuick(addr & gbRomSizeMask); 1.207 + return (gbReadROMQuick(addr+3 & gbRomSizeMask) << 24) | 1.208 + (gbReadROMQuick(addr+2 & gbRomSizeMask) << 16) | 1.209 + (gbReadROMQuick(addr+1 & gbRomSizeMask) << 8) | 1.210 + gbReadROMQuick(addr & gbRomSizeMask); 1.211 } 1.212 1.213 typedef void (*GetColorFunc)(const uint8 *, uint8 *, uint8 *, uint8 *); 1.214 @@ -245,81 +245,81 @@ 1.215 1.216 static void getColor16(const uint8 *s, uint8 *r, uint8 *g, uint8 *b) 1.217 { 1.218 - u16 v = *(const uint16 *)s; 1.219 - *r = ((v >> systemBlueShift) & 0x001f) << 3; 1.220 - *g = ((v >> systemGreenShift) & 0x001f) << 3; 1.221 - *b = ((v >> systemRedShift) & 0x001f) << 3; 1.222 + u16 v = *(const uint16 *)s; 1.223 + *r = ((v >> systemBlueShift) & 0x001f) << 3; 1.224 + *g = ((v >> systemGreenShift) & 0x001f) << 3; 1.225 + *b = ((v >> systemRedShift) & 0x001f) << 3; 1.226 } 1.227 1.228 static void getColor24(const uint8 *s, uint8 *r, uint8 *g, uint8 *b) 1.229 { 1.230 - if (systemRedShift > systemBlueShift) 1.231 - *b = s[0], *g = s[1], *r = s[2]; 1.232 - else 1.233 - *r = s[0], *g = s[1], *b = s[2]; 1.234 + if (systemRedShift > systemBlueShift) 1.235 + *b = s[0], *g = s[1], *r = s[2]; 1.236 + else 1.237 + *r = s[0], *g = s[1], *b = s[2]; 1.238 } 1.239 1.240 static void getColor32(const uint8 *s, uint8 *r, uint8 *g, uint8 *b) 1.241 { 1.242 - u32 v = *(const uint32 *)s; 1.243 - *b = ((v >> systemBlueShift) & 0x001f) << 3; 1.244 - *g = ((v >> systemGreenShift) & 0x001f) << 3; 1.245 - *r = ((v >> systemRedShift) & 0x001f) << 3; 1.246 + u32 v = *(const uint32 *)s; 1.247 + *b = ((v >> systemBlueShift) & 0x001f) << 3; 1.248 + *g = ((v >> systemGreenShift) & 0x001f) << 3; 1.249 + *r = ((v >> systemRedShift) & 0x001f) << 3; 1.250 } 1.251 1.252 static void setColor16(uint8 *s, uint8 r, uint8 g, uint8 b) 1.253 { 1.254 - *(uint16 *)s = ((b >> 3) & 0x01f) << 1.255 - systemBlueShift | 1.256 - ((g >> 3) & 0x01f) << 1.257 - systemGreenShift | 1.258 - ((r >> 3) & 0x01f) << 1.259 - systemRedShift; 1.260 + *(uint16 *)s = ((b >> 3) & 0x01f) << 1.261 + systemBlueShift | 1.262 + ((g >> 3) & 0x01f) << 1.263 + systemGreenShift | 1.264 + ((r >> 3) & 0x01f) << 1.265 + systemRedShift; 1.266 } 1.267 1.268 static void setColor24(uint8 *s, uint8 r, uint8 g, uint8 b) 1.269 { 1.270 - if (systemRedShift > systemBlueShift) 1.271 - s[0] = b, s[1] = g, s[2] = r; 1.272 - else 1.273 - s[0] = r, s[1] = g, s[2] = b; 1.274 + if (systemRedShift > systemBlueShift) 1.275 + s[0] = b, s[1] = g, s[2] = r; 1.276 + else 1.277 + s[0] = r, s[1] = g, s[2] = b; 1.278 } 1.279 1.280 static void setColor32(uint8 *s, uint8 r, uint8 g, uint8 b) 1.281 { 1.282 - *(uint32 *)s = ((b >> 3) & 0x01f) << 1.283 - systemBlueShift | 1.284 - ((g >> 3) & 0x01f) << 1.285 - systemGreenShift | 1.286 - ((r >> 3) & 0x01f) << 1.287 - systemRedShift; 1.288 + *(uint32 *)s = ((b >> 3) & 0x01f) << 1.289 + systemBlueShift | 1.290 + ((g >> 3) & 0x01f) << 1.291 + systemGreenShift | 1.292 + ((r >> 3) & 0x01f) << 1.293 + systemRedShift; 1.294 } 1.295 1.296 static bool getColorIOFunc(int depth, GetColorFunc *getColor, SetColorFunc *setColor) 1.297 { 1.298 - switch (depth) 1.299 - { 1.300 - case 16: 1.301 - if (getColor) 1.302 - *getColor = getColor16; 1.303 - if (setColor) 1.304 - *setColor = setColor16; 1.305 - return true; 1.306 - case 24: 1.307 - if (getColor) 1.308 - *getColor = getColor24; 1.309 - if (setColor) 1.310 - *setColor = setColor24; 1.311 - return true; 1.312 - case 32: 1.313 - if (getColor) 1.314 - *getColor = getColor32; 1.315 - if (setColor) 1.316 - *setColor = setColor32; 1.317 - return true; 1.318 - default: 1.319 - return false; 1.320 - } 1.321 + switch (depth) 1.322 + { 1.323 + case 16: 1.324 + if (getColor) 1.325 + *getColor = getColor16; 1.326 + if (setColor) 1.327 + *setColor = setColor16; 1.328 + return true; 1.329 + case 24: 1.330 + if (getColor) 1.331 + *getColor = getColor24; 1.332 + if (setColor) 1.333 + *setColor = setColor24; 1.334 + return true; 1.335 + case 32: 1.336 + if (getColor) 1.337 + *getColor = getColor32; 1.338 + if (setColor) 1.339 + *setColor = setColor32; 1.340 + return true; 1.341 + default: 1.342 + return false; 1.343 + } 1.344 } 1.345 1.346 /** 1.347 @@ -327,11 +327,11 @@ 1.348 */ 1.349 static void VBALuaOnStop(void) 1.350 { 1.351 - luaRunning = false; 1.352 - lua_joypads_used = 0; 1.353 - gui_used = false; 1.354 - //if (wasPaused) 1.355 - // systemSetPause(true); 1.356 + luaRunning = false; 1.357 + lua_joypads_used = 0; 1.358 + gui_used = false; 1.359 + //if (wasPaused) 1.360 + // systemSetPause(true); 1.361 } 1.362 1.363 /** 1.364 @@ -342,41 +342,41 @@ 1.365 */ 1.366 int VBALuaSpeed(void) 1.367 { 1.368 - if (!LUA || !luaRunning) 1.369 - return 0; 1.370 - 1.371 - //printf("%d\n", speedmode); 1.372 - switch (speedmode) 1.373 - { 1.374 - /* 1.375 - case SPEED_NORMAL: 1.376 - return 0; 1.377 - case SPEED_NOTHROTTLE: 1.378 - IPPU.RenderThisFrame = true; 1.379 - return 1; 1.380 - 1.381 - case SPEED_TURBO: 1.382 - IPPU.SkippedFrames++; 1.383 - if (IPPU.SkippedFrames >= 40) { 1.384 - IPPU.SkippedFrames = 0; 1.385 - IPPU.RenderThisFrame = true; 1.386 - } 1.387 - else 1.388 - IPPU.RenderThisFrame = false; 1.389 - return 1; 1.390 - 1.391 - // In mode 3, SkippedFrames is set to zero so that the frame 1.392 - // skipping code doesn't try anything funny. 1.393 - case SPEED_MAXIMUM: 1.394 - IPPU.SkippedFrames=0; 1.395 - IPPU.RenderThisFrame = false; 1.396 - return 1; 1.397 - */ 1.398 - case 0: // FIXME: to get rid of the warning 1.399 - default: 1.400 - assert(false); 1.401 - return 0; 1.402 + if (!LUA || !luaRunning) 1.403 + return 0; 1.404 + 1.405 + //printf("%d\n", speedmode); 1.406 + switch (speedmode) 1.407 + { 1.408 + /* 1.409 + case SPEED_NORMAL: 1.410 + return 0; 1.411 + case SPEED_NOTHROTTLE: 1.412 + IPPU.RenderThisFrame = true; 1.413 + return 1; 1.414 + 1.415 + case SPEED_TURBO: 1.416 + IPPU.SkippedFrames++; 1.417 + if (IPPU.SkippedFrames >= 40) { 1.418 + IPPU.SkippedFrames = 0; 1.419 + IPPU.RenderThisFrame = true; 1.420 } 1.421 + else 1.422 + IPPU.RenderThisFrame = false; 1.423 + return 1; 1.424 + 1.425 + // In mode 3, SkippedFrames is set to zero so that the frame 1.426 + // skipping code doesn't try anything funny. 1.427 + case SPEED_MAXIMUM: 1.428 + IPPU.SkippedFrames=0; 1.429 + IPPU.RenderThisFrame = false; 1.430 + return 1; 1.431 + */ 1.432 + case 0: // FIXME: to get rid of the warning 1.433 + default: 1.434 + assert(false); 1.435 + return 0; 1.436 + } 1.437 } 1.438 1.439 /////////////////////////// 1.440 @@ -390,29 +390,29 @@ 1.441 // maximum renders no frames 1.442 static int vba_speedmode(lua_State *L) 1.443 { 1.444 - const char *mode = luaL_checkstring(L, 1); 1.445 - 1.446 - if (strcasecmp(mode, "normal") == 0) 1.447 - { 1.448 - speedmode = SPEED_NORMAL; 1.449 - } 1.450 - else if (strcasecmp(mode, "nothrottle") == 0) 1.451 - { 1.452 - speedmode = SPEED_NOTHROTTLE; 1.453 - } 1.454 - else if (strcasecmp(mode, "turbo") == 0) 1.455 - { 1.456 - speedmode = SPEED_TURBO; 1.457 - } 1.458 - else if (strcasecmp(mode, "maximum") == 0) 1.459 - { 1.460 - speedmode = SPEED_MAXIMUM; 1.461 - } 1.462 - else 1.463 - luaL_error(L, "Invalid mode %s to vba.speedmode", mode); 1.464 - 1.465 - //printf("new speed mode: %d\n", speedmode); 1.466 - return 0; 1.467 + const char *mode = luaL_checkstring(L, 1); 1.468 + 1.469 + if (strcasecmp(mode, "normal") == 0) 1.470 + { 1.471 + speedmode = SPEED_NORMAL; 1.472 + } 1.473 + else if (strcasecmp(mode, "nothrottle") == 0) 1.474 + { 1.475 + speedmode = SPEED_NOTHROTTLE; 1.476 + } 1.477 + else if (strcasecmp(mode, "turbo") == 0) 1.478 + { 1.479 + speedmode = SPEED_TURBO; 1.480 + } 1.481 + else if (strcasecmp(mode, "maximum") == 0) 1.482 + { 1.483 + speedmode = SPEED_MAXIMUM; 1.484 + } 1.485 + else 1.486 + luaL_error(L, "Invalid mode %s to vba.speedmode", mode); 1.487 + 1.488 + //printf("new speed mode: %d\n", speedmode); 1.489 + return 0; 1.490 } 1.491 1.492 // vba.frameadvnace() 1.493 @@ -422,18 +422,18 @@ 1.494 // when we break out. 1.495 static int vba_frameadvance(lua_State *L) 1.496 { 1.497 - // We're going to sleep for a frame-advance. Take notes. 1.498 - if (frameAdvanceWaiting) 1.499 - return luaL_error(L, "can't call vba.frameadvance() from here"); 1.500 - 1.501 - frameAdvanceWaiting = true; 1.502 - 1.503 - // Don't do this! The user won't like us sending their emulator out of control! 1.504 - // Settings.FrameAdvance = true; 1.505 - // Now we can yield to the main 1.506 - return lua_yield(L, 0); 1.507 - 1.508 - // It's actually rather disappointing... 1.509 + // We're going to sleep for a frame-advance. Take notes. 1.510 + if (frameAdvanceWaiting) 1.511 + return luaL_error(L, "can't call vba.frameadvance() from here"); 1.512 + 1.513 + frameAdvanceWaiting = true; 1.514 + 1.515 + // Don't do this! The user won't like us sending their emulator out of control! 1.516 + // Settings.FrameAdvance = true; 1.517 + // Now we can yield to the main 1.518 + return lua_yield(L, 0); 1.519 + 1.520 + // It's actually rather disappointing... 1.521 } 1.522 1.523 // vba.pause() 1.524 @@ -444,62 +444,62 @@ 1.525 // finishes executing anwyays. In this case, the function returns immediately. 1.526 static int vba_pause(lua_State *L) 1.527 { 1.528 - systemSetPause(true); 1.529 - speedmode = SPEED_NORMAL; 1.530 - 1.531 - // Return control if we're midway through a frame. We can't pause here. 1.532 - if (frameAdvanceWaiting) 1.533 - { 1.534 - return 0; 1.535 - } 1.536 - 1.537 - // If it's on a frame boundary, we also yield. 1.538 - frameAdvanceWaiting = true; 1.539 - return lua_yield(L, 0); 1.540 + systemSetPause(true); 1.541 + speedmode = SPEED_NORMAL; 1.542 + 1.543 + // Return control if we're midway through a frame. We can't pause here. 1.544 + if (frameAdvanceWaiting) 1.545 + { 1.546 + return 0; 1.547 + } 1.548 + 1.549 + // If it's on a frame boundary, we also yield. 1.550 + frameAdvanceWaiting = true; 1.551 + return lua_yield(L, 0); 1.552 } 1.553 1.554 static int vba_registerbefore(lua_State *L) 1.555 { 1.556 - if (!lua_isnil(L, 1)) 1.557 - luaL_checktype(L, 1, LUA_TFUNCTION); 1.558 - lua_settop(L, 1); 1.559 - lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEMULATION]); 1.560 - lua_insert(L, 1); 1.561 - lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEMULATION]); 1.562 - 1.563 - //StopScriptIfFinished(luaStateToUIDMap[L]); 1.564 - return 1; 1.565 + if (!lua_isnil(L, 1)) 1.566 + luaL_checktype(L, 1, LUA_TFUNCTION); 1.567 + lua_settop(L, 1); 1.568 + lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEMULATION]); 1.569 + lua_insert(L, 1); 1.570 + lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEMULATION]); 1.571 + 1.572 + //StopScriptIfFinished(luaStateToUIDMap[L]); 1.573 + return 1; 1.574 } 1.575 1.576 static int vba_registerafter(lua_State *L) 1.577 { 1.578 - if (!lua_isnil(L, 1)) 1.579 - luaL_checktype(L, 1, LUA_TFUNCTION); 1.580 - lua_settop(L, 1); 1.581 - lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_AFTEREMULATION]); 1.582 - lua_insert(L, 1); 1.583 - lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_AFTEREMULATION]); 1.584 - 1.585 - //StopScriptIfFinished(luaStateToUIDMap[L]); 1.586 - return 1; 1.587 + if (!lua_isnil(L, 1)) 1.588 + luaL_checktype(L, 1, LUA_TFUNCTION); 1.589 + lua_settop(L, 1); 1.590 + lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_AFTEREMULATION]); 1.591 + lua_insert(L, 1); 1.592 + lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_AFTEREMULATION]); 1.593 + 1.594 + //StopScriptIfFinished(luaStateToUIDMap[L]); 1.595 + return 1; 1.596 } 1.597 1.598 static int vba_registerexit(lua_State *L) 1.599 { 1.600 - if (!lua_isnil(L, 1)) 1.601 - luaL_checktype(L, 1, LUA_TFUNCTION); 1.602 - lua_settop(L, 1); 1.603 - lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEXIT]); 1.604 - lua_insert(L, 1); 1.605 - lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEXIT]); 1.606 - 1.607 - //StopScriptIfFinished(luaStateToUIDMap[L]); 1.608 - return 1; 1.609 + if (!lua_isnil(L, 1)) 1.610 + luaL_checktype(L, 1, LUA_TFUNCTION); 1.611 + lua_settop(L, 1); 1.612 + lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEXIT]); 1.613 + lua_insert(L, 1); 1.614 + lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEXIT]); 1.615 + 1.616 + //StopScriptIfFinished(luaStateToUIDMap[L]); 1.617 + return 1; 1.618 } 1.619 1.620 static inline bool isalphaorunderscore(char c) 1.621 { 1.622 - return isalpha(c) || c == '_'; 1.623 + return isalpha(c) || c == '_'; 1.624 } 1.625 1.626 static std::vector<const void *> s_tableAddressStack; // prevents infinite recursion of a table within a table (when cycle is 1.627 @@ -512,541 +512,541 @@ 1.628 #define END ); if (_n >= 0) { ptr += _n; remaining -= _n; } else { remaining = 0; } } 1.629 static void toCStringConverter(lua_State *L, int i, char * &ptr, int &remaining) 1.630 { 1.631 - if (remaining <= 0) 1.632 - return; 1.633 - 1.634 - const char *str = ptr; // for debugging 1.635 - 1.636 - // if there is a __tostring metamethod then call it 1.637 - int usedMeta = luaL_callmeta(L, i, "__tostring"); 1.638 - if (usedMeta) 1.639 + if (remaining <= 0) 1.640 + return; 1.641 + 1.642 + const char *str = ptr; // for debugging 1.643 + 1.644 + // if there is a __tostring metamethod then call it 1.645 + int usedMeta = luaL_callmeta(L, i, "__tostring"); 1.646 + if (usedMeta) 1.647 { 1.648 - std::vector<const void *>::const_iterator foundCycleIter = std::find(s_metacallStack.begin(), s_metacallStack.end(), lua_topointer(L, i)); 1.649 - if (foundCycleIter != s_metacallStack.end()) 1.650 + std::vector<const void *>::const_iterator foundCycleIter = std::find(s_metacallStack.begin(), s_metacallStack.end(), lua_topointer(L, i)); 1.651 + if (foundCycleIter != s_metacallStack.end()) 1.652 { 1.653 - lua_pop(L, 1); 1.654 - usedMeta = false; 1.655 - } 1.656 - else 1.657 + lua_pop(L, 1); 1.658 + usedMeta = false; 1.659 + } 1.660 + else 1.661 { 1.662 - s_metacallStack.push_back(lua_topointer(L, i)); 1.663 - i = lua_gettop(L); 1.664 - } 1.665 + s_metacallStack.push_back(lua_topointer(L, i)); 1.666 + i = lua_gettop(L); 1.667 } 1.668 - 1.669 - switch (lua_type(L, i)) 1.670 + } 1.671 + 1.672 + switch (lua_type(L, i)) 1.673 { 1.674 - case LUA_TNONE: 1.675 - break; 1.676 - case LUA_TNIL: 1.677 - APPENDPRINT "nil" END break; 1.678 - case LUA_TBOOLEAN: 1.679 - APPENDPRINT lua_toboolean(L, i) ? "true" : "false" END break; 1.680 - case LUA_TSTRING : APPENDPRINT "%s", lua_tostring(L, i) END break; 1.681 - case LUA_TNUMBER: 1.682 - APPENDPRINT "%.12Lg", lua_tonumber(L, i) END break; 1.683 - case LUA_TFUNCTION: 1.684 - if ((L->base + i - 1)->value.gc->cl.c.isC) 1.685 - { 1.686 - //lua_CFunction func = lua_tocfunction(L, i); 1.687 - //std::map<lua_CFunction, const char*>::iterator iter = s_cFuncInfoMap.find(func); 1.688 - //if(iter == s_cFuncInfoMap.end()) 1.689 - goto defcase; 1.690 - //APPENDPRINT "function(%s)", iter->second END 1.691 - } 1.692 + case LUA_TNONE: 1.693 + break; 1.694 + case LUA_TNIL: 1.695 + APPENDPRINT "nil" END break; 1.696 + case LUA_TBOOLEAN: 1.697 + APPENDPRINT lua_toboolean(L, i) ? "true" : "false" END break; 1.698 + case LUA_TSTRING : APPENDPRINT "%s", lua_tostring(L, i) END break; 1.699 + case LUA_TNUMBER: 1.700 + APPENDPRINT "%.12Lg", lua_tonumber(L, i) END break; 1.701 + case LUA_TFUNCTION: 1.702 + if ((L->base + i - 1)->value.gc->cl.c.isC) 1.703 + { 1.704 + //lua_CFunction func = lua_tocfunction(L, i); 1.705 + //std::map<lua_CFunction, const char*>::iterator iter = s_cFuncInfoMap.find(func); 1.706 + //if(iter == s_cFuncInfoMap.end()) 1.707 + goto defcase; 1.708 + //APPENDPRINT "function(%s)", iter->second END 1.709 + } 1.710 + else 1.711 + { 1.712 + APPENDPRINT "function(" END 1.713 + Proto * p = (L->base + i - 1)->value.gc->cl.l.p; 1.714 + int numParams = p->numparams + (p->is_vararg ? 1 : 0); 1.715 + for (int n = 0; n < p->numparams; n++) 1.716 + { 1.717 + APPENDPRINT "%s", getstr(p->locvars[n].varname) END 1.718 + if (n != numParams - 1) 1.719 + APPENDPRINT "," END 1.720 + } 1.721 + if (p->is_vararg) 1.722 + APPENDPRINT "..." END 1.723 + APPENDPRINT ")" END 1.724 + } 1.725 + break; 1.726 + defcase: default: 1.727 + APPENDPRINT "%s:%p", luaL_typename(L, i), lua_topointer(L, i) END break; 1.728 + case LUA_TTABLE: 1.729 + { 1.730 + // first make sure there's enough stack space 1.731 + if (!lua_checkstack(L, 4)) 1.732 + { 1.733 + // note that even if lua_checkstack never returns false, 1.734 + // that doesn't mean we didn't need to call it, 1.735 + // because calling it retrieves stack space past LUA_MINSTACK 1.736 + goto defcase; 1.737 + } 1.738 + 1.739 + std::vector<const void *>::const_iterator foundCycleIter = 1.740 + std::find(s_tableAddressStack.begin(), s_tableAddressStack.end(), lua_topointer(L, i)); 1.741 + if (foundCycleIter != s_tableAddressStack.end()) 1.742 + { 1.743 + int parentNum = s_tableAddressStack.end() - foundCycleIter; 1.744 + if (parentNum > 1) 1.745 + APPENDPRINT "%s:parent^%d", luaL_typename(L, i), parentNum END 1.746 + else 1.747 + APPENDPRINT "%s:parent", luaL_typename(L, i) END 1.748 + } 1.749 + else 1.750 + { 1.751 + s_tableAddressStack.push_back(lua_topointer(L, i)); 1.752 + struct Scope { ~Scope(){ s_tableAddressStack. pop_back(); } } scope; 1.753 + 1.754 + APPENDPRINT "{" END 1.755 + 1.756 + lua_pushnil(L); // first key 1.757 + int keyIndex = lua_gettop(L); 1.758 + int valueIndex = keyIndex + 1; 1.759 + bool first = true; 1.760 + bool skipKey = true; // true if we're still in the "array part" of the table 1.761 + lua_Number arrayIndex = (lua_Number)0; 1.762 + while (lua_next(L, i)) 1.763 + { 1.764 + if (first) 1.765 + first = false; 1.766 else 1.767 - { 1.768 - APPENDPRINT "function(" END 1.769 - Proto * p = (L->base + i - 1)->value.gc->cl.l.p; 1.770 - int numParams = p->numparams + (p->is_vararg ? 1 : 0); 1.771 - for (int n = 0; n < p->numparams; n++) 1.772 - { 1.773 - APPENDPRINT "%s", getstr(p->locvars[n].varname) END 1.774 - if (n != numParams - 1) 1.775 - APPENDPRINT "," END 1.776 - } 1.777 - if (p->is_vararg) 1.778 - APPENDPRINT "..." END 1.779 - APPENDPRINT ")" END 1.780 - } 1.781 - break; 1.782 -defcase: default: 1.783 - APPENDPRINT "%s:%p", luaL_typename(L, i), lua_topointer(L, i) END break; 1.784 - case LUA_TTABLE: 1.785 - { 1.786 - // first make sure there's enough stack space 1.787 - if (!lua_checkstack(L, 4)) 1.788 - { 1.789 - // note that even if lua_checkstack never returns false, 1.790 - // that doesn't mean we didn't need to call it, 1.791 - // because calling it retrieves stack space past LUA_MINSTACK 1.792 - goto defcase; 1.793 - } 1.794 - 1.795 - std::vector<const void *>::const_iterator foundCycleIter = 1.796 - std::find(s_tableAddressStack.begin(), s_tableAddressStack.end(), lua_topointer(L, i)); 1.797 - if (foundCycleIter != s_tableAddressStack.end()) 1.798 - { 1.799 - int parentNum = s_tableAddressStack.end() - foundCycleIter; 1.800 - if (parentNum > 1) 1.801 - APPENDPRINT "%s:parent^%d", luaL_typename(L, i), parentNum END 1.802 - else 1.803 - APPENDPRINT "%s:parent", luaL_typename(L, i) END 1.804 - } 1.805 - else 1.806 - { 1.807 - s_tableAddressStack.push_back(lua_topointer(L, i)); 1.808 - struct Scope { ~Scope(){ s_tableAddressStack. pop_back(); } } scope; 1.809 - 1.810 - APPENDPRINT "{" END 1.811 - 1.812 - lua_pushnil(L); // first key 1.813 - int keyIndex = lua_gettop(L); 1.814 - int valueIndex = keyIndex + 1; 1.815 - bool first = true; 1.816 - bool skipKey = true; // true if we're still in the "array part" of the table 1.817 - lua_Number arrayIndex = (lua_Number)0; 1.818 - while (lua_next(L, i)) 1.819 - { 1.820 - if (first) 1.821 - first = false; 1.822 - else 1.823 - APPENDPRINT ", " END 1.824 - if (skipKey) 1.825 - { 1.826 - arrayIndex += (lua_Number)1; 1.827 - bool keyIsNumber = (lua_type(L, keyIndex) == LUA_TNUMBER); 1.828 - skipKey = keyIsNumber && (lua_tonumber(L, keyIndex) == arrayIndex); 1.829 - } 1.830 - if (!skipKey) 1.831 - { 1.832 - bool keyIsString = (lua_type(L, keyIndex) == LUA_TSTRING); 1.833 - bool invalidLuaIdentifier = (!keyIsString || !isalphaorunderscore(*lua_tostring(L, keyIndex))); 1.834 - if (invalidLuaIdentifier) 1.835 - if (keyIsString) 1.836 - APPENDPRINT "['" END 1.837 - else 1.838 - APPENDPRINT "[" END 1.839 - 1.840 - toCStringConverter(L, keyIndex, ptr, remaining); 1.841 - // key 1.842 - 1.843 - if (invalidLuaIdentifier) 1.844 - if (keyIsString) 1.845 - APPENDPRINT "']=" END 1.846 - else 1.847 - APPENDPRINT "]=" END 1.848 - else 1.849 - APPENDPRINT "=" END 1.850 - } 1.851 - 1.852 - bool valueIsString = (lua_type(L, valueIndex) == LUA_TSTRING); 1.853 - if (valueIsString) 1.854 - APPENDPRINT "'" END 1.855 - 1.856 - toCStringConverter(L, valueIndex, ptr, remaining); // value 1.857 - 1.858 - if (valueIsString) 1.859 - APPENDPRINT "'" END 1.860 - 1.861 - lua_pop(L, 1); 1.862 - 1.863 - if (remaining <= 0) 1.864 - { 1.865 - lua_settop(L, keyIndex - 1); // stack might not be clean yet if we're breaking 1.866 - // early 1.867 - break; 1.868 - } 1.869 - } 1.870 - APPENDPRINT "}" END 1.871 - } 1.872 - } 1.873 - break; 1.874 - } 1.875 - 1.876 - if (usedMeta) 1.877 - { 1.878 - s_metacallStack.pop_back(); 1.879 - lua_pop(L, 1); 1.880 - } 1.881 - } 1.882 - 1.883 - static const int s_tempStrMaxLen = 64 * 1024; 1.884 - static char s_tempStr [s_tempStrMaxLen]; 1.885 - 1.886 - static char *rawToCString(lua_State *L, int idx) 1.887 - { 1.888 - int a = idx > 0 ? idx : 1; 1.889 - int n = idx > 0 ? idx : lua_gettop(L); 1.890 - 1.891 - char *ptr = s_tempStr; 1.892 - *ptr = 0; 1.893 - 1.894 - int remaining = s_tempStrMaxLen; 1.895 - for (int i = a; i <= n; i++) 1.896 - { 1.897 - toCStringConverter(L, i, ptr, remaining); 1.898 - if (i != n) 1.899 - APPENDPRINT " " END 1.900 - } 1.901 - 1.902 - if (remaining < 3) 1.903 - { 1.904 - while (remaining < 6) 1.905 - remaining++, ptr--; 1.906 - APPENDPRINT "..." END 1.907 - } 1.908 - APPENDPRINT "\r\n" END 1.909 - // the trailing newline is so print() can avoid having to do wasteful things to print its newline 1.910 - // (string copying would be wasteful and calling info.print() twice can be extremely slow) 1.911 - // at the cost of functions that don't want the newline needing to trim off the last two characters 1.912 - // (which is a very fast operation and thus acceptable in this case) 1.913 - 1.914 - return s_tempStr; 1.915 - } 1.916 + APPENDPRINT ", " END 1.917 + if (skipKey) 1.918 + { 1.919 + arrayIndex += (lua_Number)1; 1.920 + bool keyIsNumber = (lua_type(L, keyIndex) == LUA_TNUMBER); 1.921 + skipKey = keyIsNumber && (lua_tonumber(L, keyIndex) == arrayIndex); 1.922 + } 1.923 + if (!skipKey) 1.924 + { 1.925 + bool keyIsString = (lua_type(L, keyIndex) == LUA_TSTRING); 1.926 + bool invalidLuaIdentifier = (!keyIsString || !isalphaorunderscore(*lua_tostring(L, keyIndex))); 1.927 + if (invalidLuaIdentifier) 1.928 + if (keyIsString) 1.929 + APPENDPRINT "['" END 1.930 + else 1.931 + APPENDPRINT "[" END 1.932 + 1.933 + toCStringConverter(L, keyIndex, ptr, remaining); 1.934 + // key 1.935 + 1.936 + if (invalidLuaIdentifier) 1.937 + if (keyIsString) 1.938 + APPENDPRINT "']=" END 1.939 + else 1.940 + APPENDPRINT "]=" END 1.941 + else 1.942 + APPENDPRINT "=" END 1.943 + } 1.944 + 1.945 + bool valueIsString = (lua_type(L, valueIndex) == LUA_TSTRING); 1.946 + if (valueIsString) 1.947 + APPENDPRINT "'" END 1.948 + 1.949 + toCStringConverter(L, valueIndex, ptr, remaining); // value 1.950 + 1.951 + if (valueIsString) 1.952 + APPENDPRINT "'" END 1.953 + 1.954 + lua_pop(L, 1); 1.955 + 1.956 + if (remaining <= 0) 1.957 + { 1.958 + lua_settop(L, keyIndex - 1); // stack might not be clean yet if we're breaking 1.959 + // early 1.960 + break; 1.961 + } 1.962 + } 1.963 + APPENDPRINT "}" END 1.964 + } 1.965 + } 1.966 + break; 1.967 + } 1.968 + 1.969 + if (usedMeta) 1.970 + { 1.971 + s_metacallStack.pop_back(); 1.972 + lua_pop(L, 1); 1.973 + } 1.974 +} 1.975 + 1.976 +static const int s_tempStrMaxLen = 64 * 1024; 1.977 +static char s_tempStr [s_tempStrMaxLen]; 1.978 + 1.979 +static char *rawToCString(lua_State *L, int idx) 1.980 +{ 1.981 + int a = idx > 0 ? idx : 1; 1.982 + int n = idx > 0 ? idx : lua_gettop(L); 1.983 + 1.984 + char *ptr = s_tempStr; 1.985 + *ptr = 0; 1.986 + 1.987 + int remaining = s_tempStrMaxLen; 1.988 + for (int i = a; i <= n; i++) 1.989 + { 1.990 + toCStringConverter(L, i, ptr, remaining); 1.991 + if (i != n) 1.992 + APPENDPRINT " " END 1.993 + } 1.994 + 1.995 + if (remaining < 3) 1.996 + { 1.997 + while (remaining < 6) 1.998 + remaining++, ptr--; 1.999 + APPENDPRINT "..." END 1.1000 + } 1.1001 + APPENDPRINT "\r\n" END 1.1002 + // the trailing newline is so print() can avoid having to do wasteful things to print its newline 1.1003 + // (string copying would be wasteful and calling info.print() twice can be extremely slow) 1.1004 + // at the cost of functions that don't want the newline needing to trim off the last two characters 1.1005 + // (which is a very fast operation and thus acceptable in this case) 1.1006 + 1.1007 + return s_tempStr; 1.1008 +} 1.1009 #undef APPENDPRINT 1.1010 #undef END 1.1011 1.1012 // replacement for luaB_tostring() that is able to show the contents of tables (and formats numbers better, and show function 1.1013 // prototypes) 1.1014 // can be called directly from lua via tostring(), assuming tostring hasn't been reassigned 1.1015 - static int tostring(lua_State *L) 1.1016 - { 1.1017 - char *str = rawToCString(L); 1.1018 - str[strlen(str) - 2] = 0; // hack: trim off the \r\n (which is there to simplify the print function's 1.1019 - // task) 1.1020 - lua_pushstring(L, str); 1.1021 - return 1; 1.1022 - } 1.1023 +static int tostring(lua_State *L) 1.1024 +{ 1.1025 + char *str = rawToCString(L); 1.1026 + str[strlen(str) - 2] = 0; // hack: trim off the \r\n (which is there to simplify the print function's 1.1027 + // task) 1.1028 + lua_pushstring(L, str); 1.1029 + return 1; 1.1030 +} 1.1031 1.1032 // like rawToCString, but will check if the global Lua function tostring() 1.1033 // has been replaced with a custom function, and call that instead if so 1.1034 - static const char *toCString(lua_State *L, int idx) 1.1035 - { 1.1036 - int a = idx > 0 ? idx : 1; 1.1037 - int n = idx > 0 ? idx : lua_gettop(L); 1.1038 - lua_getglobal(L, "tostring"); 1.1039 - lua_CFunction cf = lua_tocfunction(L, -1); 1.1040 - if (cf == tostring || lua_isnil(L, -1)) // optimization: if using our own C tostring function, we can 1.1041 - // bypass the call through Lua and all the string object 1.1042 - // allocation that would entail 1.1043 - { 1.1044 - lua_pop(L, 1); 1.1045 - return rawToCString(L, idx); 1.1046 - } 1.1047 - else // if the user overrided the tostring function, we have to actually call it and store the 1.1048 - // temporarily allocated string it returns 1.1049 - { 1.1050 - lua_pushstring(L, ""); 1.1051 - for (int i = a; i <= n; i++) 1.1052 - { 1.1053 - lua_pushvalue(L, -2); // function to be called 1.1054 - lua_pushvalue(L, i); // value to print 1.1055 - lua_call(L, 1, 1); 1.1056 - if (lua_tostring(L, -1) == NULL) 1.1057 - luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("print")); 1.1058 - lua_pushstring(L, (i < n) ? " " : "\r\n"); 1.1059 - lua_concat(L, 3); 1.1060 - } 1.1061 - const char *str = lua_tostring(L, -1); 1.1062 - strncpy(s_tempStr, str, s_tempStrMaxLen); 1.1063 - s_tempStr[s_tempStrMaxLen - 1] = 0; 1.1064 - lua_pop(L, 2); 1.1065 - return s_tempStr; 1.1066 - } 1.1067 - } 1.1068 +static const char *toCString(lua_State *L, int idx) 1.1069 +{ 1.1070 + int a = idx > 0 ? idx : 1; 1.1071 + int n = idx > 0 ? idx : lua_gettop(L); 1.1072 + lua_getglobal(L, "tostring"); 1.1073 + lua_CFunction cf = lua_tocfunction(L, -1); 1.1074 + if (cf == tostring || lua_isnil(L, -1)) // optimization: if using our own C tostring function, we can 1.1075 + // bypass the call through Lua and all the string object 1.1076 + // allocation that would entail 1.1077 + { 1.1078 + lua_pop(L, 1); 1.1079 + return rawToCString(L, idx); 1.1080 + } 1.1081 + else // if the user overrided the tostring function, we have to actually call it and store the 1.1082 + // temporarily allocated string it returns 1.1083 + { 1.1084 + lua_pushstring(L, ""); 1.1085 + for (int i = a; i <= n; i++) 1.1086 + { 1.1087 + lua_pushvalue(L, -2); // function to be called 1.1088 + lua_pushvalue(L, i); // value to print 1.1089 + lua_call(L, 1, 1); 1.1090 + if (lua_tostring(L, -1) == NULL) 1.1091 + luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("print")); 1.1092 + lua_pushstring(L, (i < n) ? " " : "\r\n"); 1.1093 + lua_concat(L, 3); 1.1094 + } 1.1095 + const char *str = lua_tostring(L, -1); 1.1096 + strncpy(s_tempStr, str, s_tempStrMaxLen); 1.1097 + s_tempStr[s_tempStrMaxLen - 1] = 0; 1.1098 + lua_pop(L, 2); 1.1099 + return s_tempStr; 1.1100 + } 1.1101 +} 1.1102 1.1103 // replacement for luaB_print() that goes to the appropriate textbox instead of stdout 1.1104 - static int print(lua_State *L) 1.1105 - { 1.1106 - const char *str = toCString(L); 1.1107 - 1.1108 - int uid = info_uid; //luaStateToUIDMap[L->l_G->mainthread]; 1.1109 - //LuaContextInfo& info = GetCurrentInfo(); 1.1110 - 1.1111 - if (info_print) 1.1112 - info_print(uid, str); 1.1113 - else 1.1114 - puts(str); 1.1115 - 1.1116 - //worry(L, 100); 1.1117 - return 0; 1.1118 - } 1.1119 - 1.1120 - static int printerror(lua_State *L, int idx) 1.1121 - { 1.1122 - lua_checkstack(L, lua_gettop(L) + 4); 1.1123 - 1.1124 - if (idx < 0) 1.1125 - idx = lua_gettop(L) + 1 + idx; 1.1126 - 1.1127 - const char *str = rawToCString(L, idx); 1.1128 - 1.1129 - int uid = info_uid; //luaStateToUIDMap[L->l_G->mainthread]; 1.1130 - //LuaContextInfo& info = GetCurrentInfo(); 1.1131 - 1.1132 - if (info_print) 1.1133 - info_print(uid, str); 1.1134 - else 1.1135 - fputs(str, stderr); 1.1136 - 1.1137 - //worry(L, 100); 1.1138 - return 0; 1.1139 - } 1.1140 +static int print(lua_State *L) 1.1141 +{ 1.1142 + const char *str = toCString(L); 1.1143 + 1.1144 + int uid = info_uid; //luaStateToUIDMap[L->l_G->mainthread]; 1.1145 + //LuaContextInfo& info = GetCurrentInfo(); 1.1146 + 1.1147 + if (info_print) 1.1148 + info_print(uid, str); 1.1149 + else 1.1150 + puts(str); 1.1151 + 1.1152 + //worry(L, 100); 1.1153 + return 0; 1.1154 +} 1.1155 + 1.1156 +static int printerror(lua_State *L, int idx) 1.1157 +{ 1.1158 + lua_checkstack(L, lua_gettop(L) + 4); 1.1159 + 1.1160 + if (idx < 0) 1.1161 + idx = lua_gettop(L) + 1 + idx; 1.1162 + 1.1163 + const char *str = rawToCString(L, idx); 1.1164 + 1.1165 + int uid = info_uid; //luaStateToUIDMap[L->l_G->mainthread]; 1.1166 + //LuaContextInfo& info = GetCurrentInfo(); 1.1167 + 1.1168 + if (info_print) 1.1169 + info_print(uid, str); 1.1170 + else 1.1171 + fputs(str, stderr); 1.1172 + 1.1173 + //worry(L, 100); 1.1174 + return 0; 1.1175 +} 1.1176 1.1177 // vba.message(string msg) 1.1178 // 1.1179 // Displays the given message on the screen. 1.1180 - static int vba_message(lua_State *L) 1.1181 - { 1.1182 - const char *msg = luaL_checkstring(L, 1); 1.1183 - systemScreenMessage(msg); 1.1184 - 1.1185 - return 0; 1.1186 - } 1.1187 +static int vba_message(lua_State *L) 1.1188 +{ 1.1189 + const char *msg = luaL_checkstring(L, 1); 1.1190 + systemScreenMessage(msg); 1.1191 + 1.1192 + return 0; 1.1193 +} 1.1194 1.1195 // provides an easy way to copy a table from Lua 1.1196 // (simple assignment only makes an alias, but sometimes an independent table is desired) 1.1197 // currently this function only performs a shallow copy, 1.1198 // but I think it should be changed to do a deep copy (possibly of configurable depth?) 1.1199 // that maintains the internal table reference structure 1.1200 - static int copytable(lua_State *L) 1.1201 - { 1.1202 - int origIndex = 1; // we only care about the first argument 1.1203 - int origType = lua_type(L, origIndex); 1.1204 - if (origType == LUA_TNIL) 1.1205 - { 1.1206 - lua_pushnil(L); 1.1207 - return 1; 1.1208 - } 1.1209 - if (origType != LUA_TTABLE) 1.1210 - { 1.1211 - luaL_typerror(L, 1, lua_typename(L, LUA_TTABLE)); 1.1212 - lua_pushnil(L); 1.1213 - return 1; 1.1214 - } 1.1215 - 1.1216 - lua_createtable(L, lua_objlen(L, 1), 0); 1.1217 - int copyIndex = lua_gettop(L); 1.1218 - 1.1219 - lua_pushnil(L); // first key 1.1220 - int keyIndex = lua_gettop(L); 1.1221 - int valueIndex = keyIndex + 1; 1.1222 - 1.1223 - while (lua_next(L, origIndex)) 1.1224 - { 1.1225 - lua_pushvalue(L, keyIndex); 1.1226 - lua_pushvalue(L, valueIndex); 1.1227 - lua_rawset(L, copyIndex); // copytable[key] = value 1.1228 - lua_pop(L, 1); 1.1229 - } 1.1230 - 1.1231 - // copy the reference to the metatable as well, if any 1.1232 - if (lua_getmetatable(L, origIndex)) 1.1233 - lua_setmetatable(L, copyIndex); 1.1234 - 1.1235 - return 1; // return the new table 1.1236 - } 1.1237 +static int copytable(lua_State *L) 1.1238 +{ 1.1239 + int origIndex = 1; // we only care about the first argument 1.1240 + int origType = lua_type(L, origIndex); 1.1241 + if (origType == LUA_TNIL) 1.1242 + { 1.1243 + lua_pushnil(L); 1.1244 + return 1; 1.1245 + } 1.1246 + if (origType != LUA_TTABLE) 1.1247 + { 1.1248 + luaL_typerror(L, 1, lua_typename(L, LUA_TTABLE)); 1.1249 + lua_pushnil(L); 1.1250 + return 1; 1.1251 + } 1.1252 + 1.1253 + lua_createtable(L, lua_objlen(L, 1), 0); 1.1254 + int copyIndex = lua_gettop(L); 1.1255 + 1.1256 + lua_pushnil(L); // first key 1.1257 + int keyIndex = lua_gettop(L); 1.1258 + int valueIndex = keyIndex + 1; 1.1259 + 1.1260 + while (lua_next(L, origIndex)) 1.1261 + { 1.1262 + lua_pushvalue(L, keyIndex); 1.1263 + lua_pushvalue(L, valueIndex); 1.1264 + lua_rawset(L, copyIndex); // copytable[key] = value 1.1265 + lua_pop(L, 1); 1.1266 + } 1.1267 + 1.1268 + // copy the reference to the metatable as well, if any 1.1269 + if (lua_getmetatable(L, origIndex)) 1.1270 + lua_setmetatable(L, copyIndex); 1.1271 + 1.1272 + return 1; // return the new table 1.1273 +} 1.1274 1.1275 // because print traditionally shows the address of tables, 1.1276 // and the print function I provide instead shows the contents of tables, 1.1277 // I also provide this function 1.1278 // (otherwise there would be no way to see a table's address, AFAICT) 1.1279 - static int addressof(lua_State *L) 1.1280 - { 1.1281 - const void *ptr = lua_topointer(L, -1); 1.1282 - lua_pushinteger(L, (lua_Integer)ptr); 1.1283 - return 1; 1.1284 - } 1.1285 - 1.1286 - struct registerPointerMap 1.1287 - { 1.1288 - const char * registerName; 1.1289 - unsigned int *pointer; 1.1290 - int dataSize; 1.1291 - }; 1.1292 - 1.1293 -#define RPM_ENTRY(name, var) \ 1.1294 - { name, (unsigned int *)&var, sizeof(var) \ 1.1295 - } \ 1.1296 - , 1.1297 - 1.1298 - extern gbRegister AF; 1.1299 - extern gbRegister BC; 1.1300 - extern gbRegister DE; 1.1301 - extern gbRegister HL; 1.1302 - extern gbRegister SP; 1.1303 - extern gbRegister PC; 1.1304 - extern u16 IFF; 1.1305 - 1.1306 - registerPointerMap regPointerMap [] = { 1.1307 - // gba registers 1.1308 - RPM_ENTRY("r0", reg[0].I) 1.1309 - RPM_ENTRY("r1", reg[1].I) 1.1310 - RPM_ENTRY("r2", reg[2].I) 1.1311 - RPM_ENTRY("r3", reg[3].I) 1.1312 - RPM_ENTRY("r4", reg[4].I) 1.1313 - RPM_ENTRY("r5", reg[5].I) 1.1314 - RPM_ENTRY("r6", reg[6].I) 1.1315 - RPM_ENTRY("r7", reg[7].I) 1.1316 - RPM_ENTRY("r8", reg[8].I) 1.1317 - RPM_ENTRY("r9", reg[9].I) 1.1318 - RPM_ENTRY("r10", reg[10].I) 1.1319 - RPM_ENTRY("r11", reg[11].I) 1.1320 - RPM_ENTRY("r12", reg[12].I) 1.1321 - RPM_ENTRY("r13", reg[13].I) 1.1322 - RPM_ENTRY("r14", reg[14].I) 1.1323 - RPM_ENTRY("r15", reg[15].I) 1.1324 - RPM_ENTRY("cpsr", reg[16].I) 1.1325 - RPM_ENTRY("spsr", reg[17].I) 1.1326 - // gb registers 1.1327 - RPM_ENTRY("a", AF.B.B1) 1.1328 - RPM_ENTRY("f", AF.B.B0) 1.1329 - RPM_ENTRY("b", BC.B.B1) 1.1330 - RPM_ENTRY("c", BC.B.B0) 1.1331 - RPM_ENTRY("d", DE.B.B1) 1.1332 - RPM_ENTRY("e", DE.B.B0) 1.1333 - RPM_ENTRY("h", HL.B.B1) 1.1334 - RPM_ENTRY("l", HL.B.B0) 1.1335 - RPM_ENTRY("af", AF.W) 1.1336 - RPM_ENTRY("bc", BC.W) 1.1337 - RPM_ENTRY("de", DE.W) 1.1338 - RPM_ENTRY("hl", HL.W) 1.1339 - RPM_ENTRY("sp", SP.W) 1.1340 - RPM_ENTRY("pc", PC.W) 1.1341 - {} 1.1342 - }; 1.1343 - 1.1344 - struct cpuToRegisterMap 1.1345 - { 1.1346 - const char *cpuName; 1.1347 - registerPointerMap *rpmap; 1.1348 - } 1.1349 - cpuToRegisterMaps [] = 1.1350 - { 1.1351 - { "", regPointerMap }, 1.1352 - }; 1.1353 +static int addressof(lua_State *L) 1.1354 +{ 1.1355 + const void *ptr = lua_topointer(L, -1); 1.1356 + lua_pushinteger(L, (lua_Integer)ptr); 1.1357 + return 1; 1.1358 +} 1.1359 + 1.1360 +struct registerPointerMap 1.1361 +{ 1.1362 + const char * registerName; 1.1363 + unsigned int *pointer; 1.1364 + int dataSize; 1.1365 +}; 1.1366 + 1.1367 +#define RPM_ENTRY(name, var) \ 1.1368 + { name, (unsigned int *)&var, sizeof(var) \ 1.1369 + } \ 1.1370 + , 1.1371 + 1.1372 +extern gbRegister AF; 1.1373 +extern gbRegister BC; 1.1374 +extern gbRegister DE; 1.1375 +extern gbRegister HL; 1.1376 +extern gbRegister SP; 1.1377 +extern gbRegister PC; 1.1378 +extern u16 IFF; 1.1379 + 1.1380 +registerPointerMap regPointerMap [] = { 1.1381 + // gba registers 1.1382 + RPM_ENTRY("r0", reg[0].I) 1.1383 + RPM_ENTRY("r1", reg[1].I) 1.1384 + RPM_ENTRY("r2", reg[2].I) 1.1385 + RPM_ENTRY("r3", reg[3].I) 1.1386 + RPM_ENTRY("r4", reg[4].I) 1.1387 + RPM_ENTRY("r5", reg[5].I) 1.1388 + RPM_ENTRY("r6", reg[6].I) 1.1389 + RPM_ENTRY("r7", reg[7].I) 1.1390 + RPM_ENTRY("r8", reg[8].I) 1.1391 + RPM_ENTRY("r9", reg[9].I) 1.1392 + RPM_ENTRY("r10", reg[10].I) 1.1393 + RPM_ENTRY("r11", reg[11].I) 1.1394 + RPM_ENTRY("r12", reg[12].I) 1.1395 + RPM_ENTRY("r13", reg[13].I) 1.1396 + RPM_ENTRY("r14", reg[14].I) 1.1397 + RPM_ENTRY("r15", reg[15].I) 1.1398 + RPM_ENTRY("cpsr", reg[16].I) 1.1399 + RPM_ENTRY("spsr", reg[17].I) 1.1400 + // gb registers 1.1401 + RPM_ENTRY("a", AF.B.B1) 1.1402 + RPM_ENTRY("f", AF.B.B0) 1.1403 + RPM_ENTRY("b", BC.B.B1) 1.1404 + RPM_ENTRY("c", BC.B.B0) 1.1405 + RPM_ENTRY("d", DE.B.B1) 1.1406 + RPM_ENTRY("e", DE.B.B0) 1.1407 + RPM_ENTRY("h", HL.B.B1) 1.1408 + RPM_ENTRY("l", HL.B.B0) 1.1409 + RPM_ENTRY("af", AF.W) 1.1410 + RPM_ENTRY("bc", BC.W) 1.1411 + RPM_ENTRY("de", DE.W) 1.1412 + RPM_ENTRY("hl", HL.W) 1.1413 + RPM_ENTRY("sp", SP.W) 1.1414 + RPM_ENTRY("pc", PC.W) 1.1415 + {} 1.1416 +}; 1.1417 + 1.1418 +struct cpuToRegisterMap 1.1419 +{ 1.1420 + const char *cpuName; 1.1421 + registerPointerMap *rpmap; 1.1422 +} 1.1423 + cpuToRegisterMaps [] = 1.1424 + { 1.1425 + { "", regPointerMap }, 1.1426 + }; 1.1427 1.1428 //DEFINE_LUA_FUNCTION(memory_getregister, "cpu_dot_registername_string") 1.1429 - static int memory_getregister(lua_State *L) 1.1430 - { 1.1431 - const char *qualifiedRegisterName = luaL_checkstring(L, 1); 1.1432 - lua_settop(L, 0); 1.1433 - for (int cpu = 0; cpu < sizeof(cpuToRegisterMaps) / sizeof(*cpuToRegisterMaps); cpu++) 1.1434 - { 1.1435 - cpuToRegisterMap ctrm = cpuToRegisterMaps[cpu]; 1.1436 - int cpuNameLen = strlen(ctrm.cpuName); 1.1437 - if (!strnicmp(qualifiedRegisterName, ctrm.cpuName, cpuNameLen)) 1.1438 - { 1.1439 - qualifiedRegisterName += cpuNameLen; 1.1440 - for (int reg = 0; ctrm.rpmap[reg].dataSize; reg++) 1.1441 - { 1.1442 - registerPointerMap rpm = ctrm.rpmap[reg]; 1.1443 - if (!stricmp(qualifiedRegisterName, rpm.registerName)) 1.1444 - { 1.1445 - switch (rpm.dataSize) 1.1446 - { 1.1447 - default: 1.1448 - case 1: 1.1449 - lua_pushinteger(L, *(unsigned char *)rpm.pointer); break; 1.1450 - case 2: 1.1451 - lua_pushinteger(L, *(unsigned short *)rpm.pointer); break; 1.1452 - case 4: 1.1453 - lua_pushinteger(L, *(unsigned long *)rpm.pointer); break; 1.1454 - } 1.1455 - return 1; 1.1456 - } 1.1457 - } 1.1458 - lua_pushnil(L); 1.1459 - return 1; 1.1460 - } 1.1461 - } 1.1462 - lua_pushnil(L); 1.1463 - return 1; 1.1464 - } 1.1465 +static int memory_getregister(lua_State *L) 1.1466 +{ 1.1467 + const char *qualifiedRegisterName = luaL_checkstring(L, 1); 1.1468 + lua_settop(L, 0); 1.1469 + for (int cpu = 0; cpu < sizeof(cpuToRegisterMaps) / sizeof(*cpuToRegisterMaps); cpu++) 1.1470 + { 1.1471 + cpuToRegisterMap ctrm = cpuToRegisterMaps[cpu]; 1.1472 + int cpuNameLen = strlen(ctrm.cpuName); 1.1473 + if (!strnicmp(qualifiedRegisterName, ctrm.cpuName, cpuNameLen)) 1.1474 + { 1.1475 + qualifiedRegisterName += cpuNameLen; 1.1476 + for (int reg = 0; ctrm.rpmap[reg].dataSize; reg++) 1.1477 + { 1.1478 + registerPointerMap rpm = ctrm.rpmap[reg]; 1.1479 + if (!stricmp(qualifiedRegisterName, rpm.registerName)) 1.1480 + { 1.1481 + switch (rpm.dataSize) 1.1482 + { 1.1483 + default: 1.1484 + case 1: 1.1485 + lua_pushinteger(L, *(unsigned char *)rpm.pointer); break; 1.1486 + case 2: 1.1487 + lua_pushinteger(L, *(unsigned short *)rpm.pointer); break; 1.1488 + case 4: 1.1489 + lua_pushinteger(L, *(unsigned long *)rpm.pointer); break; 1.1490 + } 1.1491 + return 1; 1.1492 + } 1.1493 + } 1.1494 + lua_pushnil(L); 1.1495 + return 1; 1.1496 + } 1.1497 + } 1.1498 + lua_pushnil(L); 1.1499 + return 1; 1.1500 +} 1.1501 1.1502 //DEFINE_LUA_FUNCTION(memory_setregister, "cpu_dot_registername_string,value") 1.1503 - static int memory_setregister(lua_State *L) 1.1504 - { 1.1505 - const char * qualifiedRegisterName = luaL_checkstring(L, 1); 1.1506 - unsigned long value = (unsigned long)(luaL_checkinteger(L, 2)); 1.1507 - lua_settop(L, 0); 1.1508 - for (int cpu = 0; cpu < sizeof(cpuToRegisterMaps) / sizeof(*cpuToRegisterMaps); cpu++) 1.1509 - { 1.1510 - cpuToRegisterMap ctrm = cpuToRegisterMaps[cpu]; 1.1511 - int cpuNameLen = strlen(ctrm.cpuName); 1.1512 - if (!strnicmp(qualifiedRegisterName, ctrm.cpuName, cpuNameLen)) 1.1513 - { 1.1514 - qualifiedRegisterName += cpuNameLen; 1.1515 - for (int reg = 0; ctrm.rpmap[reg].dataSize; reg++) 1.1516 - { 1.1517 - registerPointerMap rpm = ctrm.rpmap[reg]; 1.1518 - if (!stricmp(qualifiedRegisterName, rpm.registerName)) 1.1519 - { 1.1520 - switch (rpm.dataSize) 1.1521 - { 1.1522 - default: 1.1523 - case 1: 1.1524 - *(unsigned char *)rpm.pointer = (unsigned char)(value & 0xFF); break; 1.1525 - case 2: 1.1526 - *(unsigned short *)rpm.pointer = (unsigned short)(value & 0xFFFF); break; 1.1527 - case 4: 1.1528 - *(unsigned long *)rpm.pointer = value; break; 1.1529 - } 1.1530 - return 0; 1.1531 - } 1.1532 - } 1.1533 - return 0; 1.1534 - } 1.1535 - } 1.1536 - return 0; 1.1537 - } 1.1538 - 1.1539 - void HandleCallbackError(lua_State *L) 1.1540 - { 1.1541 - if (L->errfunc || L->errorJmp) 1.1542 - luaL_error(L, "%s", lua_tostring(L, -1)); 1.1543 - else 1.1544 - { 1.1545 - lua_pushnil(LUA); 1.1546 - lua_setfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 1.1547 - 1.1548 - // Error? 1.1549 -//#if (defined(WIN32) && !defined(SDL)) 1.1550 -// info_print(info_uid, lua_tostring(LUA, -1)); //Clear_Sound_Buffer(); 1.1551 -// AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(LUA, -1), "Lua run error", MB_OK | MB_ICONSTOP); 1.1552 -//#else 1.1553 -// fprintf(stderr, "Lua thread bombed out: %s\n", lua_tostring(LUA, -1)); 1.1554 -//#endif 1.1555 - printerror(LUA, -1); 1.1556 - VBALuaStop(); 1.1557 - } 1.1558 - } 1.1559 - 1.1560 - void CallRegisteredLuaFunctions(LuaCallID calltype) 1.1561 - { 1.1562 - assert((unsigned int)calltype < (unsigned int)LUACALL_COUNT); 1.1563 - 1.1564 - const char *idstring = luaCallIDStrings[calltype]; 1.1565 - 1.1566 - if (!LUA) 1.1567 - return; 1.1568 - 1.1569 - lua_settop(LUA, 0); 1.1570 - lua_getfield(LUA, LUA_REGISTRYINDEX, idstring); 1.1571 - 1.1572 - int errorcode = 0; 1.1573 - if (lua_isfunction(LUA, -1)) 1.1574 - { 1.1575 - errorcode = lua_pcall(LUA, 0, 0, 0); 1.1576 - if (errorcode) 1.1577 - HandleCallbackError(LUA); 1.1578 - } 1.1579 - else 1.1580 - { 1.1581 - lua_pop(LUA, 1); 1.1582 - } 1.1583 - } 1.1584 +static int memory_setregister(lua_State *L) 1.1585 +{ 1.1586 + const char * qualifiedRegisterName = luaL_checkstring(L, 1); 1.1587 + unsigned long value = (unsigned long)(luaL_checkinteger(L, 2)); 1.1588 + lua_settop(L, 0); 1.1589 + for (int cpu = 0; cpu < sizeof(cpuToRegisterMaps) / sizeof(*cpuToRegisterMaps); cpu++) 1.1590 + { 1.1591 + cpuToRegisterMap ctrm = cpuToRegisterMaps[cpu]; 1.1592 + int cpuNameLen = strlen(ctrm.cpuName); 1.1593 + if (!strnicmp(qualifiedRegisterName, ctrm.cpuName, cpuNameLen)) 1.1594 + { 1.1595 + qualifiedRegisterName += cpuNameLen; 1.1596 + for (int reg = 0; ctrm.rpmap[reg].dataSize; reg++) 1.1597 + { 1.1598 + registerPointerMap rpm = ctrm.rpmap[reg]; 1.1599 + if (!stricmp(qualifiedRegisterName, rpm.registerName)) 1.1600 + { 1.1601 + switch (rpm.dataSize) 1.1602 + { 1.1603 + default: 1.1604 + case 1: 1.1605 + *(unsigned char *)rpm.pointer = (unsigned char)(value & 0xFF); break; 1.1606 + case 2: 1.1607 + *(unsigned short *)rpm.pointer = (unsigned short)(value & 0xFFFF); break; 1.1608 + case 4: 1.1609 + *(unsigned long *)rpm.pointer = value; break; 1.1610 + } 1.1611 + return 0; 1.1612 + } 1.1613 + } 1.1614 + return 0; 1.1615 + } 1.1616 + } 1.1617 + return 0; 1.1618 +} 1.1619 + 1.1620 +void HandleCallbackError(lua_State *L) 1.1621 +{ 1.1622 + if (L->errfunc || L->errorJmp) 1.1623 + luaL_error(L, "%s", lua_tostring(L, -1)); 1.1624 + else 1.1625 + { 1.1626 + lua_pushnil(LUA); 1.1627 + lua_setfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 1.1628 + 1.1629 + // Error? 1.1630 + //#if (defined(WIN32) && !defined(SDL)) 1.1631 + // info_print(info_uid, lua_tostring(LUA, -1)); //Clear_Sound_Buffer(); 1.1632 + // AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(LUA, -1), "Lua run error", MB_OK | MB_ICONSTOP); 1.1633 + //#else 1.1634 + // fprintf(stderr, "Lua thread bombed out: %s\n", lua_tostring(LUA, -1)); 1.1635 + //#endif 1.1636 + printerror(LUA, -1); 1.1637 + VBALuaStop(); 1.1638 + } 1.1639 +} 1.1640 + 1.1641 +void CallRegisteredLuaFunctions(LuaCallID calltype) 1.1642 +{ 1.1643 + assert((unsigned int)calltype < (unsigned int)LUACALL_COUNT); 1.1644 + 1.1645 + const char *idstring = luaCallIDStrings[calltype]; 1.1646 + 1.1647 + if (!LUA) 1.1648 + return; 1.1649 + 1.1650 + lua_settop(LUA, 0); 1.1651 + lua_getfield(LUA, LUA_REGISTRYINDEX, idstring); 1.1652 + 1.1653 + int errorcode = 0; 1.1654 + if (lua_isfunction(LUA, -1)) 1.1655 + { 1.1656 + errorcode = lua_pcall(LUA, 0, 0, 0); 1.1657 + if (errorcode) 1.1658 + HandleCallbackError(LUA); 1.1659 + } 1.1660 + else 1.1661 + { 1.1662 + lua_pop(LUA, 1); 1.1663 + } 1.1664 +} 1.1665 1.1666 // the purpose of this structure is to provide a way of 1.1667 // QUICKLY determining whether a memory address range has a hook associated with it, 1.1668 @@ -1055,778 +1055,778 @@ 1.1669 // otherwise it would definitely be too slow.) 1.1670 // calculating the regions when a hook is added/removed may be slow, 1.1671 // but this is an intentional tradeoff to obtain a high speed of checking during later execution 1.1672 - struct TieredRegion 1.1673 - { 1.1674 - template<unsigned int maxGap> 1.1675 - struct Region 1.1676 - { 1.1677 - struct Island 1.1678 - { 1.1679 - unsigned int start; 1.1680 - unsigned int end; 1.1681 - __forceinline bool Contains(unsigned int address, int size) const { return address < end && address + size > start; } 1.1682 - }; 1.1683 - std::vector<Island> islands; 1.1684 - 1.1685 - void Calculate(const std::vector<unsigned int> &bytes) 1.1686 - { 1.1687 - islands. clear(); 1.1688 - 1.1689 - unsigned int lastEnd = ~0; 1.1690 - 1.1691 - std::vector<unsigned int>::const_iterator iter = bytes.begin(); 1.1692 - std::vector<unsigned int>::const_iterator end = bytes.end(); 1.1693 - for (; iter != end; ++iter) 1.1694 - { 1.1695 - unsigned int addr = *iter; 1.1696 - if (addr < lastEnd || addr > lastEnd + (long long)maxGap) 1.1697 - { 1.1698 - islands. push_back(Island()); 1.1699 - islands. back().start = addr; 1.1700 - } 1.1701 - islands.back(). end = addr + 1; 1.1702 - lastEnd = addr + 1; 1.1703 - } 1.1704 - } 1.1705 - 1.1706 - bool Contains(unsigned int address, int size) const 1.1707 - { 1.1708 - for (size_t i = 0; i != islands.size(); ++i) 1.1709 - { 1.1710 - if (islands[i].Contains(address, size)) 1.1711 - return true; 1.1712 - } 1.1713 - return false; 1.1714 - } 1.1715 - }; 1.1716 - 1.1717 - Region<0xFFFFFFFF> broad; 1.1718 - Region<0x1000> mid; 1.1719 - Region<0> narrow; 1.1720 - 1.1721 - void Calculate(std::vector<unsigned int> &bytes) 1.1722 - { 1.1723 - std:: sort(bytes.begin(), bytes.end()); 1.1724 - 1.1725 - broad. Calculate(bytes); 1.1726 - mid. Calculate(bytes); 1.1727 - narrow. Calculate(bytes); 1.1728 - } 1.1729 - 1.1730 - TieredRegion() 1.1731 - { 1.1732 - std::vector <unsigned int> temp; 1.1733 - Calculate(temp); 1.1734 - } 1.1735 - 1.1736 - __forceinline int NotEmpty() 1.1737 - { 1.1738 - return broad.islands.size(); 1.1739 - } 1.1740 - 1.1741 - // note: it is illegal to call this if NotEmpty() returns 0 1.1742 - __forceinline bool Contains(unsigned int address, int size) 1.1743 - { 1.1744 - return broad.islands[0].Contains(address, size) && 1.1745 - mid.Contains(address, size) && 1.1746 - narrow.Contains(address, size); 1.1747 - } 1.1748 - }; 1.1749 - TieredRegion hookedRegions [LUAMEMHOOK_COUNT]; 1.1750 - 1.1751 - static void CalculateMemHookRegions(LuaMemHookType hookType) 1.1752 - { 1.1753 - std::vector<unsigned int> hookedBytes; 1.1754 -// std::map<int, LuaContextInfo*>::iterator iter = luaContextInfo.begin(); 1.1755 -// std::map<int, LuaContextInfo*>::iterator end = luaContextInfo.end(); 1.1756 -// while(iter != end) 1.1757 -// { 1.1758 -// LuaContextInfo& info = *iter->second; 1.1759 - if (/*info.*/ numMemHooks) 1.1760 - { 1.1761 - lua_State *L = LUA /*info.L*/; 1.1762 - if (L) 1.1763 - { 1.1764 - lua_settop(L, 0); 1.1765 - lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]); 1.1766 - lua_pushnil(L); 1.1767 - while (lua_next(L, -2)) 1.1768 - { 1.1769 - if (lua_isfunction(L, -1)) 1.1770 - { 1.1771 - unsigned int addr = lua_tointeger(L, -2); 1.1772 - hookedBytes.push_back(addr); 1.1773 - } 1.1774 - lua_pop(L, 1); 1.1775 - } 1.1776 - lua_settop(L, 0); 1.1777 - } 1.1778 - } 1.1779 -// ++iter; 1.1780 -// } 1.1781 - hookedRegions[hookType].Calculate(hookedBytes); 1.1782 - } 1.1783 - 1.1784 - static void CallRegisteredLuaMemHook_LuaMatch(unsigned int address, int size, unsigned int value, LuaMemHookType hookType) 1.1785 - { 1.1786 -// std::map<int, LuaContextInfo*>::iterator iter = luaContextInfo.begin(); 1.1787 -// std::map<int, LuaContextInfo*>::iterator end = luaContextInfo.end(); 1.1788 -// while(iter != end) 1.1789 -// { 1.1790 -// LuaContextInfo& info = *iter->second; 1.1791 - if (/*info.*/ numMemHooks) 1.1792 - { 1.1793 - lua_State *L = LUA /*info.L*/; 1.1794 - if (L /* && !info.panic*/) 1.1795 - { 1.1796 +struct TieredRegion 1.1797 +{ 1.1798 + template<unsigned int maxGap> 1.1799 + struct Region 1.1800 + { 1.1801 + struct Island 1.1802 + { 1.1803 + unsigned int start; 1.1804 + unsigned int end; 1.1805 + __forceinline bool Contains(unsigned int address, int size) const { return address < end && address + size > start; } 1.1806 + }; 1.1807 + std::vector<Island> islands; 1.1808 + 1.1809 + void Calculate(const std::vector<unsigned int> &bytes) 1.1810 + { 1.1811 + islands. clear(); 1.1812 + 1.1813 + unsigned int lastEnd = ~0; 1.1814 + 1.1815 + std::vector<unsigned int>::const_iterator iter = bytes.begin(); 1.1816 + std::vector<unsigned int>::const_iterator end = bytes.end(); 1.1817 + for (; iter != end; ++iter) 1.1818 + { 1.1819 + unsigned int addr = *iter; 1.1820 + if (addr < lastEnd || addr > lastEnd + (long long)maxGap) 1.1821 + { 1.1822 + islands. push_back(Island()); 1.1823 + islands. back().start = addr; 1.1824 + } 1.1825 + islands.back(). end = addr + 1; 1.1826 + lastEnd = addr + 1; 1.1827 + } 1.1828 + } 1.1829 + 1.1830 + bool Contains(unsigned int address, int size) const 1.1831 + { 1.1832 + for (size_t i = 0; i != islands.size(); ++i) 1.1833 + { 1.1834 + if (islands[i].Contains(address, size)) 1.1835 + return true; 1.1836 + } 1.1837 + return false; 1.1838 + } 1.1839 + }; 1.1840 + 1.1841 + Region<0xFFFFFFFF> broad; 1.1842 + Region<0x1000> mid; 1.1843 + Region<0> narrow; 1.1844 + 1.1845 + void Calculate(std::vector<unsigned int> &bytes) 1.1846 + { 1.1847 + std:: sort(bytes.begin(), bytes.end()); 1.1848 + 1.1849 + broad. Calculate(bytes); 1.1850 + mid. Calculate(bytes); 1.1851 + narrow. Calculate(bytes); 1.1852 + } 1.1853 + 1.1854 + TieredRegion() 1.1855 + { 1.1856 + std::vector <unsigned int> temp; 1.1857 + Calculate(temp); 1.1858 + } 1.1859 + 1.1860 + __forceinline int NotEmpty() 1.1861 + { 1.1862 + return broad.islands.size(); 1.1863 + } 1.1864 + 1.1865 + // note: it is illegal to call this if NotEmpty() returns 0 1.1866 + __forceinline bool Contains(unsigned int address, int size) 1.1867 + { 1.1868 + return broad.islands[0].Contains(address, size) && 1.1869 + mid.Contains(address, size) && 1.1870 + narrow.Contains(address, size); 1.1871 + } 1.1872 +}; 1.1873 +TieredRegion hookedRegions [LUAMEMHOOK_COUNT]; 1.1874 + 1.1875 +static void CalculateMemHookRegions(LuaMemHookType hookType) 1.1876 +{ 1.1877 + std::vector<unsigned int> hookedBytes; 1.1878 + // std::map<int, LuaContextInfo*>::iterator iter = luaContextInfo.begin(); 1.1879 + // std::map<int, LuaContextInfo*>::iterator end = luaContextInfo.end(); 1.1880 + // while(iter != end) 1.1881 + // { 1.1882 + // LuaContextInfo& info = *iter->second; 1.1883 + if (/*info.*/ numMemHooks) 1.1884 + { 1.1885 + lua_State *L = LUA /*info.L*/; 1.1886 + if (L) 1.1887 + { 1.1888 + lua_settop(L, 0); 1.1889 + lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]); 1.1890 + lua_pushnil(L); 1.1891 + while (lua_next(L, -2)) 1.1892 + { 1.1893 + if (lua_isfunction(L, -1)) 1.1894 + { 1.1895 + unsigned int addr = lua_tointeger(L, -2); 1.1896 + hookedBytes.push_back(addr); 1.1897 + } 1.1898 + lua_pop(L, 1); 1.1899 + } 1.1900 + lua_settop(L, 0); 1.1901 + } 1.1902 + } 1.1903 + // ++iter; 1.1904 + // } 1.1905 + hookedRegions[hookType].Calculate(hookedBytes); 1.1906 +} 1.1907 + 1.1908 +static void CallRegisteredLuaMemHook_LuaMatch(unsigned int address, int size, unsigned int value, LuaMemHookType hookType) 1.1909 +{ 1.1910 + // std::map<int, LuaContextInfo*>::iterator iter = luaContextInfo.begin(); 1.1911 + // std::map<int, LuaContextInfo*>::iterator end = luaContextInfo.end(); 1.1912 + // while(iter != end) 1.1913 + // { 1.1914 + // LuaContextInfo& info = *iter->second; 1.1915 + if (/*info.*/ numMemHooks) 1.1916 + { 1.1917 + lua_State *L = LUA /*info.L*/; 1.1918 + if (L /* && !info.panic*/) 1.1919 + { 1.1920 #ifdef USE_INFO_STACK 1.1921 - infoStack.insert(infoStack.begin(), &info); 1.1922 - struct Scope { ~Scope(){ infoStack. erase(infoStack.begin()); } } scope; 1.1923 + infoStack.insert(infoStack.begin(), &info); 1.1924 + struct Scope { ~Scope(){ infoStack. erase(infoStack.begin()); } } scope; 1.1925 #endif 1.1926 - lua_settop(L, 0); 1.1927 - lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]); 1.1928 - for (int i = address; i != address + size; i++) 1.1929 - { 1.1930 - lua_rawgeti(L, -1, i); 1.1931 - if (lua_isfunction(L, -1)) 1.1932 - { 1.1933 - bool wasRunning = (luaRunning != 0) /*info.running*/; 1.1934 - luaRunning /*info.running*/ = true; 1.1935 - //RefreshScriptSpeedStatus(); 1.1936 - lua_pushinteger(L, address); 1.1937 - lua_pushinteger(L, size); 1.1938 - int errorcode = lua_pcall(L, 2, 0, 0); 1.1939 - luaRunning /*info.running*/ = wasRunning; 1.1940 - //RefreshScriptSpeedStatus(); 1.1941 - if (errorcode) 1.1942 - { 1.1943 - HandleCallbackError(L); 1.1944 - //int uid = iter->first; 1.1945 - //HandleCallbackError(L,info,uid,true); 1.1946 - } 1.1947 - break; 1.1948 - } 1.1949 - else 1.1950 - { 1.1951 - lua_pop(L, 1); 1.1952 - } 1.1953 - } 1.1954 - lua_settop(L, 0); 1.1955 - } 1.1956 - } 1.1957 -// ++iter; 1.1958 -// } 1.1959 - } 1.1960 - 1.1961 - void CallRegisteredLuaMemHook(unsigned int address, int size, unsigned int value, LuaMemHookType hookType) 1.1962 - { 1.1963 - // performance critical! (called VERY frequently) 1.1964 - // I suggest timing a large number of calls to this function in Release if you change anything in here, 1.1965 - // before and after, because even the most innocent change can make it become 30% to 400% slower. 1.1966 - // a good amount to test is: 100000000 calls with no hook set, and another 100000000 with a hook set. 1.1967 - // (on my system that consistently took 200 ms total in the former case and 350 ms total in the latter 1.1968 - // case) 1.1969 - if (hookedRegions[hookType].NotEmpty()) 1.1970 - { 1.1971 - //if((hookType <= LUAMEMHOOK_EXEC) && (address >= 0xE00000)) 1.1972 - // address |= 0xFF0000; // account for mirroring of RAM 1.1973 - if (hookedRegions[hookType].Contains(address, size)) 1.1974 - CallRegisteredLuaMemHook_LuaMatch(address, size, value, hookType); // something has hooked this 1.1975 - // specific address 1.1976 - } 1.1977 - } 1.1978 - 1.1979 - static int memory_registerHook(lua_State *L, LuaMemHookType hookType, int defaultSize) 1.1980 - { 1.1981 - // get first argument: address 1.1982 - unsigned int addr = luaL_checkinteger(L, 1); 1.1983 - //if((addr & ~0xFFFFFF) == ~0xFFFFFF) 1.1984 - // addr &= 0xFFFFFF; 1.1985 - 1.1986 - // get optional second argument: size 1.1987 - int size = defaultSize; 1.1988 - int funcIdx = 2; 1.1989 - if (lua_isnumber(L, 2)) 1.1990 - { 1.1991 - size = luaL_checkinteger(L, 2); 1.1992 - if (size < 0) 1.1993 - { 1.1994 - size = -size; 1.1995 - addr -= size; 1.1996 - } 1.1997 - funcIdx++; 1.1998 - } 1.1999 - 1.2000 - // check last argument: callback function 1.2001 - bool clearing = lua_isnil(L, funcIdx); 1.2002 - if (!clearing) 1.2003 - luaL_checktype(L, funcIdx, LUA_TFUNCTION); 1.2004 - lua_settop(L, funcIdx); 1.2005 - 1.2006 - // get the address-to-callback table for this hook type of the current script 1.2007 - lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]); 1.2008 - 1.2009 - // count how many callback functions we'll be displacing 1.2010 - int numFuncsAfter = clearing ? 0 : size; 1.2011 - int numFuncsBefore = 0; 1.2012 - for (unsigned int i = addr; i != addr + size; i++) 1.2013 - { 1.2014 - lua_rawgeti(L, -1, i); 1.2015 - if (lua_isfunction(L, -1)) 1.2016 - numFuncsBefore++; 1.2017 - lua_pop(L, 1); 1.2018 - } 1.2019 - 1.2020 - // put the callback function in the address slots 1.2021 - for (unsigned int i = addr; i != addr + size; i++) 1.2022 - { 1.2023 - lua_pushvalue(L, -2); 1.2024 - lua_rawseti(L, -2, i); 1.2025 - } 1.2026 - 1.2027 - // adjust the count of active hooks 1.2028 - //LuaContextInfo& info = GetCurrentInfo(); 1.2029 - /*info.*/ numMemHooks += numFuncsAfter - numFuncsBefore; 1.2030 - 1.2031 - // re-cache regions of hooked memory across all scripts 1.2032 - CalculateMemHookRegions(hookType); 1.2033 - 1.2034 - //StopScriptIfFinished(luaStateToUIDMap[L]); 1.2035 - return 0; 1.2036 - } 1.2037 - 1.2038 - LuaMemHookType MatchHookTypeToCPU(lua_State *L, LuaMemHookType hookType) 1.2039 - { 1.2040 - int cpuID = 0; 1.2041 - 1.2042 - int cpunameIndex = 0; 1.2043 - if (lua_type(L, 2) == LUA_TSTRING) 1.2044 - cpunameIndex = 2; 1.2045 - else if (lua_type(L, 3) == LUA_TSTRING) 1.2046 - cpunameIndex = 3; 1.2047 - 1.2048 - if (cpunameIndex) 1.2049 - { 1.2050 - const char *cpuName = lua_tostring(L, cpunameIndex); 1.2051 - if (!stricmp(cpuName, "sub")) 1.2052 - cpuID = 1; 1.2053 - lua_remove(L, cpunameIndex); 1.2054 - } 1.2055 - 1.2056 - switch (cpuID) 1.2057 - { 1.2058 - case 0: 1.2059 - return hookType; 1.2060 - 1.2061 - case 1: 1.2062 - switch (hookType) 1.2063 - { 1.2064 - case LUAMEMHOOK_WRITE: 1.2065 - return LUAMEMHOOK_WRITE_SUB; 1.2066 - case LUAMEMHOOK_READ: 1.2067 - return LUAMEMHOOK_READ_SUB; 1.2068 - case LUAMEMHOOK_EXEC: 1.2069 - return LUAMEMHOOK_EXEC_SUB; 1.2070 - } 1.2071 - } 1.2072 - return hookType; 1.2073 - } 1.2074 - 1.2075 - static int memory_registerwrite(lua_State *L) 1.2076 - { 1.2077 - return memory_registerHook(L, MatchHookTypeToCPU(L, LUAMEMHOOK_WRITE), 1); 1.2078 - } 1.2079 - 1.2080 - static int memory_registerread(lua_State *L) 1.2081 - { 1.2082 - return memory_registerHook(L, MatchHookTypeToCPU(L, LUAMEMHOOK_READ), 1); 1.2083 - } 1.2084 - 1.2085 - static int memory_registerexec(lua_State *L) 1.2086 - { 1.2087 - return memory_registerHook(L, MatchHookTypeToCPU(L, LUAMEMHOOK_EXEC), 1); 1.2088 - } 1.2089 + lua_settop(L, 0); 1.2090 + lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]); 1.2091 + for (int i = address; i != address + size; i++) 1.2092 + { 1.2093 + lua_rawgeti(L, -1, i); 1.2094 + if (lua_isfunction(L, -1)) 1.2095 + { 1.2096 + bool wasRunning = (luaRunning != 0) /*info.running*/; 1.2097 + luaRunning /*info.running*/ = true; 1.2098 + //RefreshScriptSpeedStatus(); 1.2099 + lua_pushinteger(L, address); 1.2100 + lua_pushinteger(L, size); 1.2101 + int errorcode = lua_pcall(L, 2, 0, 0); 1.2102 + luaRunning /*info.running*/ = wasRunning; 1.2103 + //RefreshScriptSpeedStatus(); 1.2104 + if (errorcode) 1.2105 + { 1.2106 + HandleCallbackError(L); 1.2107 + //int uid = iter->first; 1.2108 + //HandleCallbackError(L,info,uid,true); 1.2109 + } 1.2110 + break; 1.2111 + } 1.2112 + else 1.2113 + { 1.2114 + lua_pop(L, 1); 1.2115 + } 1.2116 + } 1.2117 + lua_settop(L, 0); 1.2118 + } 1.2119 + } 1.2120 + // ++iter; 1.2121 + // } 1.2122 +} 1.2123 + 1.2124 +void CallRegisteredLuaMemHook(unsigned int address, int size, unsigned int value, LuaMemHookType hookType) 1.2125 +{ 1.2126 + // performance critical! (called VERY frequently) 1.2127 + // I suggest timing a large number of calls to this function in Release if you change anything in here, 1.2128 + // before and after, because even the most innocent change can make it become 30% to 400% slower. 1.2129 + // a good amount to test is: 100000000 calls with no hook set, and another 100000000 with a hook set. 1.2130 + // (on my system that consistently took 200 ms total in the former case and 350 ms total in the latter 1.2131 + // case) 1.2132 + if (hookedRegions[hookType].NotEmpty()) 1.2133 + { 1.2134 + //if((hookType <= LUAMEMHOOK_EXEC) && (address >= 0xE00000)) 1.2135 + // address |= 0xFF0000; // account for mirroring of RAM 1.2136 + if (hookedRegions[hookType].Contains(address, size)) 1.2137 + CallRegisteredLuaMemHook_LuaMatch(address, size, value, hookType); // something has hooked this 1.2138 + // specific address 1.2139 + } 1.2140 +} 1.2141 + 1.2142 +static int memory_registerHook(lua_State *L, LuaMemHookType hookType, int defaultSize) 1.2143 +{ 1.2144 + // get first argument: address 1.2145 + unsigned int addr = luaL_checkinteger(L, 1); 1.2146 + //if((addr & ~0xFFFFFF) == ~0xFFFFFF) 1.2147 + // addr &= 0xFFFFFF; 1.2148 + 1.2149 + // get optional second argument: size 1.2150 + int size = defaultSize; 1.2151 + int funcIdx = 2; 1.2152 + if (lua_isnumber(L, 2)) 1.2153 + { 1.2154 + size = luaL_checkinteger(L, 2); 1.2155 + if (size < 0) 1.2156 + { 1.2157 + size = -size; 1.2158 + addr -= size; 1.2159 + } 1.2160 + funcIdx++; 1.2161 + } 1.2162 + 1.2163 + // check last argument: callback function 1.2164 + bool clearing = lua_isnil(L, funcIdx); 1.2165 + if (!clearing) 1.2166 + luaL_checktype(L, funcIdx, LUA_TFUNCTION); 1.2167 + lua_settop(L, funcIdx); 1.2168 + 1.2169 + // get the address-to-callback table for this hook type of the current script 1.2170 + lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]); 1.2171 + 1.2172 + // count how many callback functions we'll be displacing 1.2173 + int numFuncsAfter = clearing ? 0 : size; 1.2174 + int numFuncsBefore = 0; 1.2175 + for (unsigned int i = addr; i != addr + size; i++) 1.2176 + { 1.2177 + lua_rawgeti(L, -1, i); 1.2178 + if (lua_isfunction(L, -1)) 1.2179 + numFuncsBefore++; 1.2180 + lua_pop(L, 1); 1.2181 + } 1.2182 + 1.2183 + // put the callback function in the address slots 1.2184 + for (unsigned int i = addr; i != addr + size; i++) 1.2185 + { 1.2186 + lua_pushvalue(L, -2); 1.2187 + lua_rawseti(L, -2, i); 1.2188 + } 1.2189 + 1.2190 + // adjust the count of active hooks 1.2191 + //LuaContextInfo& info = GetCurrentInfo(); 1.2192 + /*info.*/ numMemHooks += numFuncsAfter - numFuncsBefore; 1.2193 + 1.2194 + // re-cache regions of hooked memory across all scripts 1.2195 + CalculateMemHookRegions(hookType); 1.2196 + 1.2197 + //StopScriptIfFinished(luaStateToUIDMap[L]); 1.2198 + return 0; 1.2199 +} 1.2200 + 1.2201 +LuaMemHookType MatchHookTypeToCPU(lua_State *L, LuaMemHookType hookType) 1.2202 +{ 1.2203 + int cpuID = 0; 1.2204 + 1.2205 + int cpunameIndex = 0; 1.2206 + if (lua_type(L, 2) == LUA_TSTRING) 1.2207 + cpunameIndex = 2; 1.2208 + else if (lua_type(L, 3) == LUA_TSTRING) 1.2209 + cpunameIndex = 3; 1.2210 + 1.2211 + if (cpunameIndex) 1.2212 + { 1.2213 + const char *cpuName = lua_tostring(L, cpunameIndex); 1.2214 + if (!stricmp(cpuName, "sub")) 1.2215 + cpuID = 1; 1.2216 + lua_remove(L, cpunameIndex); 1.2217 + } 1.2218 + 1.2219 + switch (cpuID) 1.2220 + { 1.2221 + case 0: 1.2222 + return hookType; 1.2223 + 1.2224 + case 1: 1.2225 + switch (hookType) 1.2226 + { 1.2227 + case LUAMEMHOOK_WRITE: 1.2228 + return LUAMEMHOOK_WRITE_SUB; 1.2229 + case LUAMEMHOOK_READ: 1.2230 + return LUAMEMHOOK_READ_SUB; 1.2231 + case LUAMEMHOOK_EXEC: 1.2232 + return LUAMEMHOOK_EXEC_SUB; 1.2233 + } 1.2234 + } 1.2235 + return hookType; 1.2236 +} 1.2237 + 1.2238 +static int memory_registerwrite(lua_State *L) 1.2239 +{ 1.2240 + return memory_registerHook(L, MatchHookTypeToCPU(L, LUAMEMHOOK_WRITE), 1); 1.2241 +} 1.2242 + 1.2243 +static int memory_registerread(lua_State *L) 1.2244 +{ 1.2245 + return memory_registerHook(L, MatchHookTypeToCPU(L, LUAMEMHOOK_READ), 1); 1.2246 +} 1.2247 + 1.2248 +static int memory_registerexec(lua_State *L) 1.2249 +{ 1.2250 + return memory_registerHook(L, MatchHookTypeToCPU(L, LUAMEMHOOK_EXEC), 1); 1.2251 +} 1.2252 1.2253 //int vba.lagcount 1.2254 // 1.2255 1.2256 //Returns the lagcounter variable 1.2257 - static int vba_getlagcount(lua_State *L) 1.2258 - { 1.2259 - lua_pushinteger(L, systemCounters.lagCount); 1.2260 - return 1; 1.2261 - } 1.2262 +static int vba_getlagcount(lua_State *L) 1.2263 +{ 1.2264 + lua_pushinteger(L, systemCounters.lagCount); 1.2265 + return 1; 1.2266 +} 1.2267 1.2268 //int vba.lagged 1.2269 // 1.2270 //Returns true if the current frame is a lag frame 1.2271 - static int vba_lagged(lua_State *L) 1.2272 - { 1.2273 - lua_pushboolean(L, systemCounters.laggedLast); 1.2274 - return 1; 1.2275 - } 1.2276 +static int vba_lagged(lua_State *L) 1.2277 +{ 1.2278 + lua_pushboolean(L, systemCounters.laggedLast); 1.2279 + return 1; 1.2280 +} 1.2281 1.2282 // boolean vba.emulating() 1.2283 - int vba_emulating(lua_State *L) 1.2284 - { 1.2285 - lua_pushboolean(L, systemIsEmulating()); 1.2286 - return 1; 1.2287 - } 1.2288 - 1.2289 - int movie_isactive(lua_State *L) 1.2290 - { 1.2291 - lua_pushboolean(L, VBAMovieActive()); 1.2292 - return 1; 1.2293 - } 1.2294 - 1.2295 - int movie_isrecording(lua_State *L) 1.2296 - { 1.2297 - lua_pushboolean(L, VBAMovieRecording()); 1.2298 - return 1; 1.2299 - } 1.2300 - 1.2301 - int movie_isplaying(lua_State *L) 1.2302 - { 1.2303 - lua_pushboolean(L, VBAMoviePlaying()); 1.2304 - return 1; 1.2305 - } 1.2306 - 1.2307 - int movie_getlength(lua_State *L) 1.2308 - { 1.2309 - if (VBAMovieActive()) 1.2310 - lua_pushinteger(L, VBAMovieGetLength()); 1.2311 - else 1.2312 - lua_pushinteger(L, 0); 1.2313 - return 1; 1.2314 - } 1.2315 - 1.2316 - static int memory_readbyte(lua_State *L) 1.2317 - { 1.2318 - u32 addr; 1.2319 - u8 val; 1.2320 - 1.2321 - addr = luaL_checkinteger(L, 1); 1.2322 - if (systemIsRunningGBA()) 1.2323 - { 1.2324 - val = CPUReadByteQuick(addr); 1.2325 - } 1.2326 - else 1.2327 - { 1.2328 - val = gbReadMemoryQuick8(addr); 1.2329 - } 1.2330 - 1.2331 - lua_pushinteger(L, val); 1.2332 - return 1; 1.2333 - } 1.2334 - 1.2335 - static int memory_readbytesigned(lua_State *L) 1.2336 - { 1.2337 - u32 addr; 1.2338 - s8 val; 1.2339 - 1.2340 - addr = luaL_checkinteger(L, 1); 1.2341 - if (systemIsRunningGBA()) 1.2342 - { 1.2343 - val = (s8) CPUReadByteQuick(addr); 1.2344 - } 1.2345 - else 1.2346 - { 1.2347 - val = (s8) gbReadMemoryQuick8(addr); 1.2348 - } 1.2349 - 1.2350 - lua_pushinteger(L, val); 1.2351 - return 1; 1.2352 - } 1.2353 - 1.2354 - static int memory_readword(lua_State *L) 1.2355 - { 1.2356 - u32 addr; 1.2357 - u16 val; 1.2358 - 1.2359 - addr = luaL_checkinteger(L, 1); 1.2360 - if (systemIsRunningGBA()) 1.2361 - { 1.2362 - val = CPUReadHalfWordQuick(addr); 1.2363 - } 1.2364 - else 1.2365 - { 1.2366 - val = gbReadMemoryQuick16(addr & 0x0000FFFF); 1.2367 - } 1.2368 - 1.2369 - lua_pushinteger(L, val); 1.2370 - return 1; 1.2371 - } 1.2372 - 1.2373 - static int memory_readwordsigned(lua_State *L) 1.2374 - { 1.2375 - u32 addr; 1.2376 - s16 val; 1.2377 - 1.2378 - addr = luaL_checkinteger(L, 1); 1.2379 - if (systemIsRunningGBA()) 1.2380 - { 1.2381 - val = (s16) CPUReadHalfWordQuick(addr); 1.2382 - } 1.2383 - else 1.2384 - { 1.2385 - val = (s16) gbReadMemoryQuick16(addr); 1.2386 - } 1.2387 - 1.2388 - lua_pushinteger(L, val); 1.2389 - return 1; 1.2390 - } 1.2391 - 1.2392 - static int memory_readdword(lua_State *L) 1.2393 - { 1.2394 - u32 addr; 1.2395 - u32 val; 1.2396 - 1.2397 - addr = luaL_checkinteger(L, 1); 1.2398 - if (systemIsRunningGBA()) 1.2399 - { 1.2400 - val = CPUReadMemoryQuick(addr); 1.2401 - } 1.2402 - else 1.2403 - { 1.2404 - val = gbReadMemoryQuick32(addr & 0x0000FFFF); 1.2405 - } 1.2406 - 1.2407 - // lua_pushinteger doesn't work properly for 32bit system, does it? 1.2408 - if (val >= 0x80000000 && sizeof(int) <= 4) 1.2409 - lua_pushnumber(L, val); 1.2410 - else 1.2411 - lua_pushinteger(L, val); 1.2412 - return 1; 1.2413 - } 1.2414 - 1.2415 - static int memory_readdwordsigned(lua_State *L) 1.2416 - { 1.2417 - u32 addr; 1.2418 - s32 val; 1.2419 - 1.2420 - addr = luaL_checkinteger(L, 1); 1.2421 - if (systemIsRunningGBA()) 1.2422 - { 1.2423 - val = (s32) CPUReadMemoryQuick(addr); 1.2424 - } 1.2425 - else 1.2426 - { 1.2427 - val = (s32) gbReadMemoryQuick32(addr); 1.2428 - } 1.2429 - 1.2430 - lua_pushinteger(L, val); 1.2431 - return 1; 1.2432 - } 1.2433 - 1.2434 - static int memory_readbyterange(lua_State *L) 1.2435 - { 1.2436 - uint32 address = luaL_checkinteger(L, 1); 1.2437 - int length = luaL_checkinteger(L, 2); 1.2438 - 1.2439 - if (length < 0) 1.2440 - { 1.2441 - address += length; 1.2442 - length = -length; 1.2443 - } 1.2444 - 1.2445 - // push the array 1.2446 - lua_createtable(L, abs(length), 0); 1.2447 - 1.2448 - // put all the values into the (1-based) array 1.2449 - for (int a = address, n = 1; n <= length; a++, n++) 1.2450 - { 1.2451 - unsigned char value; 1.2452 - 1.2453 - if (systemIsRunningGBA()) 1.2454 - { 1.2455 - value = CPUReadByteQuick(a); 1.2456 - } 1.2457 - else 1.2458 - { 1.2459 - value = gbReadMemoryQuick8(a); 1.2460 - } 1.2461 - 1.2462 - lua_pushinteger(L, value); 1.2463 - lua_rawseti(L, -2, n); 1.2464 - } 1.2465 - 1.2466 - return 1; 1.2467 - } 1.2468 - 1.2469 - static int memory_writebyte(lua_State *L) 1.2470 - { 1.2471 - u32 addr; 1.2472 - int val; 1.2473 - 1.2474 - addr = luaL_checkinteger(L, 1); 1.2475 - val = luaL_checkinteger(L, 2); 1.2476 - if (systemIsRunningGBA()) 1.2477 - { 1.2478 - CPUWriteByteQuick(addr, val); 1.2479 - } 1.2480 - else 1.2481 - { 1.2482 - gbWriteMemoryQuick8(addr, val); 1.2483 - } 1.2484 - 1.2485 - CallRegisteredLuaMemHook(addr, 1, val, LUAMEMHOOK_WRITE); 1.2486 - return 0; 1.2487 - } 1.2488 - 1.2489 - static int memory_writeword(lua_State *L) 1.2490 - { 1.2491 - u32 addr; 1.2492 - int val; 1.2493 - 1.2494 - addr = luaL_checkinteger(L, 1); 1.2495 - val = luaL_checkinteger(L, 2); 1.2496 - if (systemIsRunningGBA()) 1.2497 - { 1.2498 - CPUWriteHalfWordQuick(addr, val); 1.2499 - } 1.2500 - else 1.2501 - { 1.2502 - gbWriteMemoryQuick16(addr, val); 1.2503 - } 1.2504 - 1.2505 - CallRegisteredLuaMemHook(addr, 2, val, LUAMEMHOOK_WRITE); 1.2506 - return 0; 1.2507 - } 1.2508 - 1.2509 - static int memory_writedword(lua_State *L) 1.2510 - { 1.2511 - u32 addr; 1.2512 - int val; 1.2513 - 1.2514 - addr = luaL_checkinteger(L, 1); 1.2515 - val = luaL_checkinteger(L, 2); 1.2516 - if (systemIsRunningGBA()) 1.2517 - { 1.2518 - CPUWriteMemoryQuick(addr, val); 1.2519 - } 1.2520 - else 1.2521 - { 1.2522 - gbWriteMemoryQuick32(addr, val); 1.2523 - } 1.2524 - 1.2525 - CallRegisteredLuaMemHook(addr, 4, val, LUAMEMHOOK_WRITE); 1.2526 - return 0; 1.2527 - } 1.2528 - 1.2529 - static int memory_gbromreadbyte(lua_State *L) 1.2530 - { 1.2531 - u32 addr; 1.2532 - u8 val; 1.2533 - 1.2534 - addr = luaL_checkinteger(L, 1); 1.2535 - if (systemIsRunningGBA()) 1.2536 - { 1.2537 - lua_pushnil(L); 1.2538 - return 1; 1.2539 - } 1.2540 - else 1.2541 - { 1.2542 - val = gbReadROMQuick8(addr); 1.2543 - } 1.2544 - 1.2545 - lua_pushinteger(L, val); 1.2546 - return 1; 1.2547 - } 1.2548 - 1.2549 - static int memory_gbromreadbytesigned(lua_State *L) 1.2550 - { 1.2551 - u32 addr; 1.2552 - s8 val; 1.2553 - 1.2554 - addr = luaL_checkinteger(L, 1); 1.2555 - if (systemIsRunningGBA()) 1.2556 - { 1.2557 - lua_pushnil(L); 1.2558 - return 1; 1.2559 - } 1.2560 - else 1.2561 - { 1.2562 - val = (s8) gbReadROMQuick8(addr); 1.2563 - } 1.2564 - 1.2565 - lua_pushinteger(L, val); 1.2566 - return 1; 1.2567 - } 1.2568 - 1.2569 - static int memory_gbromreadword(lua_State *L) 1.2570 - { 1.2571 - u32 addr; 1.2572 - u16 val; 1.2573 - 1.2574 - addr = luaL_checkinteger(L, 1); 1.2575 - if (systemIsRunningGBA()) 1.2576 - { 1.2577 - lua_pushnil(L); 1.2578 - return 1; 1.2579 - } 1.2580 - else 1.2581 - { 1.2582 - val = gbReadROMQuick16(addr); 1.2583 - } 1.2584 - 1.2585 - lua_pushinteger(L, val); 1.2586 - return 1; 1.2587 - } 1.2588 - 1.2589 - static int memory_gbromreadwordsigned(lua_State *L) 1.2590 - { 1.2591 - u32 addr; 1.2592 - s16 val; 1.2593 - 1.2594 - addr = luaL_checkinteger(L, 1); 1.2595 - if (systemIsRunningGBA()) 1.2596 - { 1.2597 - lua_pushnil(L); 1.2598 - return 1; 1.2599 - } 1.2600 - else 1.2601 - { 1.2602 - val = (s16) gbReadROMQuick16(addr); 1.2603 - } 1.2604 - 1.2605 - lua_pushinteger(L, val); 1.2606 - return 1; 1.2607 - } 1.2608 - 1.2609 - static int memory_gbromreaddword(lua_State *L) 1.2610 - { 1.2611 - u32 addr; 1.2612 - u32 val; 1.2613 - 1.2614 - addr = luaL_checkinteger(L, 1); 1.2615 - if (systemIsRunningGBA()) 1.2616 - { 1.2617 - lua_pushnil(L); 1.2618 - return 1; 1.2619 - } 1.2620 - else 1.2621 - { 1.2622 - val = gbReadROMQuick32(addr); 1.2623 - } 1.2624 - 1.2625 - // lua_pushinteger doesn't work properly for 32bit system, does it? 1.2626 - if (val >= 0x80000000 && sizeof(int) <= 4) 1.2627 - lua_pushnumber(L, val); 1.2628 - else 1.2629 - lua_pushinteger(L, val); 1.2630 - return 1; 1.2631 - } 1.2632 - 1.2633 - static int memory_gbromreaddwordsigned(lua_State *L) 1.2634 - { 1.2635 - u32 addr; 1.2636 - s32 val; 1.2637 - 1.2638 - addr = luaL_checkinteger(L, 1); 1.2639 - if (systemIsRunningGBA()) 1.2640 - { 1.2641 - lua_pushnil(L); 1.2642 - return 1; 1.2643 - } 1.2644 - else 1.2645 - { 1.2646 - val = (s32) gbReadROMQuick32(addr); 1.2647 - } 1.2648 - 1.2649 - lua_pushinteger(L, val); 1.2650 - return 1; 1.2651 - } 1.2652 - 1.2653 - static int memory_gbromreadbyterange(lua_State *L) 1.2654 - { 1.2655 - uint32 address = luaL_checkinteger(L, 1); 1.2656 - int length = luaL_checkinteger(L, 2); 1.2657 - 1.2658 - if (length < 0) 1.2659 - { 1.2660 - address += length; 1.2661 - length = -length; 1.2662 - } 1.2663 - 1.2664 - // push the array 1.2665 - lua_createtable(L, abs(length), 0); 1.2666 - 1.2667 - // put all the values into the (1-based) array 1.2668 - for (int a = address, n = 1; n <= length; a++, n++) 1.2669 - { 1.2670 - unsigned char value; 1.2671 - 1.2672 - if (systemIsRunningGBA()) 1.2673 - { 1.2674 - lua_pushnil(L); 1.2675 - return 1; 1.2676 - } 1.2677 - else 1.2678 - { 1.2679 - value = gbReadROMQuick8(a); 1.2680 - } 1.2681 - 1.2682 - lua_pushinteger(L, value); 1.2683 - lua_rawseti(L, -2, n); 1.2684 - } 1.2685 - 1.2686 - return 1; 1.2687 - } 1.2688 +int vba_emulating(lua_State *L) 1.2689 +{ 1.2690 + lua_pushboolean(L, systemIsEmulating()); 1.2691 + return 1; 1.2692 +} 1.2693 + 1.2694 +int movie_isactive(lua_State *L) 1.2695 +{ 1.2696 + lua_pushboolean(L, VBAMovieActive()); 1.2697 + return 1; 1.2698 +} 1.2699 + 1.2700 +int movie_isrecording(lua_State *L) 1.2701 +{ 1.2702 + lua_pushboolean(L, VBAMovieRecording()); 1.2703 + return 1; 1.2704 +} 1.2705 + 1.2706 +int movie_isplaying(lua_State *L) 1.2707 +{ 1.2708 + lua_pushboolean(L, VBAMoviePlaying()); 1.2709 + return 1; 1.2710 +} 1.2711 + 1.2712 +int movie_getlength(lua_State *L) 1.2713 +{ 1.2714 + if (VBAMovieActive()) 1.2715 + lua_pushinteger(L, VBAMovieGetLength()); 1.2716 + else 1.2717 + lua_pushinteger(L, 0); 1.2718 + return 1; 1.2719 +} 1.2720 + 1.2721 +static int memory_readbyte(lua_State *L) 1.2722 +{ 1.2723 + u32 addr; 1.2724 + u8 val; 1.2725 + 1.2726 + addr = luaL_checkinteger(L, 1); 1.2727 + if (systemIsRunningGBA()) 1.2728 + { 1.2729 + val = CPUReadByteQuick(addr); 1.2730 + } 1.2731 + else 1.2732 + { 1.2733 + val = gbReadMemoryQuick8(addr); 1.2734 + } 1.2735 + 1.2736 + lua_pushinteger(L, val); 1.2737 + return 1; 1.2738 +} 1.2739 + 1.2740 +static int memory_readbytesigned(lua_State *L) 1.2741 +{ 1.2742 + u32 addr; 1.2743 + s8 val; 1.2744 + 1.2745 + addr = luaL_checkinteger(L, 1); 1.2746 + if (systemIsRunningGBA()) 1.2747 + { 1.2748 + val = (s8) CPUReadByteQuick(addr); 1.2749 + } 1.2750 + else 1.2751 + { 1.2752 + val = (s8) gbReadMemoryQuick8(addr); 1.2753 + } 1.2754 + 1.2755 + lua_pushinteger(L, val); 1.2756 + return 1; 1.2757 +} 1.2758 + 1.2759 +static int memory_readword(lua_State *L) 1.2760 +{ 1.2761 + u32 addr; 1.2762 + u16 val; 1.2763 + 1.2764 + addr = luaL_checkinteger(L, 1); 1.2765 + if (systemIsRunningGBA()) 1.2766 + { 1.2767 + val = CPUReadHalfWordQuick(addr); 1.2768 + } 1.2769 + else 1.2770 + { 1.2771 + val = gbReadMemoryQuick16(addr & 0x0000FFFF); 1.2772 + } 1.2773 + 1.2774 + lua_pushinteger(L, val); 1.2775 + return 1; 1.2776 +} 1.2777 + 1.2778 +static int memory_readwordsigned(lua_State *L) 1.2779 +{ 1.2780 + u32 addr; 1.2781 + s16 val; 1.2782 + 1.2783 + addr = luaL_checkinteger(L, 1); 1.2784 + if (systemIsRunningGBA()) 1.2785 + { 1.2786 + val = (s16) CPUReadHalfWordQuick(addr); 1.2787 + } 1.2788 + else 1.2789 + { 1.2790 + val = (s16) gbReadMemoryQuick16(addr); 1.2791 + } 1.2792 + 1.2793 + lua_pushinteger(L, val); 1.2794 + return 1; 1.2795 +} 1.2796 + 1.2797 +static int memory_readdword(lua_State *L) 1.2798 +{ 1.2799 + u32 addr; 1.2800 + u32 val; 1.2801 + 1.2802 + addr = luaL_checkinteger(L, 1); 1.2803 + if (systemIsRunningGBA()) 1.2804 + { 1.2805 + val = CPUReadMemoryQuick(addr); 1.2806 + } 1.2807 + else 1.2808 + { 1.2809 + val = gbReadMemoryQuick32(addr & 0x0000FFFF); 1.2810 + } 1.2811 + 1.2812 + // lua_pushinteger doesn't work properly for 32bit system, does it? 1.2813 + if (val >= 0x80000000 && sizeof(int) <= 4) 1.2814 + lua_pushnumber(L, val); 1.2815 + else 1.2816 + lua_pushinteger(L, val); 1.2817 + return 1; 1.2818 +} 1.2819 + 1.2820 +static int memory_readdwordsigned(lua_State *L) 1.2821 +{ 1.2822 + u32 addr; 1.2823 + s32 val; 1.2824 + 1.2825 + addr = luaL_checkinteger(L, 1); 1.2826 + if (systemIsRunningGBA()) 1.2827 + { 1.2828 + val = (s32) CPUReadMemoryQuick(addr); 1.2829 + } 1.2830 + else 1.2831 + { 1.2832 + val = (s32) gbReadMemoryQuick32(addr); 1.2833 + } 1.2834 + 1.2835 + lua_pushinteger(L, val); 1.2836 + return 1; 1.2837 +} 1.2838 + 1.2839 +static int memory_readbyterange(lua_State *L) 1.2840 +{ 1.2841 + uint32 address = luaL_checkinteger(L, 1); 1.2842 + int length = luaL_checkinteger(L, 2); 1.2843 + 1.2844 + if (length < 0) 1.2845 + { 1.2846 + address += length; 1.2847 + length = -length; 1.2848 + } 1.2849 + 1.2850 + // push the array 1.2851 + lua_createtable(L, abs(length), 0); 1.2852 + 1.2853 + // put all the values into the (1-based) array 1.2854 + for (int a = address, n = 1; n <= length; a++, n++) 1.2855 + { 1.2856 + unsigned char value; 1.2857 + 1.2858 + if (systemIsRunningGBA()) 1.2859 + { 1.2860 + value = CPUReadByteQuick(a); 1.2861 + } 1.2862 + else 1.2863 + { 1.2864 + value = gbReadMemoryQuick8(a); 1.2865 + } 1.2866 + 1.2867 + lua_pushinteger(L, value); 1.2868 + lua_rawseti(L, -2, n); 1.2869 + } 1.2870 + 1.2871 + return 1; 1.2872 +} 1.2873 + 1.2874 +static int memory_writebyte(lua_State *L) 1.2875 +{ 1.2876 + u32 addr; 1.2877 + int val; 1.2878 + 1.2879 + addr = luaL_checkinteger(L, 1); 1.2880 + val = luaL_checkinteger(L, 2); 1.2881 + if (systemIsRunningGBA()) 1.2882 + { 1.2883 + CPUWriteByteQuick(addr, val); 1.2884 + } 1.2885 + else 1.2886 + { 1.2887 + gbWriteMemoryQuick8(addr, val); 1.2888 + } 1.2889 + 1.2890 + CallRegisteredLuaMemHook(addr, 1, val, LUAMEMHOOK_WRITE); 1.2891 + return 0; 1.2892 +} 1.2893 + 1.2894 +static int memory_writeword(lua_State *L) 1.2895 +{ 1.2896 + u32 addr; 1.2897 + int val; 1.2898 + 1.2899 + addr = luaL_checkinteger(L, 1); 1.2900 + val = luaL_checkinteger(L, 2); 1.2901 + if (systemIsRunningGBA()) 1.2902 + { 1.2903 + CPUWriteHalfWordQuick(addr, val); 1.2904 + } 1.2905 + else 1.2906 + { 1.2907 + gbWriteMemoryQuick16(addr, val); 1.2908 + } 1.2909 + 1.2910 + CallRegisteredLuaMemHook(addr, 2, val, LUAMEMHOOK_WRITE); 1.2911 + return 0; 1.2912 +} 1.2913 + 1.2914 +static int memory_writedword(lua_State *L) 1.2915 +{ 1.2916 + u32 addr; 1.2917 + int val; 1.2918 + 1.2919 + addr = luaL_checkinteger(L, 1); 1.2920 + val = luaL_checkinteger(L, 2); 1.2921 + if (systemIsRunningGBA()) 1.2922 + { 1.2923 + CPUWriteMemoryQuick(addr, val); 1.2924 + } 1.2925 + else 1.2926 + { 1.2927 + gbWriteMemoryQuick32(addr, val); 1.2928 + } 1.2929 + 1.2930 + CallRegisteredLuaMemHook(addr, 4, val, LUAMEMHOOK_WRITE); 1.2931 + return 0; 1.2932 +} 1.2933 + 1.2934 +static int memory_gbromreadbyte(lua_State *L) 1.2935 +{ 1.2936 + u32 addr; 1.2937 + u8 val; 1.2938 + 1.2939 + addr = luaL_checkinteger(L, 1); 1.2940 + if (systemIsRunningGBA()) 1.2941 + { 1.2942 + lua_pushnil(L); 1.2943 + return 1; 1.2944 + } 1.2945 + else 1.2946 + { 1.2947 + val = gbReadROMQuick8(addr); 1.2948 + } 1.2949 + 1.2950 + lua_pushinteger(L, val); 1.2951 + return 1; 1.2952 +} 1.2953 + 1.2954 +static int memory_gbromreadbytesigned(lua_State *L) 1.2955 +{ 1.2956 + u32 addr; 1.2957 + s8 val; 1.2958 + 1.2959 + addr = luaL_checkinteger(L, 1); 1.2960 + if (systemIsRunningGBA()) 1.2961 + { 1.2962 + lua_pushnil(L); 1.2963 + return 1; 1.2964 + } 1.2965 + else 1.2966 + { 1.2967 + val = (s8) gbReadROMQuick8(addr); 1.2968 + } 1.2969 + 1.2970 + lua_pushinteger(L, val); 1.2971 + return 1; 1.2972 +} 1.2973 + 1.2974 +static int memory_gbromreadword(lua_State *L) 1.2975 +{ 1.2976 + u32 addr; 1.2977 + u16 val; 1.2978 + 1.2979 + addr = luaL_checkinteger(L, 1); 1.2980 + if (systemIsRunningGBA()) 1.2981 + { 1.2982 + lua_pushnil(L); 1.2983 + return 1; 1.2984 + } 1.2985 + else 1.2986 + { 1.2987 + val = gbReadROMQuick16(addr); 1.2988 + } 1.2989 + 1.2990 + lua_pushinteger(L, val); 1.2991 + return 1; 1.2992 +} 1.2993 + 1.2994 +static int memory_gbromreadwordsigned(lua_State *L) 1.2995 +{ 1.2996 + u32 addr; 1.2997 + s16 val; 1.2998 + 1.2999 + addr = luaL_checkinteger(L, 1); 1.3000 + if (systemIsRunningGBA()) 1.3001 + { 1.3002 + lua_pushnil(L); 1.3003 + return 1; 1.3004 + } 1.3005 + else 1.3006 + { 1.3007 + val = (s16) gbReadROMQuick16(addr); 1.3008 + } 1.3009 + 1.3010 + lua_pushinteger(L, val); 1.3011 + return 1; 1.3012 +} 1.3013 + 1.3014 +static int memory_gbromreaddword(lua_State *L) 1.3015 +{ 1.3016 + u32 addr; 1.3017 + u32 val; 1.3018 + 1.3019 + addr = luaL_checkinteger(L, 1); 1.3020 + if (systemIsRunningGBA()) 1.3021 + { 1.3022 + lua_pushnil(L); 1.3023 + return 1; 1.3024 + } 1.3025 + else 1.3026 + { 1.3027 + val = gbReadROMQuick32(addr); 1.3028 + } 1.3029 + 1.3030 + // lua_pushinteger doesn't work properly for 32bit system, does it? 1.3031 + if (val >= 0x80000000 && sizeof(int) <= 4) 1.3032 + lua_pushnumber(L, val); 1.3033 + else 1.3034 + lua_pushinteger(L, val); 1.3035 + return 1; 1.3036 +} 1.3037 + 1.3038 +static int memory_gbromreaddwordsigned(lua_State *L) 1.3039 +{ 1.3040 + u32 addr; 1.3041 + s32 val; 1.3042 + 1.3043 + addr = luaL_checkinteger(L, 1); 1.3044 + if (systemIsRunningGBA()) 1.3045 + { 1.3046 + lua_pushnil(L); 1.3047 + return 1; 1.3048 + } 1.3049 + else 1.3050 + { 1.3051 + val = (s32) gbReadROMQuick32(addr); 1.3052 + } 1.3053 + 1.3054 + lua_pushinteger(L, val); 1.3055 + return 1; 1.3056 +} 1.3057 + 1.3058 +static int memory_gbromreadbyterange(lua_State *L) 1.3059 +{ 1.3060 + uint32 address = luaL_checkinteger(L, 1); 1.3061 + int length = luaL_checkinteger(L, 2); 1.3062 + 1.3063 + if (length < 0) 1.3064 + { 1.3065 + address += length; 1.3066 + length = -length; 1.3067 + } 1.3068 + 1.3069 + // push the array 1.3070 + lua_createtable(L, abs(length), 0); 1.3071 + 1.3072 + // put all the values into the (1-based) array 1.3073 + for (int a = address, n = 1; n <= length; a++, n++) 1.3074 + { 1.3075 + unsigned char value; 1.3076 + 1.3077 + if (systemIsRunningGBA()) 1.3078 + { 1.3079 + lua_pushnil(L); 1.3080 + return 1; 1.3081 + } 1.3082 + else 1.3083 + { 1.3084 + value = gbReadROMQuick8(a); 1.3085 + } 1.3086 + 1.3087 + lua_pushinteger(L, value); 1.3088 + lua_rawseti(L, -2, n); 1.3089 + } 1.3090 + 1.3091 + return 1; 1.3092 +} 1.3093 1.3094 // table joypad.get(int which = 1) 1.3095 // 1.3096 // Reads the joypads as inputted by the user. 1.3097 - static int joy_get_internal(lua_State *L, bool reportUp, bool reportDown) 1.3098 - { 1.3099 - // Reads the joypads as inputted by the user 1.3100 - int which = luaL_checkinteger(L, 1); 1.3101 - 1.3102 - if (which < 0 || which > 4) 1.3103 - { 1.3104 - luaL_error(L, "Invalid input port (valid range 0-4, specified %d)", which); 1.3105 - } 1.3106 - 1.3107 - uint32 buttons = systemGetOriginalJoypad(which - 1, false); 1.3108 - 1.3109 - lua_newtable(L); 1.3110 - 1.3111 - int i; 1.3112 - for (i = 0; i < 10; i++) 1.3113 - { 1.3114 - bool pressed = (buttons & (1 << i)) != 0; 1.3115 - if ((pressed && reportDown) || (!pressed && reportUp)) 1.3116 - { 1.3117 - lua_pushboolean(L, pressed); 1.3118 - lua_setfield(L, -2, button_mappings[i]); 1.3119 - } 1.3120 - } 1.3121 - 1.3122 - return 1; 1.3123 - } 1.3124 +static int joy_get_internal(lua_State *L, bool reportUp, bool reportDown) 1.3125 +{ 1.3126 + // Reads the joypads as inputted by the user 1.3127 + int which = luaL_checkinteger(L, 1); 1.3128 + 1.3129 + if (which < 0 || which > 4) 1.3130 + { 1.3131 + luaL_error(L, "Invalid input port (valid range 0-4, specified %d)", which); 1.3132 + } 1.3133 + 1.3134 + uint32 buttons = systemGetOriginalJoypad(which - 1, false); 1.3135 + 1.3136 + lua_newtable(L); 1.3137 + 1.3138 + int i; 1.3139 + for (i = 0; i < 10; i++) 1.3140 + { 1.3141 + bool pressed = (buttons & (1 << i)) != 0; 1.3142 + if ((pressed && reportDown) || (!pressed && reportUp)) 1.3143 + { 1.3144 + lua_pushboolean(L, pressed); 1.3145 + lua_setfield(L, -2, button_mappings[i]); 1.3146 + } 1.3147 + } 1.3148 + 1.3149 + return 1; 1.3150 +} 1.3151 1.3152 // joypad.get(which) 1.3153 // returns a table of every game button, 1.3154 // true meaning currently-held and false meaning not-currently-held 1.3155 // (as of last frame boundary) 1.3156 // this WILL read input from a currently-playing movie 1.3157 - static int joypad_get(lua_State *L) 1.3158 - { 1.3159 - return joy_get_internal(L, true, true); 1.3160 - } 1.3161 +static int joypad_get(lua_State *L) 1.3162 +{ 1.3163 + return joy_get_internal(L, true, true); 1.3164 +} 1.3165 1.3166 // joypad.getdown(which) 1.3167 // returns a table of every game button that is currently held 1.3168 - static int joypad_getdown(lua_State *L) 1.3169 - { 1.3170 - return joy_get_internal(L, false, true); 1.3171 - } 1.3172 +static int joypad_getdown(lua_State *L) 1.3173 +{ 1.3174 + return joy_get_internal(L, false, true); 1.3175 +} 1.3176 1.3177 // joypad.getup(which) 1.3178 // returns a table of every game button that is not currently held 1.3179 - static int joypad_getup(lua_State *L) 1.3180 - { 1.3181 - return joy_get_internal(L, true, false); 1.3182 - } 1.3183 +static int joypad_getup(lua_State *L) 1.3184 +{ 1.3185 + return joy_get_internal(L, true, false); 1.3186 +} 1.3187 1.3188 // joypad.set(int which, table buttons) 1.3189 // 1.3190 @@ -1834,83 +1834,83 @@ 1.3191 // frame advance. The table should have the right 1.3192 1.3193 // keys (no pun intended) set. 1.3194 - static int joypad_set(lua_State *L) 1.3195 - { 1.3196 - // Which joypad we're tampering with 1.3197 - int which = luaL_checkinteger(L, 1); 1.3198 - if (which < 0 || which > 4) 1.3199 - { 1.3200 - luaL_error(L, "Invalid output port (valid range 0-4, specified %d)", which); 1.3201 - } 1.3202 - 1.3203 - if (which == 0) 1.3204 - which = systemGetDefaultJoypad(); 1.3205 - 1.3206 - // And the table of buttons. 1.3207 - luaL_checktype(L, 2, LUA_TTABLE); 1.3208 - 1.3209 - // Set up for taking control of the indicated controller 1.3210 - lua_joypads_used |= 1 << (which - 1); 1.3211 - lua_joypads[which - 1] = 0; 1.3212 - 1.3213 - for (int i = 0; i < 10; i++) 1.3214 - { 1.3215 - const char *name = button_mappings[i]; 1.3216 - lua_getfield(L, 2, name); 1.3217 - if (!lua_isnil(L, -1)) 1.3218 - { 1.3219 - bool pressed = lua_toboolean(L, -1) != 0; 1.3220 - if (pressed) 1.3221 - lua_joypads[which - 1] |= 1 << i; 1.3222 - else 1.3223 - lua_joypads[which - 1] &= ~(1 << i); 1.3224 - } 1.3225 - lua_pop(L, 1); 1.3226 - } 1.3227 - 1.3228 - return 0; 1.3229 - } 1.3230 +static int joypad_set(lua_State *L) 1.3231 +{ 1.3232 + // Which joypad we're tampering with 1.3233 + int which = luaL_checkinteger(L, 1); 1.3234 + if (which < 0 || which > 4) 1.3235 + { 1.3236 + luaL_error(L, "Invalid output port (valid range 0-4, specified %d)", which); 1.3237 + } 1.3238 + 1.3239 + if (which == 0) 1.3240 + which = systemGetDefaultJoypad(); 1.3241 + 1.3242 + // And the table of buttons. 1.3243 + luaL_checktype(L, 2, LUA_TTABLE); 1.3244 + 1.3245 + // Set up for taking control of the indicated controller 1.3246 + lua_joypads_used |= 1 << (which - 1); 1.3247 + lua_joypads[which - 1] = 0; 1.3248 + 1.3249 + for (int i = 0; i < 10; i++) 1.3250 + { 1.3251 + const char *name = button_mappings[i]; 1.3252 + lua_getfield(L, 2, name); 1.3253 + if (!lua_isnil(L, -1)) 1.3254 + { 1.3255 + bool pressed = lua_toboolean(L, -1) != 0; 1.3256 + if (pressed) 1.3257 + lua_joypads[which - 1] |= 1 << i; 1.3258 + else 1.3259 + lua_joypads[which - 1] &= ~(1 << i); 1.3260 + } 1.3261 + lua_pop(L, 1); 1.3262 + } 1.3263 + 1.3264 + return 0; 1.3265 +} 1.3266 1.3267 // Helper function to convert a savestate object to the filename it represents. 1.3268 - static const char *savestateobj2filename(lua_State *L, int offset) 1.3269 - { 1.3270 - // First we get the metatable of the indicated object 1.3271 - int result = lua_getmetatable(L, offset); 1.3272 - 1.3273 - if (!result) 1.3274 - luaL_error(L, "object not a savestate object"); 1.3275 - 1.3276 - // Also check that the type entry is set 1.3277 - lua_getfield(L, -1, "__metatable"); 1.3278 - if (strcmp(lua_tostring(L, -1), "vba Savestate") != 0) 1.3279 - luaL_error(L, "object not a savestate object"); 1.3280 - lua_pop(L, 1); 1.3281 - 1.3282 - // Now, get the field we want 1.3283 - lua_getfield(L, -1, "filename"); 1.3284 - 1.3285 - // Return it 1.3286 - return lua_tostring(L, -1); 1.3287 - } 1.3288 +static const char *savestateobj2filename(lua_State *L, int offset) 1.3289 +{ 1.3290 + // First we get the metatable of the indicated object 1.3291 + int result = lua_getmetatable(L, offset); 1.3292 + 1.3293 + if (!result) 1.3294 + luaL_error(L, "object not a savestate object"); 1.3295 + 1.3296 + // Also check that the type entry is set 1.3297 + lua_getfield(L, -1, "__metatable"); 1.3298 + if (strcmp(lua_tostring(L, -1), "vba Savestate") != 0) 1.3299 + luaL_error(L, "object not a savestate object"); 1.3300 + lua_pop(L, 1); 1.3301 + 1.3302 + // Now, get the field we want 1.3303 + lua_getfield(L, -1, "filename"); 1.3304 + 1.3305 + // Return it 1.3306 + return lua_tostring(L, -1); 1.3307 +} 1.3308 1.3309 // Helper function for garbage collection. 1.3310 - static int savestate_gc(lua_State *L) 1.3311 - { 1.3312 - // The object we're collecting is on top of the stack 1.3313 - lua_getmetatable(L, 1); 1.3314 - 1.3315 - // Get the filename 1.3316 - const char *filename; 1.3317 - lua_getfield(L, -1, "filename"); 1.3318 - filename = lua_tostring(L, -1); 1.3319 - 1.3320 - // Delete the file 1.3321 - remove(filename); 1.3322 - 1.3323 - // We exit, and the garbage collector takes care of the rest. 1.3324 - // Edit: Visual Studio needs a return value anyway, so returns 0. 1.3325 - return 0; 1.3326 - } 1.3327 +static int savestate_gc(lua_State *L) 1.3328 +{ 1.3329 + // The object we're collecting is on top of the stack 1.3330 + lua_getmetatable(L, 1); 1.3331 + 1.3332 + // Get the filename 1.3333 + const char *filename; 1.3334 + lua_getfield(L, -1, "filename"); 1.3335 + filename = lua_tostring(L, -1); 1.3336 + 1.3337 + // Delete the file 1.3338 + remove(filename); 1.3339 + 1.3340 + // We exit, and the garbage collector takes care of the rest. 1.3341 + // Edit: Visual Studio needs a return value anyway, so returns 0. 1.3342 + return 0; 1.3343 +} 1.3344 1.3345 // object savestate.create(int which = nil) 1.3346 // 1.3347 @@ -1918,244 +1918,244 @@ 1.3348 // The object can be associated with a player-accessible savestate 1.3349 1.3350 // ("which" between 1 and 12) or not (which == nil). 1.3351 - static int savestate_create(lua_State *L) 1.3352 - { 1.3353 - int which = -1; 1.3354 - if (lua_gettop(L) >= 1) 1.3355 - { 1.3356 - which = luaL_checkinteger(L, 1); 1.3357 - if (which < 1 || which > 12) 1.3358 - { 1.3359 - luaL_error(L, "invalid player's savestate %d", which); 1.3360 - } 1.3361 - } 1.3362 - 1.3363 - char stateName[2048]; 1.3364 - 1.3365 - if (which > 0) 1.3366 - { 1.3367 - // Find an appropriate filename. This is OS specific, unfortunately. 1.3368 +static int savestate_create(lua_State *L) 1.3369 +{ 1.3370 + int which = -1; 1.3371 + if (lua_gettop(L) >= 1) 1.3372 + { 1.3373 + which = luaL_checkinteger(L, 1); 1.3374 + if (which < 1 || which > 12) 1.3375 + { 1.3376 + luaL_error(L, "invalid player's savestate %d", which); 1.3377 + } 1.3378 + } 1.3379 + 1.3380 + char stateName[2048]; 1.3381 + 1.3382 + if (which > 0) 1.3383 + { 1.3384 + // Find an appropriate filename. This is OS specific, unfortunately. 1.3385 #if (defined(WIN32) && !defined(SDL)) 1.3386 - CString stateName = winGetSavestateFilename(theApp.gameFilename, which); 1.3387 + CString stateName = winGetSavestateFilename(theApp.gameFilename, which); 1.3388 #else 1.3389 - extern char saveDir[2048]; 1.3390 - extern char filename[2048]; 1.3391 - extern char *sdlGetFilename(char *name); 1.3392 - 1.3393 - if (saveDir[0]) 1.3394 - sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename), which); 1.3395 - else 1.3396 - sprintf(stateName, "%s%d.sgm", filename, which); 1.3397 + extern char saveDir[2048]; 1.3398 + extern char filename[2048]; 1.3399 + extern char *sdlGetFilename(char *name); 1.3400 + 1.3401 + if (saveDir[0]) 1.3402 + sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename), which); 1.3403 + else 1.3404 + sprintf(stateName, "%s%d.sgm", filename, which); 1.3405 #endif 1.3406 - } 1.3407 - else 1.3408 - { 1.3409 - char *stateNameTemp = tempnam(NULL, "snlua"); 1.3410 - strcpy(stateName, stateNameTemp); 1.3411 - if (stateNameTemp) 1.3412 - free(stateNameTemp); 1.3413 - } 1.3414 - 1.3415 - // Our "object". We don't care about the type, we just need the memory and GC services. 1.3416 - lua_newuserdata(L, 1); 1.3417 - 1.3418 - // The metatable we use, protected from Lua and contains garbage collection info and stuff. 1.3419 - lua_newtable(L); 1.3420 - 1.3421 - // First, we must protect it 1.3422 - lua_pushstring(L, "vba Savestate"); 1.3423 - lua_setfield(L, -2, "__metatable"); 1.3424 - 1.3425 - // Now we need to save the file itself. 1.3426 - lua_pushstring(L, stateName); 1.3427 - lua_setfield(L, -2, "filename"); 1.3428 - 1.3429 - // If it's an anonymous savestate, we must delete the file from disk should it be gargage collected 1.3430 - if (which < 0) 1.3431 - { 1.3432 - lua_pushcfunction(L, savestate_gc); 1.3433 - lua_setfield(L, -2, "__gc"); 1.3434 - } 1.3435 - 1.3436 - // Set the metatable 1.3437 - lua_setmetatable(L, -2); 1.3438 - 1.3439 - // Awesome. Return the object 1.3440 - return 1; 1.3441 - } 1.3442 + } 1.3443 + else 1.3444 + { 1.3445 + char *stateNameTemp = tempnam(NULL, "snlua"); 1.3446 + strcpy(stateName, stateNameTemp); 1.3447 + if (stateNameTemp) 1.3448 + free(stateNameTemp); 1.3449 + } 1.3450 + 1.3451 + // Our "object". We don't care about the type, we just need the memory and GC services. 1.3452 + lua_newuserdata(L, 1); 1.3453 + 1.3454 + // The metatable we use, protected from Lua and contains garbage collection info and stuff. 1.3455 + lua_newtable(L); 1.3456 + 1.3457 + // First, we must protect it 1.3458 + lua_pushstring(L, "vba Savestate"); 1.3459 + lua_setfield(L, -2, "__metatable"); 1.3460 + 1.3461 + // Now we need to save the file itself. 1.3462 + lua_pushstring(L, stateName); 1.3463 + lua_setfield(L, -2, "filename"); 1.3464 + 1.3465 + // If it's an anonymous savestate, we must delete the file from disk should it be gargage collected 1.3466 + if (which < 0) 1.3467 + { 1.3468 + lua_pushcfunction(L, savestate_gc); 1.3469 + lua_setfield(L, -2, "__gc"); 1.3470 + } 1.3471 + 1.3472 + // Set the metatable 1.3473 + lua_setmetatable(L, -2); 1.3474 + 1.3475 + // Awesome. Return the object 1.3476 + return 1; 1.3477 +} 1.3478 1.3479 // savestate.save(object state) 1.3480 // 1.3481 1.3482 // Saves a state to the given object. 1.3483 - static int savestate_save(lua_State *L) 1.3484 - { 1.3485 - const char *filename = savestateobj2filename(L, 1); 1.3486 - 1.3487 - // printf("saving %s\n", filename); 1.3488 - // Save states are very expensive. They take time. 1.3489 - numTries--; 1.3490 - 1.3491 - bool8 retvalue = theEmulator.emuWriteState ? theEmulator.emuWriteState(filename) : false; 1.3492 - if (!retvalue) 1.3493 - { 1.3494 - // Uh oh 1.3495 - luaL_error(L, "savestate failed"); 1.3496 - } 1.3497 - 1.3498 - return 0; 1.3499 - } 1.3500 +static int savestate_save(lua_State *L) 1.3501 +{ 1.3502 + const char *filename = savestateobj2filename(L, 1); 1.3503 + 1.3504 + // printf("saving %s\n", filename); 1.3505 + // Save states are very expensive. They take time. 1.3506 + numTries--; 1.3507 + 1.3508 + bool8 retvalue = theEmulator.emuWriteState ? theEmulator.emuWriteState(filename) : false; 1.3509 + if (!retvalue) 1.3510 + { 1.3511 + // Uh oh 1.3512 + luaL_error(L, "savestate failed"); 1.3513 + } 1.3514 + 1.3515 + return 0; 1.3516 +} 1.3517 1.3518 // savestate.load(object state) 1.3519 // 1.3520 1.3521 // Loads the given state 1.3522 - static int savestate_load(lua_State *L) 1.3523 - { 1.3524 - const char *filename = savestateobj2filename(L, 1); 1.3525 - 1.3526 - numTries--; 1.3527 - 1.3528 - // printf("loading %s\n", filename); 1.3529 - bool8 retvalue = theEmulator.emuReadState ? theEmulator.emuReadState(filename) : false; 1.3530 - if (!retvalue) 1.3531 - { 1.3532 - // Uh oh 1.3533 - luaL_error(L, "loadstate failed"); 1.3534 - } 1.3535 - 1.3536 - return 0; 1.3537 - } 1.3538 +static int savestate_load(lua_State *L) 1.3539 +{ 1.3540 + const char *filename = savestateobj2filename(L, 1); 1.3541 + 1.3542 + numTries--; 1.3543 + 1.3544 + // printf("loading %s\n", filename); 1.3545 + bool8 retvalue = theEmulator.emuReadState ? theEmulator.emuReadState(filename) : false; 1.3546 + if (!retvalue) 1.3547 + { 1.3548 + // Uh oh 1.3549 + luaL_error(L, "loadstate failed"); 1.3550 + } 1.3551 + 1.3552 + return 0; 1.3553 +} 1.3554 1.3555 // int vba.framecount() 1.3556 // 1.3557 1.3558 // Gets the frame counter for the movie, or the number of frames since last reset. 1.3559 - int vba_framecount(lua_State *L) 1.3560 - { 1.3561 - if (!VBAMovieActive()) 1.3562 - { 1.3563 - lua_pushinteger(L, systemCounters.frameCount); 1.3564 - } 1.3565 - else 1.3566 - { 1.3567 - lua_pushinteger(L, VBAMovieGetFrameCounter()); 1.3568 - } 1.3569 - 1.3570 - return 1; 1.3571 - } 1.3572 +int vba_framecount(lua_State *L) 1.3573 +{ 1.3574 + if (!VBAMovieActive()) 1.3575 + { 1.3576 + lua_pushinteger(L, systemCounters.frameCount); 1.3577 + } 1.3578 + else 1.3579 + { 1.3580 + lua_pushinteger(L, VBAMovieGetFrameCounter()); 1.3581 + } 1.3582 + 1.3583 + return 1; 1.3584 +} 1.3585 1.3586 //string movie.getauthor 1.3587 // 1.3588 1.3589 // returns author info field of .vbm file 1.3590 - int movie_getauthor(lua_State *L) 1.3591 - { 1.3592 - if (!VBAMovieActive()) 1.3593 - { 1.3594 - //lua_pushnil(L); 1.3595 - lua_pushstring(L, ""); 1.3596 - return 1; 1.3597 - } 1.3598 - 1.3599 - lua_pushstring(L, VBAMovieGetAuthorInfo().c_str()); 1.3600 - return 1; 1.3601 - } 1.3602 +int movie_getauthor(lua_State *L) 1.3603 +{ 1.3604 + if (!VBAMovieActive()) 1.3605 + { 1.3606 + //lua_pushnil(L); 1.3607 + lua_pushstring(L, ""); 1.3608 + return 1; 1.3609 + } 1.3610 + 1.3611 + lua_pushstring(L, VBAMovieGetAuthorInfo().c_str()); 1.3612 + return 1; 1.3613 +} 1.3614 1.3615 //string movie.filename 1.3616 - int movie_getfilename(lua_State *L) 1.3617 - { 1.3618 - if (!VBAMovieActive()) 1.3619 - { 1.3620 - //lua_pushnil(L); 1.3621 - lua_pushstring(L, ""); 1.3622 - return 1; 1.3623 - } 1.3624 - 1.3625 - lua_pushstring(L, VBAMovieGetFilename().c_str()); 1.3626 - return 1; 1.3627 - } 1.3628 +int movie_getfilename(lua_State *L) 1.3629 +{ 1.3630 + if (!VBAMovieActive()) 1.3631 + { 1.3632 + //lua_pushnil(L); 1.3633 + lua_pushstring(L, ""); 1.3634 + return 1; 1.3635 + } 1.3636 + 1.3637 + lua_pushstring(L, VBAMovieGetFilename().c_str()); 1.3638 + return 1; 1.3639 +} 1.3640 1.3641 // string movie.mode() 1.3642 // 1.3643 1.3644 // "record", "playback" or nil 1.3645 - int movie_getmode(lua_State *L) 1.3646 - { 1.3647 - assert(!VBAMovieLoading()); 1.3648 - if (!VBAMovieActive()) 1.3649 - { 1.3650 - lua_pushnil(L); 1.3651 - return 1; 1.3652 - } 1.3653 - 1.3654 - if (VBAMovieRecording()) 1.3655 - lua_pushstring(L, "record"); 1.3656 - else 1.3657 - lua_pushstring(L, "playback"); 1.3658 - return 1; 1.3659 - } 1.3660 - 1.3661 - static int movie_rerecordcount(lua_State *L) 1.3662 - { 1.3663 - if (VBAMovieActive()) 1.3664 - lua_pushinteger(L, VBAMovieGetRerecordCount()); 1.3665 - else 1.3666 - lua_pushinteger(L, 0); 1.3667 - return 1; 1.3668 - } 1.3669 - 1.3670 - static int movie_setrerecordcount(lua_State *L) 1.3671 - { 1.3672 - if (VBAMovieActive()) 1.3673 - VBAMovieSetRerecordCount(luaL_checkinteger(L, 1)); 1.3674 - return 0; 1.3675 - } 1.3676 - 1.3677 - static int movie_rerecordcounting(lua_State *L) 1.3678 - { 1.3679 - if (lua_gettop(L) == 0) 1.3680 - luaL_error(L, "no parameters specified"); 1.3681 - 1.3682 - skipRerecords = lua_toboolean(L, 1); 1.3683 - return 0; 1.3684 - } 1.3685 +int movie_getmode(lua_State *L) 1.3686 +{ 1.3687 + assert(!VBAMovieLoading()); 1.3688 + if (!VBAMovieActive()) 1.3689 + { 1.3690 + lua_pushnil(L); 1.3691 + return 1; 1.3692 + } 1.3693 + 1.3694 + if (VBAMovieRecording()) 1.3695 + lua_pushstring(L, "record"); 1.3696 + else 1.3697 + lua_pushstring(L, "playback"); 1.3698 + return 1; 1.3699 +} 1.3700 + 1.3701 +static int movie_rerecordcount(lua_State *L) 1.3702 +{ 1.3703 + if (VBAMovieActive()) 1.3704 + lua_pushinteger(L, VBAMovieGetRerecordCount()); 1.3705 + else 1.3706 + lua_pushinteger(L, 0); 1.3707 + return 1; 1.3708 +} 1.3709 + 1.3710 +static int movie_setrerecordcount(lua_State *L) 1.3711 +{ 1.3712 + if (VBAMovieActive()) 1.3713 + VBAMovieSetRerecordCount(luaL_checkinteger(L, 1)); 1.3714 + return 0; 1.3715 +} 1.3716 + 1.3717 +static int movie_rerecordcounting(lua_State *L) 1.3718 +{ 1.3719 + if (lua_gettop(L) == 0) 1.3720 + luaL_error(L, "no parameters specified"); 1.3721 + 1.3722 + skipRerecords = lua_toboolean(L, 1); 1.3723 + return 0; 1.3724 +} 1.3725 1.3726 // movie.stop() 1.3727 // 1.3728 1.3729 // Stops movie playback/recording. Bombs out if movie is not running. 1.3730 - static int movie_stop(lua_State *L) 1.3731 - { 1.3732 - if (!VBAMovieActive()) 1.3733 - luaL_error(L, "no movie"); 1.3734 - 1.3735 - VBAMovieStop(false); 1.3736 - return 0; 1.3737 - } 1.3738 +static int movie_stop(lua_State *L) 1.3739 +{ 1.3740 + if (!VBAMovieActive()) 1.3741 + luaL_error(L, "no movie"); 1.3742 + 1.3743 + VBAMovieStop(false); 1.3744 + return 0; 1.3745 +} 1.3746 1.3747 #define LUA_SCREEN_WIDTH 256 1.3748 #define LUA_SCREEN_HEIGHT 239 1.3749 1.3750 // Common code by the gui library: make sure the screen array is ready 1.3751 - static void gui_prepare(void) 1.3752 - { 1.3753 - if (!gui_data) 1.3754 - gui_data = (uint8 *)malloc(LUA_SCREEN_WIDTH * LUA_SCREEN_HEIGHT * 4); 1.3755 - if (!gui_used) 1.3756 - memset(gui_data, 0, LUA_SCREEN_WIDTH * LUA_SCREEN_HEIGHT * 4); 1.3757 - gui_used = true; 1.3758 - } 1.3759 +static void gui_prepare(void) 1.3760 +{ 1.3761 + if (!gui_data) 1.3762 + gui_data = (uint8 *)malloc(LUA_SCREEN_WIDTH * LUA_SCREEN_HEIGHT * 4); 1.3763 + if (!gui_used) 1.3764 + memset(gui_data, 0, LUA_SCREEN_WIDTH * LUA_SCREEN_HEIGHT * 4); 1.3765 + gui_used = true; 1.3766 +} 1.3767 1.3768 // pixform for lua graphics 1.3769 #define BUILD_PIXEL_ARGB8888(A, R, G, B) (((int)(A) << 24) | ((int)(R) << 16) | ((int)(G) << 8) | (int)(B)) 1.3770 -#define DECOMPOSE_PIXEL_ARGB8888(PIX, A, R, G, B) \ 1.3771 - { \ 1.3772 - (A) = ((PIX) >> 24) & 0xff; \ 1.3773 - (R) = ((PIX) >> 16) & 0xff; \ 1.3774 - (G) = ((PIX) >> 8) & 0xff; \ 1.3775 - (B) = (PIX) & 0xff; \ 1.3776 - } 1.3777 +#define DECOMPOSE_PIXEL_ARGB8888(PIX, A, R, G, B) \ 1.3778 + { \ 1.3779 + (A) = ((PIX) >> 24) & 0xff; \ 1.3780 + (R) = ((PIX) >> 16) & 0xff; \ 1.3781 + (G) = ((PIX) >> 8) & 0xff; \ 1.3782 + (B) = (PIX) & 0xff; \ 1.3783 + } 1.3784 #define LUA_BUILD_PIXEL BUILD_PIXEL_ARGB8888 1.3785 #define LUA_DECOMPOSE_PIXEL DECOMPOSE_PIXEL_ARGB8888 1.3786 #define LUA_PIXEL_A(PIX) (((PIX) >> 24) & 0xff) 1.3787 @@ -2163,387 +2163,387 @@ 1.3788 #define LUA_PIXEL_G(PIX) (((PIX) >> 8) & 0xff) 1.3789 #define LUA_PIXEL_B(PIX) ((PIX) & 0xff) 1.3790 1.3791 - template<class T> 1.3792 - static void swap(T &one, T &two) 1.3793 - { 1.3794 - T temp = one; 1.3795 - one = two; 1.3796 - two = temp; 1.3797 - } 1.3798 +template<class T> 1.3799 +static void swap(T &one, T &two) 1.3800 +{ 1.3801 + T temp = one; 1.3802 + one = two; 1.3803 + two = temp; 1.3804 +} 1.3805 1.3806 // write a pixel to buffer 1.3807 - static inline void blend32(uint32 *dstPixel, uint32 colour) 1.3808 - { 1.3809 - uint8 *dst = (uint8 *)dstPixel; 1.3810 - int a, r, g, b; 1.3811 - LUA_DECOMPOSE_PIXEL(colour, a, r, g, b); 1.3812 - 1.3813 - if (a == 255 || dst[3] == 0) 1.3814 - { 1.3815 - // direct copy 1.3816 - *(uint32 *) (dst) = colour; 1.3817 - } 1.3818 - else if (a == 0) 1.3819 - { 1.3820 - // do not copy 1.3821 - } 1.3822 - else 1.3823 - { 1.3824 - // alpha-blending 1.3825 - int a_dst = ((255 - a) * dst[3] + 128) / 255; 1.3826 - int a_new = a + a_dst; 1.3827 - 1.3828 - dst[0] = (uint8) (((dst[0] * a_dst + b * a) + (a_new / 2)) / a_new); 1.3829 - dst[1] = (uint8) (((dst[1] * a_dst + g * a) + (a_new / 2)) / a_new); 1.3830 - dst[2] = (uint8) (((dst[2] * a_dst + r * a) + (a_new / 2)) / a_new); 1.3831 - dst[3] = (uint8) a_new; 1.3832 - } 1.3833 - } 1.3834 +static inline void blend32(uint32 *dstPixel, uint32 colour) 1.3835 +{ 1.3836 + uint8 *dst = (uint8 *)dstPixel; 1.3837 + int a, r, g, b; 1.3838 + LUA_DECOMPOSE_PIXEL(colour, a, r, g, b); 1.3839 + 1.3840 + if (a == 255 || dst[3] == 0) 1.3841 + { 1.3842 + // direct copy 1.3843 + *(uint32 *) (dst) = colour; 1.3844 + } 1.3845 + else if (a == 0) 1.3846 + { 1.3847 + // do not copy 1.3848 + } 1.3849 + else 1.3850 + { 1.3851 + // alpha-blending 1.3852 + int a_dst = ((255 - a) * dst[3] + 128) / 255; 1.3853 + int a_new = a + a_dst; 1.3854 + 1.3855 + dst[0] = (uint8) (((dst[0] * a_dst + b * a) + (a_new / 2)) / a_new); 1.3856 + dst[1] = (uint8) (((dst[1] * a_dst + g * a) + (a_new / 2)) / a_new); 1.3857 + dst[2] = (uint8) (((dst[2] * a_dst + r * a) + (a_new / 2)) / a_new); 1.3858 + dst[3] = (uint8) a_new; 1.3859 + } 1.3860 +} 1.3861 1.3862 // check if a pixel is in the lua canvas 1.3863 - static inline bool gui_check_boundary(int x, int y) 1.3864 - { 1.3865 - return !(x < 0 || x >= LUA_SCREEN_WIDTH || y < 0 || y >= LUA_SCREEN_HEIGHT); 1.3866 - } 1.3867 +static inline bool gui_check_boundary(int x, int y) 1.3868 +{ 1.3869 + return !(x < 0 || x >= LUA_SCREEN_WIDTH || y < 0 || y >= LUA_SCREEN_HEIGHT); 1.3870 +} 1.3871 1.3872 // check if any part of a box is in the lua canvas 1.3873 - static inline bool gui_checkbox(int x1, int y1, int x2, int y2) 1.3874 - { 1.3875 - if ((x1 < 0 && x2 < 0) 1.3876 - || (x1 >= LUA_SCREEN_WIDTH && x2 >= LUA_SCREEN_WIDTH) 1.3877 - || (y1 < 0 && y2 < 0) 1.3878 - || (y1 >= LUA_SCREEN_HEIGHT && y2 >= LUA_SCREEN_HEIGHT)) 1.3879 - return false; 1.3880 - return true; 1.3881 - } 1.3882 +static inline bool gui_checkbox(int x1, int y1, int x2, int y2) 1.3883 +{ 1.3884 + if ((x1 < 0 && x2 < 0) 1.3885 + || (x1 >= LUA_SCREEN_WIDTH && x2 >= LUA_SCREEN_WIDTH) 1.3886 + || (y1 < 0 && y2 < 0) 1.3887 + || (y1 >= LUA_SCREEN_HEIGHT && y2 >= LUA_SCREEN_HEIGHT)) 1.3888 + return false; 1.3889 + return true; 1.3890 +} 1.3891 1.3892 // write a pixel to gui_data (do not check boundaries for speedup) 1.3893 - static inline void gui_drawpixel_fast(int x, int y, uint32 colour) 1.3894 - { 1.3895 - //gui_prepare(); 1.3896 - blend32((uint32 *) &gui_data[(y * LUA_SCREEN_WIDTH + x) * 4], colour); 1.3897 - } 1.3898 +static inline void gui_drawpixel_fast(int x, int y, uint32 colour) 1.3899 +{ 1.3900 + //gui_prepare(); 1.3901 + blend32((uint32 *) &gui_data[(y * LUA_SCREEN_WIDTH + x) * 4], colour); 1.3902 +} 1.3903 1.3904 // write a pixel to gui_data (check boundaries) 1.3905 - static inline void gui_drawpixel_internal(int x, int y, uint32 colour) 1.3906 - { 1.3907 - //gui_prepare(); 1.3908 - if (gui_check_boundary(x, y)) 1.3909 - gui_drawpixel_fast(x, y, colour); 1.3910 - } 1.3911 +static inline void gui_drawpixel_internal(int x, int y, uint32 colour) 1.3912 +{ 1.3913 + //gui_prepare(); 1.3914 + if (gui_check_boundary(x, y)) 1.3915 + gui_drawpixel_fast(x, y, colour); 1.3916 +} 1.3917 1.3918 // draw a line on gui_data (checks boundaries) 1.3919 - static void gui_drawline_internal(int x1, int y1, int x2, int y2, bool lastPixel, uint32 colour) 1.3920 - { 1.3921 - //gui_prepare(); 1.3922 - // Note: New version of Bresenham's Line Algorithm 1.3923 - // 1.3924 - // 1.3925 - // http://groups.google.co.jp/group/rec.games.roguelike.development/browse_thread/thread/345f4c42c3b25858/29e07a3af3a450e6?show_docid=29e07a3af3a450e6 1.3926 - int swappedx = 0; 1.3927 - int swappedy = 0; 1.3928 - 1.3929 - int xtemp = x1 - x2; 1.3930 - int ytemp = y1 - y2; 1.3931 - if (xtemp == 0 && ytemp == 0) 1.3932 - { 1.3933 - gui_drawpixel_internal(x1, y1, colour); 1.3934 - return; 1.3935 - } 1.3936 - 1.3937 - if (xtemp < 0) 1.3938 - { 1.3939 - xtemp = -xtemp; 1.3940 - swappedx = 1; 1.3941 - } 1.3942 - 1.3943 - if (ytemp < 0) 1.3944 - { 1.3945 - ytemp = -ytemp; 1.3946 - swappedy = 1; 1.3947 - } 1.3948 - 1.3949 - int delta_x = xtemp << 1; 1.3950 - int delta_y = ytemp << 1; 1.3951 - 1.3952 - signed char ix = x1 > x2 ? 1 : -1; 1.3953 - signed char iy = y1 > y2 ? 1 : -1; 1.3954 - 1.3955 - if (lastPixel) 1.3956 - gui_drawpixel_internal(x2, y2, colour); 1.3957 - 1.3958 - if (delta_x >= delta_y) 1.3959 - { 1.3960 - int error = delta_y - (delta_x >> 1); 1.3961 - 1.3962 - while (x2 != x1) 1.3963 - { 1.3964 - if (error == 0 && !swappedx) 1.3965 - gui_drawpixel_internal(x2 + ix, y2, colour); 1.3966 - if (error >= 0) 1.3967 - { 1.3968 - if (error || (ix > 0)) 1.3969 - { 1.3970 - y2 += iy; 1.3971 - error -= delta_x; 1.3972 - } 1.3973 - } 1.3974 - 1.3975 - x2 += ix; 1.3976 - gui_drawpixel_internal(x2, y2, colour); 1.3977 - if (error == 0 && swappedx) 1.3978 - gui_drawpixel_internal(x2, y2 + iy, colour); 1.3979 - error += delta_y; 1.3980 - } 1.3981 - } 1.3982 - else 1.3983 - { 1.3984 - int error = delta_x - (delta_y >> 1); 1.3985 - 1.3986 - while (y2 != y1) 1.3987 - { 1.3988 - if (error == 0 && !swappedy) 1.3989 - gui_drawpixel_internal(x2, y2 + iy, colour); 1.3990 - if (error >= 0) 1.3991 - { 1.3992 - if (error || (iy > 0)) 1.3993 - { 1.3994 - x2 += ix; 1.3995 - error -= delta_y; 1.3996 - } 1.3997 - } 1.3998 - 1.3999 - y2 += iy; 1.4000 - gui_drawpixel_internal(x2, y2, colour); 1.4001 - if (error == 0 && swappedy) 1.4002 - gui_drawpixel_internal(x2 + ix, y2, colour); 1.4003 - error += delta_x; 1.4004 - } 1.4005 - } 1.4006 - } 1.4007 +static void gui_drawline_internal(int x1, int y1, int x2, int y2, bool lastPixel, uint32 colour) 1.4008 +{ 1.4009 + //gui_prepare(); 1.4010 + // Note: New version of Bresenham's Line Algorithm 1.4011 + // 1.4012 + // 1.4013 + // http://groups.google.co.jp/group/rec.games.roguelike.development/browse_thread/thread/345f4c42c3b25858/29e07a3af3a450e6?show_docid=29e07a3af3a450e6 1.4014 + int swappedx = 0; 1.4015 + int swappedy = 0; 1.4016 + 1.4017 + int xtemp = x1 - x2; 1.4018 + int ytemp = y1 - y2; 1.4019 + if (xtemp == 0 && ytemp == 0) 1.4020 + { 1.4021 + gui_drawpixel_internal(x1, y1, colour); 1.4022 + return; 1.4023 + } 1.4024 + 1.4025 + if (xtemp < 0) 1.4026 + { 1.4027 + xtemp = -xtemp; 1.4028 + swappedx = 1; 1.4029 + } 1.4030 + 1.4031 + if (ytemp < 0) 1.4032 + { 1.4033 + ytemp = -ytemp; 1.4034 + swappedy = 1; 1.4035 + } 1.4036 + 1.4037 + int delta_x = xtemp << 1; 1.4038 + int delta_y = ytemp << 1; 1.4039 + 1.4040 + signed char ix = x1 > x2 ? 1 : -1; 1.4041 + signed char iy = y1 > y2 ? 1 : -1; 1.4042 + 1.4043 + if (lastPixel) 1.4044 + gui_drawpixel_internal(x2, y2, colour); 1.4045 + 1.4046 + if (delta_x >= delta_y) 1.4047 + { 1.4048 + int error = delta_y - (delta_x >> 1); 1.4049 + 1.4050 + while (x2 != x1) 1.4051 + { 1.4052 + if (error == 0 && !swappedx) 1.4053 + gui_drawpixel_internal(x2 + ix, y2, colour); 1.4054 + if (error >= 0) 1.4055 + { 1.4056 + if (error || (ix > 0)) 1.4057 + { 1.4058 + y2 += iy; 1.4059 + error -= delta_x; 1.4060 + } 1.4061 + } 1.4062 + 1.4063 + x2 += ix; 1.4064 + gui_drawpixel_internal(x2, y2, colour); 1.4065 + if (error == 0 && swappedx) 1.4066 + gui_drawpixel_internal(x2, y2 + iy, colour); 1.4067 + error += delta_y; 1.4068 + } 1.4069 + } 1.4070 + else 1.4071 + { 1.4072 + int error = delta_x - (delta_y >> 1); 1.4073 + 1.4074 + while (y2 != y1) 1.4075 + { 1.4076 + if (error == 0 && !swappedy) 1.4077 + gui_drawpixel_internal(x2, y2 + iy, colour); 1.4078 + if (error >= 0) 1.4079 + { 1.4080 + if (error || (iy > 0)) 1.4081 + { 1.4082 + x2 += ix; 1.4083 + error -= delta_y; 1.4084 + } 1.4085 + } 1.4086 + 1.4087 + y2 += iy; 1.4088 + gui_drawpixel_internal(x2, y2, colour); 1.4089 + if (error == 0 && swappedy) 1.4090 + gui_drawpixel_internal(x2 + ix, y2, colour); 1.4091 + error += delta_x; 1.4092 + } 1.4093 + } 1.4094 +} 1.4095 1.4096 // draw a rect on gui_data 1.4097 - static void gui_drawbox_internal(int x1, int y1, int x2, int y2, uint32 colour) 1.4098 - { 1.4099 - if (x1 > x2) 1.4100 - std::swap(x1, x2); 1.4101 - if (y1 > y2) 1.4102 - std::swap(y1, y2); 1.4103 - if (x1 < 0) 1.4104 - x1 = -1; 1.4105 - if (y1 < 0) 1.4106 - y1 = -1; 1.4107 - if (x2 >= LUA_SCREEN_WIDTH) 1.4108 - x2 = LUA_SCREEN_WIDTH; 1.4109 - if (y2 >= LUA_SCREEN_HEIGHT) 1.4110 - y2 = LUA_SCREEN_HEIGHT; 1.4111 - 1.4112 - if (!gui_checkbox(x1, y1, x2, y2)) 1.4113 - return; 1.4114 - 1.4115 - //gui_prepare(); 1.4116 - gui_drawline_internal(x1, y1, x2, y1, true, colour); 1.4117 - gui_drawline_internal(x1, y2, x2, y2, true, colour); 1.4118 - gui_drawline_internal(x1, y1, x1, y2, true, colour); 1.4119 - gui_drawline_internal(x2, y1, x2, y2, true, colour); 1.4120 - } 1.4121 +static void gui_drawbox_internal(int x1, int y1, int x2, int y2, uint32 colour) 1.4122 +{ 1.4123 + if (x1 > x2) 1.4124 + std::swap(x1, x2); 1.4125 + if (y1 > y2) 1.4126 + std::swap(y1, y2); 1.4127 + if (x1 < 0) 1.4128 + x1 = -1; 1.4129 + if (y1 < 0) 1.4130 + y1 = -1; 1.4131 + if (x2 >= LUA_SCREEN_WIDTH) 1.4132 + x2 = LUA_SCREEN_WIDTH; 1.4133 + if (y2 >= LUA_SCREEN_HEIGHT) 1.4134 + y2 = LUA_SCREEN_HEIGHT; 1.4135 + 1.4136 + if (!gui_checkbox(x1, y1, x2, y2)) 1.4137 + return; 1.4138 + 1.4139 + //gui_prepare(); 1.4140 + gui_drawline_internal(x1, y1, x2, y1, true, colour); 1.4141 + gui_drawline_internal(x1, y2, x2, y2, true, colour); 1.4142 + gui_drawline_internal(x1, y1, x1, y2, true, colour); 1.4143 + gui_drawline_internal(x2, y1, x2, y2, true, colour); 1.4144 +} 1.4145 1.4146 // draw a circle on gui_data 1.4147 - static void gui_drawcircle_internal(int x0, int y0, int radius, uint32 colour) 1.4148 - { 1.4149 - //gui_prepare(); 1.4150 - if (radius < 0) 1.4151 - radius = -radius; 1.4152 - if (radius == 0) 1.4153 - return; 1.4154 - if (radius == 1) 1.4155 - { 1.4156 - gui_drawpixel_internal(x0, y0, colour); 1.4157 - return; 1.4158 - } 1.4159 - 1.4160 - // http://en.wikipedia.org/wiki/Midpoint_circle_algorithm 1.4161 - int f = 1 - radius; 1.4162 - int ddF_x = 1; 1.4163 - int ddF_y = -2 * radius; 1.4164 - int x = 0; 1.4165 - int y = radius; 1.4166 - 1.4167 - if (!gui_checkbox(x0 - radius, y0 - radius, x0 + radius, y0 + radius)) 1.4168 - return; 1.4169 - 1.4170 - gui_drawpixel_internal(x0, y0 + radius, colour); 1.4171 - gui_drawpixel_internal(x0, y0 - radius, colour); 1.4172 - gui_drawpixel_internal(x0 + radius, y0, colour); 1.4173 - gui_drawpixel_internal(x0 - radius, y0, colour); 1.4174 - 1.4175 - // same pixel shouldn't be drawed twice, 1.4176 - // because each pixel has opacity. 1.4177 - // so now the routine gets ugly. 1.4178 - while (true) 1.4179 - { 1.4180 - assert(ddF_x == 2 * x + 1); 1.4181 - assert(ddF_y == -2 * y); 1.4182 - assert(f == x * x + y * y - radius * radius + 2 * x - y + 1); 1.4183 - if (f >= 0) 1.4184 - { 1.4185 - y--; 1.4186 - ddF_y += 2; 1.4187 - f += ddF_y; 1.4188 - } 1.4189 - 1.4190 - x++; 1.4191 - ddF_x += 2; 1.4192 - f += ddF_x; 1.4193 - if (x < y) 1.4194 - { 1.4195 - gui_drawpixel_internal(x0 + x, y0 + y, colour); 1.4196 - gui_drawpixel_internal(x0 - x, y0 + y, colour); 1.4197 - gui_drawpixel_internal(x0 + x, y0 - y, colour); 1.4198 - gui_drawpixel_internal(x0 - x, y0 - y, colour); 1.4199 - gui_drawpixel_internal(x0 + y, y0 + x, colour); 1.4200 - gui_drawpixel_internal(x0 - y, y0 + x, colour); 1.4201 - gui_drawpixel_internal(x0 + y, y0 - x, colour); 1.4202 - gui_drawpixel_internal(x0 - y, y0 - x, colour); 1.4203 - } 1.4204 - else if (x == y) 1.4205 - { 1.4206 - gui_drawpixel_internal(x0 + x, y0 + y, colour); 1.4207 - gui_drawpixel_internal(x0 - x, y0 + y, colour); 1.4208 - gui_drawpixel_internal(x0 + x, y0 - y, colour); 1.4209 - gui_drawpixel_internal(x0 - x, y0 - y, colour); 1.4210 - break; 1.4211 - } 1.4212 - else 1.4213 - break; 1.4214 - } 1.4215 - } 1.4216 +static void gui_drawcircle_internal(int x0, int y0, int radius, uint32 colour) 1.4217 +{ 1.4218 + //gui_prepare(); 1.4219 + if (radius < 0) 1.4220 + radius = -radius; 1.4221 + if (radius == 0) 1.4222 + return; 1.4223 + if (radius == 1) 1.4224 + { 1.4225 + gui_drawpixel_internal(x0, y0, colour); 1.4226 + return; 1.4227 + } 1.4228 + 1.4229 + // http://en.wikipedia.org/wiki/Midpoint_circle_algorithm 1.4230 + int f = 1 - radius; 1.4231 + int ddF_x = 1; 1.4232 + int ddF_y = -2 * radius; 1.4233 + int x = 0; 1.4234 + int y = radius; 1.4235 + 1.4236 + if (!gui_checkbox(x0 - radius, y0 - radius, x0 + radius, y0 + radius)) 1.4237 + return; 1.4238 + 1.4239 + gui_drawpixel_internal(x0, y0 + radius, colour); 1.4240 + gui_drawpixel_internal(x0, y0 - radius, colour); 1.4241 + gui_drawpixel_internal(x0 + radius, y0, colour); 1.4242 + gui_drawpixel_internal(x0 - radius, y0, colour); 1.4243 + 1.4244 + // same pixel shouldn't be drawed twice, 1.4245 + // because each pixel has opacity. 1.4246 + // so now the routine gets ugly. 1.4247 + while (true) 1.4248 + { 1.4249 + assert(ddF_x == 2 * x + 1); 1.4250 + assert(ddF_y == -2 * y); 1.4251 + assert(f == x * x + y * y - radius * radius + 2 * x - y + 1); 1.4252 + if (f >= 0) 1.4253 + { 1.4254 + y--; 1.4255 + ddF_y += 2; 1.4256 + f += ddF_y; 1.4257 + } 1.4258 + 1.4259 + x++; 1.4260 + ddF_x += 2; 1.4261 + f += ddF_x; 1.4262 + if (x < y) 1.4263 + { 1.4264 + gui_drawpixel_internal(x0 + x, y0 + y, colour); 1.4265 + gui_drawpixel_internal(x0 - x, y0 + y, colour); 1.4266 + gui_drawpixel_internal(x0 + x, y0 - y, colour); 1.4267 + gui_drawpixel_internal(x0 - x, y0 - y, colour); 1.4268 + gui_drawpixel_internal(x0 + y, y0 + x, colour); 1.4269 + gui_drawpixel_internal(x0 - y, y0 + x, colour); 1.4270 + gui_drawpixel_internal(x0 + y, y0 - x, colour); 1.4271 + gui_drawpixel_internal(x0 - y, y0 - x, colour); 1.4272 + } 1.4273 + else if (x == y) 1.4274 + { 1.4275 + gui_drawpixel_internal(x0 + x, y0 + y, colour); 1.4276 + gui_drawpixel_internal(x0 - x, y0 + y, colour); 1.4277 + gui_drawpixel_internal(x0 + x, y0 - y, colour); 1.4278 + gui_drawpixel_internal(x0 - x, y0 - y, colour); 1.4279 + break; 1.4280 + } 1.4281 + else 1.4282 + break; 1.4283 + } 1.4284 +} 1.4285 1.4286 // draw fill rect on gui_data 1.4287 - static void gui_fillbox_internal(int x1, int y1, int x2, int y2, uint32 colour) 1.4288 - { 1.4289 - if (x1 > x2) 1.4290 - std::swap(x1, x2); 1.4291 - if (y1 > y2) 1.4292 - std::swap(y1, y2); 1.4293 - if (x1 < 0) 1.4294 - x1 = 0; 1.4295 - if (y1 < 0) 1.4296 - y1 = 0; 1.4297 - if (x2 >= LUA_SCREEN_WIDTH) 1.4298 - x2 = LUA_SCREEN_WIDTH - 1; 1.4299 - if (y2 >= LUA_SCREEN_HEIGHT) 1.4300 - y2 = LUA_SCREEN_HEIGHT - 1; 1.4301 - 1.4302 - //gui_prepare(); 1.4303 - int ix, iy; 1.4304 - for (iy = y1; iy <= y2; iy++) 1.4305 - { 1.4306 - for (ix = x1; ix <= x2; ix++) 1.4307 - { 1.4308 - gui_drawpixel_fast(ix, iy, colour); 1.4309 - } 1.4310 - } 1.4311 - } 1.4312 +static void gui_fillbox_internal(int x1, int y1, int x2, int y2, uint32 colour) 1.4313 +{ 1.4314 + if (x1 > x2) 1.4315 + std::swap(x1, x2); 1.4316 + if (y1 > y2) 1.4317 + std::swap(y1, y2); 1.4318 + if (x1 < 0) 1.4319 + x1 = 0; 1.4320 + if (y1 < 0) 1.4321 + y1 = 0; 1.4322 + if (x2 >= LUA_SCREEN_WIDTH) 1.4323 + x2 = LUA_SCREEN_WIDTH - 1; 1.4324 + if (y2 >= LUA_SCREEN_HEIGHT) 1.4325 + y2 = LUA_SCREEN_HEIGHT - 1; 1.4326 + 1.4327 + //gui_prepare(); 1.4328 + int ix, iy; 1.4329 + for (iy = y1; iy <= y2; iy++) 1.4330 + { 1.4331 + for (ix = x1; ix <= x2; ix++) 1.4332 + { 1.4333 + gui_drawpixel_fast(ix, iy, colour); 1.4334 + } 1.4335 + } 1.4336 +} 1.4337 1.4338 // fill a circle on gui_data 1.4339 - static void gui_fillcircle_internal(int x0, int y0, int radius, uint32 colour) 1.4340 - { 1.4341 - //gui_prepare(); 1.4342 - if (radius < 0) 1.4343 - radius = -radius; 1.4344 - if (radius == 0) 1.4345 - return; 1.4346 - if (radius == 1) 1.4347 - { 1.4348 - gui_drawpixel_internal(x0, y0, colour); 1.4349 - return; 1.4350 - } 1.4351 - 1.4352 - // http://en.wikipedia.org/wiki/Midpoint_circle_algorithm 1.4353 - int f = 1 - radius; 1.4354 - int ddF_x = 1; 1.4355 - int ddF_y = -2 * radius; 1.4356 - int x = 0; 1.4357 - int y = radius; 1.4358 - 1.4359 - if (!gui_checkbox(x0 - radius, y0 - radius, x0 + radius, y0 + radius)) 1.4360 - return; 1.4361 - 1.4362 - gui_drawline_internal(x0, y0 - radius, x0, y0 + radius, true, colour); 1.4363 - 1.4364 - while (true) 1.4365 - { 1.4366 - assert(ddF_x == 2 * x + 1); 1.4367 - assert(ddF_y == -2 * y); 1.4368 - assert(f == x * x + y * y - radius * radius + 2 * x - y + 1); 1.4369 - if (f >= 0) 1.4370 - { 1.4371 - y--; 1.4372 - ddF_y += 2; 1.4373 - f += ddF_y; 1.4374 - } 1.4375 - 1.4376 - x++; 1.4377 - ddF_x += 2; 1.4378 - f += ddF_x; 1.4379 - 1.4380 - if (x < y) 1.4381 - { 1.4382 - gui_drawline_internal(x0 + x, y0 - y, x0 + x, y0 + y, true, colour); 1.4383 - gui_drawline_internal(x0 - x, y0 - y, x0 - x, y0 + y, true, colour); 1.4384 - if (f >= 0) 1.4385 - { 1.4386 - gui_drawline_internal(x0 + y, y0 - x, x0 + y, y0 + x, true, colour); 1.4387 - gui_drawline_internal(x0 - y, y0 - x, x0 - y, y0 + x, true, colour); 1.4388 - } 1.4389 - } 1.4390 - else if (x == y) 1.4391 - { 1.4392 - gui_drawline_internal(x0 + x, y0 - y, x0 + x, y0 + y, true, colour); 1.4393 - gui_drawline_internal(x0 - x, y0 - y, x0 - x, y0 + y, true, colour); 1.4394 - break; 1.4395 - } 1.4396 - else 1.4397 - break; 1.4398 - } 1.4399 - } 1.4400 +static void gui_fillcircle_internal(int x0, int y0, int radius, uint32 colour) 1.4401 +{ 1.4402 + //gui_prepare(); 1.4403 + if (radius < 0) 1.4404 + radius = -radius; 1.4405 + if (radius == 0) 1.4406 + return; 1.4407 + if (radius == 1) 1.4408 + { 1.4409 + gui_drawpixel_internal(x0, y0, colour); 1.4410 + return; 1.4411 + } 1.4412 + 1.4413 + // http://en.wikipedia.org/wiki/Midpoint_circle_algorithm 1.4414 + int f = 1 - radius; 1.4415 + int ddF_x = 1; 1.4416 + int ddF_y = -2 * radius; 1.4417 + int x = 0; 1.4418 + int y = radius; 1.4419 + 1.4420 + if (!gui_checkbox(x0 - radius, y0 - radius, x0 + radius, y0 + radius)) 1.4421 + return; 1.4422 + 1.4423 + gui_drawline_internal(x0, y0 - radius, x0, y0 + radius, true, colour); 1.4424 + 1.4425 + while (true) 1.4426 + { 1.4427 + assert(ddF_x == 2 * x + 1); 1.4428 + assert(ddF_y == -2 * y); 1.4429 + assert(f == x * x + y * y - radius * radius + 2 * x - y + 1); 1.4430 + if (f >= 0) 1.4431 + { 1.4432 + y--; 1.4433 + ddF_y += 2; 1.4434 + f += ddF_y; 1.4435 + } 1.4436 + 1.4437 + x++; 1.4438 + ddF_x += 2; 1.4439 + f += ddF_x; 1.4440 + 1.4441 + if (x < y) 1.4442 + { 1.4443 + gui_drawline_internal(x0 + x, y0 - y, x0 + x, y0 + y, true, colour); 1.4444 + gui_drawline_internal(x0 - x, y0 - y, x0 - x, y0 + y, true, colour); 1.4445 + if (f >= 0) 1.4446 + { 1.4447 + gui_drawline_internal(x0 + y, y0 - x, x0 + y, y0 + x, true, colour); 1.4448 + gui_drawline_internal(x0 - y, y0 - x, x0 - y, y0 + x, true, colour); 1.4449 + } 1.4450 + } 1.4451 + else if (x == y) 1.4452 + { 1.4453 + gui_drawline_internal(x0 + x, y0 - y, x0 + x, y0 + y, true, colour); 1.4454 + gui_drawline_internal(x0 - x, y0 - y, x0 - x, y0 + y, true, colour); 1.4455 + break; 1.4456 + } 1.4457 + else 1.4458 + break; 1.4459 + } 1.4460 +} 1.4461 1.4462 // Helper for a simple hex parser 1.4463 - static int hex2int(lua_State *L, char c) 1.4464 - { 1.4465 - if (c >= '0' && c <= '9') 1.4466 - return c - '0'; 1.4467 - if (c >= 'a' && c <= 'f') 1.4468 - return c - 'a' + 10; 1.4469 - if (c >= 'A' && c <= 'F') 1.4470 - return c - 'A' + 10; 1.4471 - return luaL_error(L, "invalid hex in colour"); 1.4472 - } 1.4473 - 1.4474 - static const struct ColorMapping 1.4475 - { 1.4476 - const char *name; 1.4477 - int value; 1.4478 - } 1.4479 - s_colorMapping[] = 1.4480 - { 1.4481 - { "white", 0xFFFFFFFF }, 1.4482 - { "black", 0x000000FF }, 1.4483 - { "clear", 0x00000000 }, 1.4484 - { "gray", 0x7F7F7FFF }, 1.4485 - { "grey", 0x7F7F7FFF }, 1.4486 - { "red", 0xFF0000FF }, 1.4487 - { "orange", 0xFF7F00FF }, 1.4488 - { "yellow", 0xFFFF00FF }, 1.4489 - { "chartreuse", 0x7FFF00FF }, 1.4490 - { "green", 0x00FF00FF }, 1.4491 - { "teal", 0x00FF7FFF }, 1.4492 - { "cyan", 0x00FFFFFF }, 1.4493 - { "blue", 0x0000FFFF }, 1.4494 - { "purple", 0x7F00FFFF }, 1.4495 - { "magenta", 0xFF00FFFF }, 1.4496 - }; 1.4497 +static int hex2int(lua_State *L, char c) 1.4498 +{ 1.4499 + if (c >= '0' && c <= '9') 1.4500 + return c - '0'; 1.4501 + if (c >= 'a' && c <= 'f') 1.4502 + return c - 'a' + 10; 1.4503 + if (c >= 'A' && c <= 'F') 1.4504 + return c - 'A' + 10; 1.4505 + return luaL_error(L, "invalid hex in colour"); 1.4506 +} 1.4507 + 1.4508 +static const struct ColorMapping 1.4509 +{ 1.4510 + const char *name; 1.4511 + int value; 1.4512 +} 1.4513 + s_colorMapping[] = 1.4514 + { 1.4515 + { "white", 0xFFFFFFFF }, 1.4516 + { "black", 0x000000FF }, 1.4517 + { "clear", 0x00000000 }, 1.4518 + { "gray", 0x7F7F7FFF }, 1.4519 + { "grey", 0x7F7F7FFF }, 1.4520 + { "red", 0xFF0000FF }, 1.4521 + { "orange", 0xFF7F00FF }, 1.4522 + { "yellow", 0xFFFF00FF }, 1.4523 + { "chartreuse", 0x7FFF00FF }, 1.4524 + { "green", 0x00FF00FF }, 1.4525 + { "teal", 0x00FF7FFF }, 1.4526 + { "cyan", 0x00FFFFFF }, 1.4527 + { "blue", 0x0000FFFF }, 1.4528 + { "purple", 0x7F00FFFF }, 1.4529 + { "magenta", 0xFF00FFFF }, 1.4530 + }; 1.4531 1.4532 /** 1.4533 * Converts an integer or a string on the stack at the given 1.4534 @@ -2551,358 +2551,358 @@ 1.4535 * The user may construct their own RGB value, given a simple colour name, 1.4536 * or an HTML-style "#09abcd" colour. 16 bit reduction doesn't occur at this time. 1.4537 */ 1.4538 - static inline bool str2colour(uint32 *colour, lua_State *L, const char *str) 1.4539 - { 1.4540 - if (str[0] == '#') 1.4541 - { 1.4542 - int color; 1.4543 - sscanf(str + 1, "%X", &color); 1.4544 - 1.4545 - int len = strlen(str + 1); 1.4546 - int missing = max(0, 8 - len); 1.4547 - color <<= missing << 2; 1.4548 - if (missing >= 2) 1.4549 - color |= 0xFF; 1.4550 - *colour = color; 1.4551 - return true; 1.4552 - } 1.4553 - else 1.4554 - { 1.4555 - if (!strnicmp(str, "rand", 4)) 1.4556 - { 1.4557 - *colour = gen_rand32() | 0xFF; //((rand()*255/RAND_MAX) << 8) | ((rand()*255/RAND_MAX) << 16) | 1.4558 - // ((rand()*255/RAND_MAX) << 24) | 0xFF; 1.4559 - return true; 1.4560 - } 1.4561 - 1.4562 - for (int i = 0; i < sizeof(s_colorMapping) / sizeof(*s_colorMapping); i++) 1.4563 - { 1.4564 - if (!stricmp(str, s_colorMapping[i].name)) 1.4565 - { 1.4566 - *colour = s_colorMapping[i].value; 1.4567 - return true; 1.4568 - } 1.4569 - } 1.4570 - } 1.4571 - 1.4572 - return false; 1.4573 - } 1.4574 - 1.4575 - static inline uint32 gui_getcolour_wrapped(lua_State *L, int offset, bool hasDefaultValue, uint32 defaultColour) 1.4576 - { 1.4577 - switch (lua_type(L, offset)) 1.4578 - { 1.4579 - case LUA_TSTRING: 1.4580 - { 1.4581 - const char *str = lua_tostring(L, offset); 1.4582 - uint32 colour; 1.4583 - 1.4584 - if (str2colour(&colour, L, str)) 1.4585 - return colour; 1.4586 - else 1.4587 - { 1.4588 - if (hasDefaultValue) 1.4589 - return defaultColour; 1.4590 - else 1.4591 - return luaL_error(L, "unknown colour %s", str); 1.4592 - } 1.4593 - } 1.4594 - 1.4595 - case LUA_TNUMBER: 1.4596 - { 1.4597 - uint32 colour = (uint32) lua_tointeger(L, offset); 1.4598 - return colour; 1.4599 - } 1.4600 - 1.4601 - case LUA_TTABLE: 1.4602 - { 1.4603 - int color = 0xFF; 1.4604 - lua_pushnil(L); // first key 1.4605 - int keyIndex = lua_gettop(L); 1.4606 - int valueIndex = keyIndex + 1; 1.4607 - bool first = true; 1.4608 - while (lua_next(L, offset)) 1.4609 - { 1.4610 - bool keyIsString = (lua_type(L, keyIndex) == LUA_TSTRING); 1.4611 - bool keyIsNumber = (lua_type(L, keyIndex) == LUA_TNUMBER); 1.4612 - int key = keyIsString ? tolower(*lua_tostring(L, keyIndex)) : (keyIsNumber ? lua_tointeger(L, keyIndex) : 0); 1.4613 - int value = lua_tointeger(L, valueIndex); 1.4614 - if (value < 0) value = 0; 1.4615 - if (value > 255) value = 255; 1.4616 - switch (key) 1.4617 - { 1.4618 - case 1: 1.4619 - case 'r': 1.4620 - color |= value << 24; break; 1.4621 - case 2: 1.4622 - case 'g': 1.4623 - color |= value << 16; break; 1.4624 - case 3: 1.4625 - case 'b': 1.4626 - color |= value << 8; break; 1.4627 - case 4: 1.4628 - case 'a': 1.4629 - color = (color & ~0xFF) | value; break; 1.4630 - } 1.4631 - lua_pop(L, 1); 1.4632 - } 1.4633 - return color; 1.4634 - } break; 1.4635 - 1.4636 - case LUA_TFUNCTION: 1.4637 - luaL_error(L, "invalid colour"); // NYI 1.4638 - return 0; 1.4639 - 1.4640 - default: 1.4641 - if (hasDefaultValue) 1.4642 - return defaultColour; 1.4643 - else 1.4644 - return luaL_error(L, "invalid colour"); 1.4645 - } 1.4646 - } 1.4647 - 1.4648 - static uint32 gui_getcolour(lua_State *L, int offset) 1.4649 - { 1.4650 - uint32 colour; 1.4651 - int a, r, g, b; 1.4652 - 1.4653 - colour = gui_getcolour_wrapped(L, offset, false, 0); 1.4654 - a = ((colour & 0xff) * transparencyModifier) / 255; 1.4655 - if (a > 255) 1.4656 - a = 255; 1.4657 - b = (colour >> 8) & 0xff; 1.4658 - g = (colour >> 16) & 0xff; 1.4659 - r = (colour >> 24) & 0xff; 1.4660 - return LUA_BUILD_PIXEL(a, r, g, b); 1.4661 - } 1.4662 - 1.4663 - static uint32 gui_optcolour(lua_State *L, int offset, uint32 defaultColour) 1.4664 - { 1.4665 - uint32 colour; 1.4666 - int a, r, g, b; 1.4667 - uint8 defA, defB, defG, defR; 1.4668 - 1.4669 - LUA_DECOMPOSE_PIXEL(defaultColour, defA, defR, defG, defB); 1.4670 - defaultColour = (defR << 24) | (defG << 16) | (defB << 8) | defA; 1.4671 - 1.4672 - colour = gui_getcolour_wrapped(L, offset, true, defaultColour); 1.4673 - a = ((colour & 0xff) * transparencyModifier) / 255; 1.4674 - if (a > 255) 1.4675 - a = 255; 1.4676 - b = (colour >> 8) & 0xff; 1.4677 - g = (colour >> 16) & 0xff; 1.4678 - r = (colour >> 24) & 0xff; 1.4679 - return LUA_BUILD_PIXEL(a, r, g, b); 1.4680 - } 1.4681 +static inline bool str2colour(uint32 *colour, lua_State *L, const char *str) 1.4682 +{ 1.4683 + if (str[0] == '#') 1.4684 + { 1.4685 + int color; 1.4686 + sscanf(str + 1, "%X", &color); 1.4687 + 1.4688 + int len = strlen(str + 1); 1.4689 + int missing = max(0, 8 - len); 1.4690 + color <<= missing << 2; 1.4691 + if (missing >= 2) 1.4692 + color |= 0xFF; 1.4693 + *colour = color; 1.4694 + return true; 1.4695 + } 1.4696 + else 1.4697 + { 1.4698 + if (!strnicmp(str, "rand", 4)) 1.4699 + { 1.4700 + *colour = gen_rand32() | 0xFF; //((rand()*255/RAND_MAX) << 8) | ((rand()*255/RAND_MAX) << 16) | 1.4701 + // ((rand()*255/RAND_MAX) << 24) | 0xFF; 1.4702 + return true; 1.4703 + } 1.4704 + 1.4705 + for (int i = 0; i < sizeof(s_colorMapping) / sizeof(*s_colorMapping); i++) 1.4706 + { 1.4707 + if (!stricmp(str, s_colorMapping[i].name)) 1.4708 + { 1.4709 + *colour = s_colorMapping[i].value; 1.4710 + return true; 1.4711 + } 1.4712 + } 1.4713 + } 1.4714 + 1.4715 + return false; 1.4716 +} 1.4717 + 1.4718 +static inline uint32 gui_getcolour_wrapped(lua_State *L, int offset, bool hasDefaultValue, uint32 defaultColour) 1.4719 +{ 1.4720 + switch (lua_type(L, offset)) 1.4721 + { 1.4722 + case LUA_TSTRING: 1.4723 + { 1.4724 + const char *str = lua_tostring(L, offset); 1.4725 + uint32 colour; 1.4726 + 1.4727 + if (str2colour(&colour, L, str)) 1.4728 + return colour; 1.4729 + else 1.4730 + { 1.4731 + if (hasDefaultValue) 1.4732 + return defaultColour; 1.4733 + else 1.4734 + return luaL_error(L, "unknown colour %s", str); 1.4735 + } 1.4736 + } 1.4737 + 1.4738 + case LUA_TNUMBER: 1.4739 + { 1.4740 + uint32 colour = (uint32) lua_tointeger(L, offset); 1.4741 + return colour; 1.4742 + } 1.4743 + 1.4744 + case LUA_TTABLE: 1.4745 + { 1.4746 + int color = 0xFF; 1.4747 + lua_pushnil(L); // first key 1.4748 + int keyIndex = lua_gettop(L); 1.4749 + int valueIndex = keyIndex + 1; 1.4750 + bool first = true; 1.4751 + while (lua_next(L, offset)) 1.4752 + { 1.4753 + bool keyIsString = (lua_type(L, keyIndex) == LUA_TSTRING); 1.4754 + bool keyIsNumber = (lua_type(L, keyIndex) == LUA_TNUMBER); 1.4755 + int key = keyIsString ? tolower(*lua_tostring(L, keyIndex)) : (keyIsNumber ? lua_tointeger(L, keyIndex) : 0); 1.4756 + int value = lua_tointeger(L, valueIndex); 1.4757 + if (value < 0) value = 0; 1.4758 + if (value > 255) value = 255; 1.4759 + switch (key) 1.4760 + { 1.4761 + case 1: 1.4762 + case 'r': 1.4763 + color |= value << 24; break; 1.4764 + case 2: 1.4765 + case 'g': 1.4766 + color |= value << 16; break; 1.4767 + case 3: 1.4768 + case 'b': 1.4769 + color |= value << 8; break; 1.4770 + case 4: 1.4771 + case 'a': 1.4772 + color = (color & ~0xFF) | value; break; 1.4773 + } 1.4774 + lua_pop(L, 1); 1.4775 + } 1.4776 + return color; 1.4777 + } break; 1.4778 + 1.4779 + case LUA_TFUNCTION: 1.4780 + luaL_error(L, "invalid colour"); // NYI 1.4781 + return 0; 1.4782 + 1.4783 + default: 1.4784 + if (hasDefaultValue) 1.4785 + return defaultColour; 1.4786 + else 1.4787 + return luaL_error(L, "invalid colour"); 1.4788 + } 1.4789 +} 1.4790 + 1.4791 +static uint32 gui_getcolour(lua_State *L, int offset) 1.4792 +{ 1.4793 + uint32 colour; 1.4794 + int a, r, g, b; 1.4795 + 1.4796 + colour = gui_getcolour_wrapped(L, offset, false, 0); 1.4797 + a = ((colour & 0xff) * transparencyModifier) / 255; 1.4798 + if (a > 255) 1.4799 + a = 255; 1.4800 + b = (colour >> 8) & 0xff; 1.4801 + g = (colour >> 16) & 0xff; 1.4802 + r = (colour >> 24) & 0xff; 1.4803 + return LUA_BUILD_PIXEL(a, r, g, b); 1.4804 +} 1.4805 + 1.4806 +static uint32 gui_optcolour(lua_State *L, int offset, uint32 defaultColour) 1.4807 +{ 1.4808 + uint32 colour; 1.4809 + int a, r, g, b; 1.4810 + uint8 defA, defB, defG, defR; 1.4811 + 1.4812 + LUA_DECOMPOSE_PIXEL(defaultColour, defA, defR, defG, defB); 1.4813 + defaultColour = (defR << 24) | (defG << 16) | (defB << 8) | defA; 1.4814 + 1.4815 + colour = gui_getcolour_wrapped(L, offset, true, defaultColour); 1.4816 + a = ((colour & 0xff) * transparencyModifier) / 255; 1.4817 + if (a > 255) 1.4818 + a = 255; 1.4819 + b = (colour >> 8) & 0xff; 1.4820 + g = (colour >> 16) & 0xff; 1.4821 + r = (colour >> 24) & 0xff; 1.4822 + return LUA_BUILD_PIXEL(a, r, g, b); 1.4823 +} 1.4824 1.4825 // gui.drawpixel(x,y,colour) 1.4826 - static int gui_drawpixel(lua_State *L) 1.4827 - { 1.4828 - int x = luaL_checkinteger(L, 1); 1.4829 - int y = luaL_checkinteger(L, 2); 1.4830 - 1.4831 - uint32 colour = gui_getcolour(L, 3); 1.4832 - 1.4833 - // if (!gui_check_boundary(x, y)) 1.4834 - // luaL_error(L,"bad coordinates"); 1.4835 - gui_prepare(); 1.4836 - 1.4837 - gui_drawpixel_internal(x, y, colour); 1.4838 - 1.4839 - return 0; 1.4840 - } 1.4841 +static int gui_drawpixel(lua_State *L) 1.4842 +{ 1.4843 + int x = luaL_checkinteger(L, 1); 1.4844 + int y = luaL_checkinteger(L, 2); 1.4845 + 1.4846 + uint32 colour = gui_getcolour(L, 3); 1.4847 + 1.4848 + // if (!gui_check_boundary(x, y)) 1.4849 + // luaL_error(L,"bad coordinates"); 1.4850 + gui_prepare(); 1.4851 + 1.4852 + gui_drawpixel_internal(x, y, colour); 1.4853 + 1.4854 + return 0; 1.4855 +} 1.4856 1.4857 // gui.drawline(x1,y1,x2,y2,color,skipFirst) 1.4858 - static int gui_drawline(lua_State *L) 1.4859 - { 1.4860 - int x1, y1, x2, y2; 1.4861 - uint32 color; 1.4862 - x1 = luaL_checkinteger(L, 1); 1.4863 - y1 = luaL_checkinteger(L, 2); 1.4864 - x2 = luaL_checkinteger(L, 3); 1.4865 - y2 = luaL_checkinteger(L, 4); 1.4866 - color = gui_optcolour(L, 5, LUA_BUILD_PIXEL(255, 255, 255, 255)); 1.4867 - int skipFirst = lua_toboolean(L, 6); 1.4868 - 1.4869 - gui_prepare(); 1.4870 - 1.4871 - gui_drawline_internal(x2, y2, x1, y1, !skipFirst, color); 1.4872 - 1.4873 - return 0; 1.4874 - } 1.4875 +static int gui_drawline(lua_State *L) 1.4876 +{ 1.4877 + int x1, y1, x2, y2; 1.4878 + uint32 color; 1.4879 + x1 = luaL_checkinteger(L, 1); 1.4880 + y1 = luaL_checkinteger(L, 2); 1.4881 + x2 = luaL_checkinteger(L, 3); 1.4882 + y2 = luaL_checkinteger(L, 4); 1.4883 + color = gui_optcolour(L, 5, LUA_BUILD_PIXEL(255, 255, 255, 255)); 1.4884 + int skipFirst = lua_toboolean(L, 6); 1.4885 + 1.4886 + gui_prepare(); 1.4887 + 1.4888 + gui_drawline_internal(x2, y2, x1, y1, !skipFirst, color); 1.4889 + 1.4890 + return 0; 1.4891 +} 1.4892 1.4893 // gui.drawbox(x1, y1, x2, y2, fillcolor, outlinecolor) 1.4894 - static int gui_drawbox(lua_State *L) 1.4895 - { 1.4896 - int x1, y1, x2, y2; 1.4897 - uint32 fillcolor; 1.4898 - uint32 outlinecolor; 1.4899 - 1.4900 - x1 = luaL_checkinteger(L, 1); 1.4901 - y1 = luaL_checkinteger(L, 2); 1.4902 - x2 = luaL_checkinteger(L, 3); 1.4903 - y2 = luaL_checkinteger(L, 4); 1.4904 - fillcolor = gui_optcolour(L, 5, LUA_BUILD_PIXEL(63, 255, 255, 255)); 1.4905 - outlinecolor = gui_optcolour(L, 6, LUA_BUILD_PIXEL(255, LUA_PIXEL_R(fillcolor), LUA_PIXEL_G(fillcolor), LUA_PIXEL_B(fillcolor))); 1.4906 - 1.4907 - if (x1 > x2) 1.4908 - std::swap(x1, x2); 1.4909 - if (y1 > y2) 1.4910 - std::swap(y1, y2); 1.4911 - 1.4912 - gui_prepare(); 1.4913 - 1.4914 - gui_drawbox_internal(x1, y1, x2, y2, outlinecolor); 1.4915 - if ((x2 - x1) >= 2 && (y2 - y1) >= 2) 1.4916 - gui_fillbox_internal(x1 + 1, y1 + 1, x2 - 1, y2 - 1, fillcolor); 1.4917 - 1.4918 - return 0; 1.4919 - } 1.4920 +static int gui_drawbox(lua_State *L) 1.4921 +{ 1.4922 + int x1, y1, x2, y2; 1.4923 + uint32 fillcolor; 1.4924 + uint32 outlinecolor; 1.4925 + 1.4926 + x1 = luaL_checkinteger(L, 1); 1.4927 + y1 = luaL_checkinteger(L, 2); 1.4928 + x2 = luaL_checkinteger(L, 3); 1.4929 + y2 = luaL_checkinteger(L, 4); 1.4930 + fillcolor = gui_optcolour(L, 5, LUA_BUILD_PIXEL(63, 255, 255, 255)); 1.4931 + outlinecolor = gui_optcolour(L, 6, LUA_BUILD_PIXEL(255, LUA_PIXEL_R(fillcolor), LUA_PIXEL_G(fillcolor), LUA_PIXEL_B(fillcolor))); 1.4932 + 1.4933 + if (x1 > x2) 1.4934 + std::swap(x1, x2); 1.4935 + if (y1 > y2) 1.4936 + std::swap(y1, y2); 1.4937 + 1.4938 + gui_prepare(); 1.4939 + 1.4940 + gui_drawbox_internal(x1, y1, x2, y2, outlinecolor); 1.4941 + if ((x2 - x1) >= 2 && (y2 - y1) >= 2) 1.4942 + gui_fillbox_internal(x1 + 1, y1 + 1, x2 - 1, y2 - 1, fillcolor); 1.4943 + 1.4944 + return 0; 1.4945 +} 1.4946 1.4947 // gui.drawcircle(x0, y0, radius, colour) 1.4948 - static int gui_drawcircle(lua_State *L) 1.4949 - { 1.4950 - int x, y, r; 1.4951 - uint32 colour; 1.4952 - 1.4953 - x = luaL_checkinteger(L, 1); 1.4954 - y = luaL_checkinteger(L, 2); 1.4955 - r = luaL_checkinteger(L, 3); 1.4956 - colour = gui_getcolour(L, 4); 1.4957 - 1.4958 - gui_prepare(); 1.4959 - 1.4960 - gui_drawcircle_internal(x, y, r, colour); 1.4961 - 1.4962 - return 0; 1.4963 - } 1.4964 +static int gui_drawcircle(lua_State *L) 1.4965 +{ 1.4966 + int x, y, r; 1.4967 + uint32 colour; 1.4968 + 1.4969 + x = luaL_checkinteger(L, 1); 1.4970 + y = luaL_checkinteger(L, 2); 1.4971 + r = luaL_checkinteger(L, 3); 1.4972 + colour = gui_getcolour(L, 4); 1.4973 + 1.4974 + gui_prepare(); 1.4975 + 1.4976 + gui_drawcircle_internal(x, y, r, colour); 1.4977 + 1.4978 + return 0; 1.4979 +} 1.4980 1.4981 // gui.fillbox(x1, y1, x2, y2, colour) 1.4982 - static int gui_fillbox(lua_State *L) 1.4983 - { 1.4984 - int x1, y1, x2, y2; 1.4985 - uint32 colour; 1.4986 - 1.4987 - x1 = luaL_checkinteger(L, 1); 1.4988 - y1 = luaL_checkinteger(L, 2); 1.4989 - x2 = luaL_checkinteger(L, 3); 1.4990 - y2 = luaL_checkinteger(L, 4); 1.4991 - colour = gui_getcolour(L, 5); 1.4992 - 1.4993 - // if (!gui_check_boundary(x1, y1)) 1.4994 - // luaL_error(L,"bad coordinates"); 1.4995 - // 1.4996 - // if (!gui_check_boundary(x2, y2)) 1.4997 - // luaL_error(L,"bad coordinates"); 1.4998 - gui_prepare(); 1.4999 - 1.5000 - if (!gui_checkbox(x1, y1, x2, y2)) 1.5001 - return 0; 1.5002 - 1.5003 - gui_fillbox_internal(x1, y1, x2, y2, colour); 1.5004 - 1.5005 - return 0; 1.5006 - } 1.5007 +static int gui_fillbox(lua_State *L) 1.5008 +{ 1.5009 + int x1, y1, x2, y2; 1.5010 + uint32 colour; 1.5011 + 1.5012 + x1 = luaL_checkinteger(L, 1); 1.5013 + y1 = luaL_checkinteger(L, 2); 1.5014 + x2 = luaL_checkinteger(L, 3); 1.5015 + y2 = luaL_checkinteger(L, 4); 1.5016 + colour = gui_getcolour(L, 5); 1.5017 + 1.5018 + // if (!gui_check_boundary(x1, y1)) 1.5019 + // luaL_error(L,"bad coordinates"); 1.5020 + // 1.5021 + // if (!gui_check_boundary(x2, y2)) 1.5022 + // luaL_error(L,"bad coordinates"); 1.5023 + gui_prepare(); 1.5024 + 1.5025 + if (!gui_checkbox(x1, y1, x2, y2)) 1.5026 + return 0; 1.5027 + 1.5028 + gui_fillbox_internal(x1, y1, x2, y2, colour); 1.5029 + 1.5030 + return 0; 1.5031 +} 1.5032 1.5033 // gui.fillcircle(x0, y0, radius, colour) 1.5034 - static int gui_fillcircle(lua_State *L) 1.5035 - { 1.5036 - int x, y, r; 1.5037 - uint32 colour; 1.5038 - 1.5039 - x = luaL_checkinteger(L, 1); 1.5040 - y = luaL_checkinteger(L, 2); 1.5041 - r = luaL_checkinteger(L, 3); 1.5042 - colour = gui_getcolour(L, 4); 1.5043 - 1.5044 - gui_prepare(); 1.5045 - 1.5046 - gui_fillcircle_internal(x, y, r, colour); 1.5047 - 1.5048 - return 0; 1.5049 - } 1.5050 - 1.5051 - static int gui_getpixel(lua_State *L) 1.5052 - { 1.5053 - int x = luaL_checkinteger(L, 1); 1.5054 - int y = luaL_checkinteger(L, 2); 1.5055 - 1.5056 - int pixWidth = 240, pixHeight = 160; 1.5057 - int scrWidth = 240, scrHeight = 160; 1.5058 - int scrOffsetX = 0, scrOffsetY = 0; 1.5059 - int pitch; 1.5060 - if (!systemIsRunningGBA()) 1.5061 - { 1.5062 - if (gbBorderOn) 1.5063 - { 1.5064 - pixWidth = 256, pixHeight = 224; 1.5065 - scrOffsetX = 48, scrOffsetY = 40; 1.5066 - } 1.5067 - else 1.5068 - { 1.5069 - pixWidth = 160, pixHeight = 144; 1.5070 - } 1.5071 - scrWidth = 160, scrHeight = 144; 1.5072 - } 1.5073 - pitch = pixWidth * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); 1.5074 - scrOffsetY++; // don't know why it's needed 1.5075 - 1.5076 - if (!(x >= 0 && y >= 0 && x < scrWidth && y < scrHeight) /*!gui_check_boundary(x,y)*/) 1.5077 - { 1.5078 - lua_pushinteger(L, 0); 1.5079 - lua_pushinteger(L, 0); 1.5080 - lua_pushinteger(L, 0); 1.5081 - } 1.5082 - else 1.5083 - { 1.5084 - switch (systemColorDepth) 1.5085 - { 1.5086 - case 16: 1.5087 - { 1.5088 - uint16 *screen = (uint16 *) (&pix[scrOffsetY * pitch + scrOffsetX * 2]); 1.5089 - uint16 pixColor = screen[y * pitch / 2 + x]; 1.5090 - lua_pushinteger(L, (pixColor >> 8) & 0xF8); // red 1.5091 - lua_pushinteger(L, (pixColor >> 3) & 0xFC); // green 1.5092 - lua_pushinteger(L, (pixColor << 3) & 0xF8); // blue 1.5093 - } 1.5094 - break; 1.5095 - case 24: 1.5096 - { 1.5097 - uint8 *screen = &pix[scrOffsetY * pitch + scrOffsetX * 3]; 1.5098 - lua_pushinteger(L, screen[y * pitch + x * 3 + 2]); // red 1.5099 - lua_pushinteger(L, screen[y * pitch + x * 3 + 1]); // green 1.5100 - lua_pushinteger(L, screen[y * pitch + x * 3 + 0]); // blue 1.5101 - } 1.5102 - break; 1.5103 - case 32: 1.5104 - { 1.5105 - uint8 *screen = &pix[scrOffsetY * pitch + scrOffsetX * 4]; 1.5106 - lua_pushinteger(L, screen[y * pitch + x * 4 + 2]); // red 1.5107 - lua_pushinteger(L, screen[y * pitch + x * 4 + 1]); // green 1.5108 - lua_pushinteger(L, screen[y * pitch + x * 4 + 0]); // blue 1.5109 - } 1.5110 - break; 1.5111 - default: 1.5112 - lua_pushinteger(L, 0); 1.5113 - lua_pushinteger(L, 0); 1.5114 - lua_pushinteger(L, 0); 1.5115 - break; 1.5116 - } 1.5117 - } 1.5118 - return 3; 1.5119 - } 1.5120 - 1.5121 - static int gui_parsecolor(lua_State *L) 1.5122 - { 1.5123 - int r, g, b, a; 1.5124 - uint32 color = gui_getcolour(L, 1); 1.5125 - LUA_DECOMPOSE_PIXEL(color, a, r, g, b); 1.5126 - lua_pushinteger(L, r); 1.5127 - lua_pushinteger(L, g); 1.5128 - lua_pushinteger(L, b); 1.5129 - lua_pushinteger(L, a); 1.5130 - return 4; 1.5131 - } 1.5132 +static int gui_fillcircle(lua_State *L) 1.5133 +{ 1.5134 + int x, y, r; 1.5135 + uint32 colour; 1.5136 + 1.5137 + x = luaL_checkinteger(L, 1); 1.5138 + y = luaL_checkinteger(L, 2); 1.5139 + r = luaL_checkinteger(L, 3); 1.5140 + colour = gui_getcolour(L, 4); 1.5141 + 1.5142 + gui_prepare(); 1.5143 + 1.5144 + gui_fillcircle_internal(x, y, r, colour); 1.5145 + 1.5146 + return 0; 1.5147 +} 1.5148 + 1.5149 +static int gui_getpixel(lua_State *L) 1.5150 +{ 1.5151 + int x = luaL_checkinteger(L, 1); 1.5152 + int y = luaL_checkinteger(L, 2); 1.5153 + 1.5154 + int pixWidth = 240, pixHeight = 160; 1.5155 + int scrWidth = 240, scrHeight = 160; 1.5156 + int scrOffsetX = 0, scrOffsetY = 0; 1.5157 + int pitch; 1.5158 + if (!systemIsRunningGBA()) 1.5159 + { 1.5160 + if (gbBorderOn) 1.5161 + { 1.5162 + pixWidth = 256, pixHeight = 224; 1.5163 + scrOffsetX = 48, scrOffsetY = 40; 1.5164 + } 1.5165 + else 1.5166 + { 1.5167 + pixWidth = 160, pixHeight = 144; 1.5168 + } 1.5169 + scrWidth = 160, scrHeight = 144; 1.5170 + } 1.5171 + pitch = pixWidth * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); 1.5172 + scrOffsetY++; // don't know why it's needed 1.5173 + 1.5174 + if (!(x >= 0 && y >= 0 && x < scrWidth && y < scrHeight) /*!gui_check_boundary(x,y)*/) 1.5175 + { 1.5176 + lua_pushinteger(L, 0); 1.5177 + lua_pushinteger(L, 0); 1.5178 + lua_pushinteger(L, 0); 1.5179 + } 1.5180 + else 1.5181 + { 1.5182 + switch (systemColorDepth) 1.5183 + { 1.5184 + case 16: 1.5185 + { 1.5186 + uint16 *screen = (uint16 *) (&pix[scrOffsetY * pitch + scrOffsetX * 2]); 1.5187 + uint16 pixColor = screen[y * pitch / 2 + x]; 1.5188 + lua_pushinteger(L, (pixColor >> 8) & 0xF8); // red 1.5189 + lua_pushinteger(L, (pixColor >> 3) & 0xFC); // green 1.5190 + lua_pushinteger(L, (pixColor << 3) & 0xF8); // blue 1.5191 + } 1.5192 + break; 1.5193 + case 24: 1.5194 + { 1.5195 + uint8 *screen = &pix[scrOffsetY * pitch + scrOffsetX * 3]; 1.5196 + lua_pushinteger(L, screen[y * pitch + x * 3 + 2]); // red 1.5197 + lua_pushinteger(L, screen[y * pitch + x * 3 + 1]); // green 1.5198 + lua_pushinteger(L, screen[y * pitch + x * 3 + 0]); // blue 1.5199 + } 1.5200 + break; 1.5201 + case 32: 1.5202 + { 1.5203 + uint8 *screen = &pix[scrOffsetY * pitch + scrOffsetX * 4]; 1.5204 + lua_pushinteger(L, screen[y * pitch + x * 4 + 2]); // red 1.5205 + lua_pushinteger(L, screen[y * pitch + x * 4 + 1]); // green 1.5206 + lua_pushinteger(L, screen[y * pitch + x * 4 + 0]); // blue 1.5207 + } 1.5208 + break; 1.5209 + default: 1.5210 + lua_pushinteger(L, 0); 1.5211 + lua_pushinteger(L, 0); 1.5212 + lua_pushinteger(L, 0); 1.5213 + break; 1.5214 + } 1.5215 + } 1.5216 + return 3; 1.5217 +} 1.5218 + 1.5219 +static int gui_parsecolor(lua_State *L) 1.5220 +{ 1.5221 + int r, g, b, a; 1.5222 + uint32 color = gui_getcolour(L, 1); 1.5223 + LUA_DECOMPOSE_PIXEL(color, a, r, g, b); 1.5224 + lua_pushinteger(L, r); 1.5225 + lua_pushinteger(L, g); 1.5226 + lua_pushinteger(L, b); 1.5227 + lua_pushinteger(L, a); 1.5228 + return 4; 1.5229 +} 1.5230 1.5231 // gui.gdscreenshot() 1.5232 // 1.5233 @@ -2915,66 +2915,66 @@ 1.5234 // It really is easier that way. 1.5235 1.5236 // example: gd.createFromGdStr(gui.gdscreenshot()):png("outputimage.png") 1.5237 - static int gui_gdscreenshot(lua_State *L) 1.5238 - { 1.5239 - int xofs = 0, yofs = 0, ppl = 240, width = 240, height = 160; 1.5240 - if (!systemIsRunningGBA()) 1.5241 - { 1.5242 - if (gbBorderOn) 1.5243 - xofs = 48, yofs = 40, ppl = 256; 1.5244 - else 1.5245 - ppl = 160; 1.5246 - width = 160, height = 144; 1.5247 - } 1.5248 - 1.5249 - yofs++; 1.5250 - 1.5251 - //int pitch = (((ppl * systemColorDepth + 7)>>3)+3)&~3; 1.5252 - int pitch = ppl * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); 1.5253 - uint8 *screen = &pix[yofs * pitch + xofs * (systemColorDepth / 8)]; 1.5254 - 1.5255 - int size = 11 + width * height * 4; 1.5256 - char *str = new char[size + 1]; 1.5257 - str[size] = 0; 1.5258 - 1.5259 - unsigned char *ptr = (unsigned char *)str; 1.5260 - 1.5261 - // GD format header for truecolor image (11 bytes) 1.5262 - *ptr++ = (65534 >> 8) & 0xFF; 1.5263 - *ptr++ = (65534) & 0xFF; 1.5264 - *ptr++ = (width >> 8) & 0xFF; 1.5265 - *ptr++ = (width) & 0xFF; 1.5266 - *ptr++ = (height >> 8) & 0xFF; 1.5267 - *ptr++ = (height) & 0xFF; 1.5268 - *ptr++ = 1; 1.5269 - *ptr++ = 255; 1.5270 - *ptr++ = 255; 1.5271 - *ptr++ = 255; 1.5272 - *ptr++ = 255; 1.5273 - 1.5274 - GetColorFunc getColor; 1.5275 - getColorIOFunc(systemColorDepth, &getColor, NULL); 1.5276 - 1.5277 - int x, y; 1.5278 - for (y = 0; y < height; y++) 1.5279 - { 1.5280 - uint8 *s = &screen[y * pitch]; 1.5281 - for (x = 0; x < width; x++, s += systemColorDepth / 8) 1.5282 - { 1.5283 - uint8 r, g, b; 1.5284 - getColor(s, &r, &g, &b); 1.5285 - 1.5286 - *ptr++ = 0; 1.5287 - *ptr++ = r; 1.5288 - *ptr++ = g; 1.5289 - *ptr++ = b; 1.5290 - } 1.5291 - } 1.5292 - 1.5293 - lua_pushlstring(L, str, size); 1.5294 - delete[] str; 1.5295 - return 1; 1.5296 - } 1.5297 +static int gui_gdscreenshot(lua_State *L) 1.5298 +{ 1.5299 + int xofs = 0, yofs = 0, ppl = 240, width = 240, height = 160; 1.5300 + if (!systemIsRunningGBA()) 1.5301 + { 1.5302 + if (gbBorderOn) 1.5303 + xofs = 48, yofs = 40, ppl = 256; 1.5304 + else 1.5305 + ppl = 160; 1.5306 + width = 160, height = 144; 1.5307 + } 1.5308 + 1.5309 + yofs++; 1.5310 + 1.5311 + //int pitch = (((ppl * systemColorDepth + 7)>>3)+3)&~3; 1.5312 + int pitch = ppl * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); 1.5313 + uint8 *screen = &pix[yofs * pitch + xofs * (systemColorDepth / 8)]; 1.5314 + 1.5315 + int size = 11 + width * height * 4; 1.5316 + char *str = new char[size + 1]; 1.5317 + str[size] = 0; 1.5318 + 1.5319 + unsigned char *ptr = (unsigned char *)str; 1.5320 + 1.5321 + // GD format header for truecolor image (11 bytes) 1.5322 + *ptr++ = (65534 >> 8) & 0xFF; 1.5323 + *ptr++ = (65534) & 0xFF; 1.5324 + *ptr++ = (width >> 8) & 0xFF; 1.5325 + *ptr++ = (width) & 0xFF; 1.5326 + *ptr++ = (height >> 8) & 0xFF; 1.5327 + *ptr++ = (height) & 0xFF; 1.5328 + *ptr++ = 1; 1.5329 + *ptr++ = 255; 1.5330 + *ptr++ = 255; 1.5331 + *ptr++ = 255; 1.5332 + *ptr++ = 255; 1.5333 + 1.5334 + GetColorFunc getColor; 1.5335 + getColorIOFunc(systemColorDepth, &getColor, NULL); 1.5336 + 1.5337 + int x, y; 1.5338 + for (y = 0; y < height; y++) 1.5339 + { 1.5340 + uint8 *s = &screen[y * pitch]; 1.5341 + for (x = 0; x < width; x++, s += systemColorDepth / 8) 1.5342 + { 1.5343 + uint8 r, g, b; 1.5344 + getColor(s, &r, &g, &b); 1.5345 + 1.5346 + *ptr++ = 0; 1.5347 + *ptr++ = r; 1.5348 + *ptr++ = g; 1.5349 + *ptr++ = b; 1.5350 + } 1.5351 + } 1.5352 + 1.5353 + lua_pushlstring(L, str, size); 1.5354 + delete[] str; 1.5355 + return 1; 1.5356 +} 1.5357 1.5358 // gui.opacity(number alphaValue) 1.5359 // sets the transparency of subsequent draw calls 1.5360 @@ -2984,472 +2984,472 @@ 1.5361 // because you can provide an alpha value in the color argument of each draw call. 1.5362 1.5363 // however, it can be convenient to be able to globally modify the drawing transparency 1.5364 - static int gui_setopacity(lua_State *L) 1.5365 - { 1.5366 - double opacF = luaL_checknumber(L, 1); 1.5367 - transparencyModifier = (int)(opacF * 255); 1.5368 - if (transparencyModifier < 0) 1.5369 - transparencyModifier = 0; 1.5370 - return 0; 1.5371 - } 1.5372 +static int gui_setopacity(lua_State *L) 1.5373 +{ 1.5374 + double opacF = luaL_checknumber(L, 1); 1.5375 + transparencyModifier = (int)(opacF * 255); 1.5376 + if (transparencyModifier < 0) 1.5377 + transparencyModifier = 0; 1.5378 + return 0; 1.5379 +} 1.5380 1.5381 // gui.transparency(int strength) 1.5382 // 1.5383 1.5384 // 0 = solid, 1.5385 - static int gui_transparency(lua_State *L) 1.5386 - { 1.5387 - double trans = luaL_checknumber(L, 1); 1.5388 - transparencyModifier = (int)((4.0 - trans) / 4.0 * 255); 1.5389 - if (transparencyModifier < 0) 1.5390 - transparencyModifier = 0; 1.5391 - return 0; 1.5392 - } 1.5393 - 1.5394 - static const uint32 Small_Font_Data[] = 1.5395 - { 1.5396 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 32 1.5397 - 0x00000000, 0x00000300, 0x00000400, 0x00000500, 0x00000000, 0x00000700, 0x00000000, // 33 ! 1.5398 - 0x00000000, 0x00040002, 0x00050003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 34 " 1.5399 - 0x00000000, 0x00040002, 0x00050403, 0x00060004, 0x00070605, 0x00080006, 0x00000000, // 35 # 1.5400 - 0x00000000, 0x00040300, 0x00000403, 0x00000500, 0x00070600, 0x00000706, 0x00000000, // 36 $ 1.5401 - 0x00000000, 0x00000002, 0x00050000, 0x00000500, 0x00000005, 0x00080000, 0x00000000, // 37 % 1.5402 - 0x00000000, 0x00000300, 0x00050003, 0x00000500, 0x00070005, 0x00080700, 0x00000000, // 38 & 1.5403 - 0x00000000, 0x00000300, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 39 ' 1.5404 - 0x00000000, 0x00000300, 0x00000003, 0x00000004, 0x00000005, 0x00000700, 0x00000000, // 40 ( 1.5405 - 0x00000000, 0x00000300, 0x00050000, 0x00060000, 0x00070000, 0x00000700, 0x00000000, // 41 ) 1.5406 - 0x00000000, 0x00000000, 0x00000400, 0x00060504, 0x00000600, 0x00080006, 0x00000000, // 42 * 1.5407 - 0x00000000, 0x00000000, 0x00000400, 0x00060504, 0x00000600, 0x00000000, 0x00000000, // 43 + 1.5408 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000600, 0x00000700, 0x00000007, // 44 , 1.5409 - 0x00000000, 0x00000000, 0x00000000, 0x00060504, 0x00000000, 0x00000000, 0x00000000, // 45 - 1.5410 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000700, 0x00000000, // 46 . 1.5411 - 0x00030000, 0x00040000, 0x00000400, 0x00000500, 0x00000005, 0x00000006, 0x00000000, // 47 / 1.5412 - 0x00000000, 0x00000300, 0x00050003, 0x00060004, 0x00070005, 0x00000700, 0x00000000, // 48 0 1.5413 - 0x00000000, 0x00000300, 0x00000403, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 49 1 1.5414 - 0x00000000, 0x00000302, 0x00050000, 0x00000500, 0x00000005, 0x00080706, 0x00000000, // 50 2 1.5415 - 0x00000000, 0x00000302, 0x00050000, 0x00000504, 0x00070000, 0x00000706, 0x00000000, // 51 3 1.5416 - 0x00000000, 0x00000300, 0x00000003, 0x00060004, 0x00070605, 0x00080000, 0x00000000, // 52 4 1.5417 - 0x00000000, 0x00040302, 0x00000003, 0x00000504, 0x00070000, 0x00000706, 0x00000000, // 53 5 1.5418 - 0x00000000, 0x00000300, 0x00000003, 0x00000504, 0x00070005, 0x00000700, 0x00000000, // 54 6 1.5419 - 0x00000000, 0x00040302, 0x00050000, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 55 7 1.5420 - 0x00000000, 0x00000300, 0x00050003, 0x00000500, 0x00070005, 0x00000700, 0x00000000, // 56 8 1.5421 - 0x00000000, 0x00000300, 0x00050003, 0x00060500, 0x00070000, 0x00000700, 0x00000000, // 57 9 1.5422 - 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000700, 0x00000000, // 58 : 1.5423 - 0x00000000, 0x00000000, 0x00000000, 0x00000500, 0x00000000, 0x00000700, 0x00000007, // 59 ; 1.5424 - 0x00000000, 0x00040000, 0x00000400, 0x00000004, 0x00000600, 0x00080000, 0x00000000, // 60 < 1.5425 - 0x00000000, 0x00000000, 0x00050403, 0x00000000, 0x00070605, 0x00000000, 0x00000000, // 61 = 1.5426 - 0x00000000, 0x00000002, 0x00000400, 0x00060000, 0x00000600, 0x00000006, 0x00000000, // 62 > 1.5427 - 0x00000000, 0x00000302, 0x00050000, 0x00000500, 0x00000000, 0x00000700, 0x00000000, // 63 ? 1.5428 - 0x00000000, 0x00000300, 0x00050400, 0x00060004, 0x00070600, 0x00000000, 0x00000000, // 64 @ 1.5429 - 0x00000000, 0x00000300, 0x00050003, 0x00060504, 0x00070005, 0x00080006, 0x00000000, // 65 A 1.5430 - 0x00000000, 0x00000302, 0x00050003, 0x00000504, 0x00070005, 0x00000706, 0x00000000, // 66 B 1.5431 - 0x00000000, 0x00040300, 0x00000003, 0x00000004, 0x00000005, 0x00080700, 0x00000000, // 67 C 1.5432 - 0x00000000, 0x00000302, 0x00050003, 0x00060004, 0x00070005, 0x00000706, 0x00000000, // 68 D 1.5433 - 0x00000000, 0x00040302, 0x00000003, 0x00000504, 0x00000005, 0x00080706, 0x00000000, // 69 E 1.5434 - 0x00000000, 0x00040302, 0x00000003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 70 F 1.5435 - 0x00000000, 0x00040300, 0x00000003, 0x00060004, 0x00070005, 0x00080700, 0x00000000, // 71 G 1.5436 - 0x00000000, 0x00040002, 0x00050003, 0x00060504, 0x00070005, 0x00080006, 0x00000000, // 72 H 1.5437 - 0x00000000, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 73 I 1.5438 - 0x00000000, 0x00040000, 0x00050000, 0x00060000, 0x00070005, 0x00000700, 0x00000000, // 74 J 1.5439 - 0x00000000, 0x00040002, 0x00050003, 0x00000504, 0x00070005, 0x00080006, 0x00000000, // 75 K 1.5440 - 0x00000000, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00080706, 0x00000000, // 76 l 1.5441 - 0x00000000, 0x00040002, 0x00050403, 0x00060004, 0x00070005, 0x00080006, 0x00000000, // 77 M 1.5442 - 0x00000000, 0x00000302, 0x00050003, 0x00060004, 0x00070005, 0x00080006, 0x00000000, // 78 N 1.5443 - 0x00000000, 0x00040302, 0x00050003, 0x00060004, 0x00070005, 0x00080706, 0x00000000, // 79 O 1.5444 - 0x00000000, 0x00000302, 0x00050003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 80 P 1.5445 - 0x00000000, 0x00040302, 0x00050003, 0x00060004, 0x00070005, 0x00080706, 0x00090000, // 81 Q 1.5446 - 0x00000000, 0x00000302, 0x00050003, 0x00000504, 0x00070005, 0x00080006, 0x00000000, // 82 R 1.5447 - 0x00000000, 0x00040300, 0x00000003, 0x00000500, 0x00070000, 0x00000706, 0x00000000, // 83 S 1.5448 - 0x00000000, 0x00040302, 0x00000400, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 84 T 1.5449 - 0x00000000, 0x00040002, 0x00050003, 0x00060004, 0x00070005, 0x00080706, 0x00000000, // 85 U 1.5450 - 0x00000000, 0x00040002, 0x00050003, 0x00060004, 0x00000600, 0x00000700, 0x00000000, // 86 V 1.5451 - 0x00000000, 0x00040002, 0x00050003, 0x00060004, 0x00070605, 0x00080006, 0x00000000, // 87 W 1.5452 - 0x00000000, 0x00040002, 0x00050003, 0x00000500, 0x00070005, 0x00080006, 0x00000000, // 88 X 1.5453 - 0x00000000, 0x00040002, 0x00050003, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 89 Y 1.5454 - 0x00000000, 0x00040302, 0x00050000, 0x00000500, 0x00000005, 0x00080706, 0x00000000, // 90 Z 1.5455 - 0x00000000, 0x00040300, 0x00000400, 0x00000500, 0x00000600, 0x00080700, 0x00000000, // 91 [ 1.5456 - 0x00000000, 0x00000002, 0x00000400, 0x00000500, 0x00070000, 0x00080000, 0x00000000, // 92 '\' 1.5457 - 0x00000000, 0x00000302, 0x00000400, 0x00000500, 0x00000600, 0x00000706, 0x00000000, // 93 ] 1.5458 - 0x00000000, 0x00000300, 0x00050003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 94 ^ 1.5459 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080706, 0x00000000, // 95 _ 1.5460 - 0x00000000, 0x00000002, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 96 ` 1.5461 - 0x00000000, 0x00000000, 0x00050400, 0x00060004, 0x00070005, 0x00080700, 0x00000000, // 97 a 1.5462 - 0x00000000, 0x00000002, 0x00000003, 0x00000504, 0x00070005, 0x00000706, 0x00000000, // 98 b 1.5463 - 0x00000000, 0x00000000, 0x00050400, 0x00000004, 0x00000005, 0x00080700, 0x00000000, // 99 c 1.5464 - 0x00000000, 0x00040000, 0x00050000, 0x00060500, 0x00070005, 0x00080700, 0x00000000, // 100 d 1.5465 - 0x00000000, 0x00000000, 0x00050400, 0x00060504, 0x00000005, 0x00080700, 0x00000000, // 101 e 1.5466 - 0x00000000, 0x00040300, 0x00000003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 102 f 1.5467 - 0x00000000, 0x00000000, 0x00050400, 0x00060004, 0x00070600, 0x00080000, 0x00000807, // 103 g 1.5468 - 0x00000000, 0x00000002, 0x00000003, 0x00000504, 0x00070005, 0x00080006, 0x00000000, // 104 h 1.5469 - 0x00000000, 0x00000300, 0x00000000, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 105 i 1.5470 - 0x00000000, 0x00000300, 0x00000000, 0x00000500, 0x00000600, 0x00000700, 0x00000007, // 106 j 1.5471 - 0x00000000, 0x00000002, 0x00000003, 0x00060004, 0x00000605, 0x00080006, 0x00000000, // 107 k 1.5472 - 0x00000000, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00080000, 0x00000000, // 108 l 1.5473 - 0x00000000, 0x00000000, 0x00050003, 0x00060504, 0x00070005, 0x00080006, 0x00000000, // 109 m 1.5474 - 0x00000000, 0x00000000, 0x00000403, 0x00060004, 0x00070005, 0x00080006, 0x00000000, // 110 n 1.5475 - 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00070005, 0x00000700, 0x00000000, // 111 o 1.5476 - 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00000605, 0x00000006, 0x00000007, // 112 p 1.5477 - 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00070600, 0x00080000, 0x00090000, // 113 q 1.5478 - 0x00000000, 0x00000000, 0x00050003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 114 r 1.5479 - 0x00000000, 0x00000000, 0x00050400, 0x00000004, 0x00070600, 0x00000706, 0x00000000, // 115 s 1.5480 - 0x00000000, 0x00000300, 0x00050403, 0x00000500, 0x00000600, 0x00080000, 0x00000000, // 116 t 1.5481 - 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00070005, 0x00080700, 0x00000000, // 117 u 1.5482 - 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00070005, 0x00000700, 0x00000000, // 118 v 1.5483 - 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00070605, 0x00080006, 0x00000000, // 119 w 1.5484 - 0x00000000, 0x00000000, 0x00050003, 0x00000500, 0x00070005, 0x00080006, 0x00000000, // 120 x 1.5485 - 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00000600, 0x00000700, 0x00000007, // 121 y 1.5486 - 0x00000000, 0x00000000, 0x00050403, 0x00000500, 0x00000005, 0x00080706, 0x00000000, // 122 z 1.5487 - 0x00000000, 0x00040300, 0x00000400, 0x00000504, 0x00000600, 0x00080700, 0x00000000, // 123 { 1.5488 - 0x00000000, 0x00000300, 0x00000400, 0x00000000, 0x00000600, 0x00000700, 0x00000000, // 124 | 1.5489 - 0x00000000, 0x00000302, 0x00000400, 0x00060500, 0x00000600, 0x00000706, 0x00000000, // 125 } 1.5490 - 0x00000000, 0x00000302, 0x00050000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 126 ~ 1.5491 - 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00070605, 0x00000000, 0x00000000, // 127 1.5492 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.5493 - }; 1.5494 - 1.5495 - static void PutTextInternal(const char *str, int len, short x, short y, int color, int backcolor) 1.5496 - { 1.5497 - int Opac = (color >> 24) & 0xFF; 1.5498 - int backOpac = (backcolor >> 24) & 0xFF; 1.5499 - int origX = x; 1.5500 - 1.5501 - if (!Opac && !backOpac) 1.5502 - return; 1.5503 - 1.5504 - while (*str && len && y < LUA_SCREEN_HEIGHT) 1.5505 - { 1.5506 - int c = *str++; 1.5507 - while (x > LUA_SCREEN_WIDTH && c != '\n') 1.5508 - { 1.5509 - c = *str; 1.5510 - if (c == '\0') 1.5511 - break; 1.5512 - str++; 1.5513 - } 1.5514 - 1.5515 - if (c == '\n') 1.5516 - { 1.5517 - x = origX; 1.5518 - y += 8; 1.5519 - continue; 1.5520 - } 1.5521 - else if (c == '\t') // just in case 1.5522 - { 1.5523 - const int tabSpace = 8; 1.5524 - x += (tabSpace - (((x - origX) / 4) % tabSpace)) * 4; 1.5525 - continue; 1.5526 - } 1.5527 - 1.5528 - if ((unsigned int)(c - 32) >= 96) 1.5529 - continue; 1.5530 - 1.5531 - const unsigned char *Cur_Glyph = (const unsigned char *) &Small_Font_Data + (c - 32) * 7 * 4; 1.5532 - 1.5533 - for (int y2 = 0; y2 < 8; y2++) 1.5534 - { 1.5535 - unsigned int glyphLine = *((unsigned int *)Cur_Glyph + y2); 1.5536 - for (int x2 = -1; x2 < 4; x2++) 1.5537 - { 1.5538 - int shift = x2 << 3; 1.5539 - int mask = 0xFF << shift; 1.5540 - int intensity = (glyphLine & mask) >> shift; 1.5541 - 1.5542 - if (intensity && x2 >= 0 && y2 < 7) 1.5543 - { 1.5544 - //int xdraw = max(0,min(LUA_SCREEN_WIDTH - 1,x+x2)); 1.5545 - //int ydraw = max(0,min(LUA_SCREEN_HEIGHT - 1,y+y2)); 1.5546 - //gui_drawpixel_fast(xdraw, ydraw, color); 1.5547 - gui_drawpixel_internal(x + x2, y + y2, color); 1.5548 - } 1.5549 - else if (backOpac) 1.5550 - { 1.5551 - for (int y3 = max(0, y2 - 1); y3 <= min(6, y2 + 1); y3++) 1.5552 - { 1.5553 - unsigned int glyphLine = *((unsigned int *)Cur_Glyph + y3); 1.5554 - for (int x3 = max(0, x2 - 1); x3 <= min(3, x2 + 1); x3++) 1.5555 - { 1.5556 - int shift = x3 << 3; 1.5557 - int mask = 0xFF << shift; 1.5558 - intensity |= (glyphLine & mask) >> shift; 1.5559 - if (intensity) 1.5560 - goto draw_outline; // speedup? 1.5561 - } 1.5562 - } 1.5563 - 1.5564 -draw_outline: 1.5565 - if (intensity) 1.5566 - { 1.5567 - //int xdraw = max(0,min(LUA_SCREEN_WIDTH - 1,x+x2)); 1.5568 - //int ydraw = max(0,min(LUA_SCREEN_HEIGHT - 1,y+y2)); 1.5569 - //gui_drawpixel_fast(xdraw, ydraw, backcolor); 1.5570 - gui_drawpixel_internal(x + x2, y + y2, backcolor); 1.5571 - } 1.5572 - } 1.5573 - } 1.5574 - } 1.5575 - 1.5576 - x += 4; 1.5577 - len--; 1.5578 - } 1.5579 - } 1.5580 - 1.5581 - static int strlinelen(const char *string) 1.5582 - { 1.5583 - const char *s = string; 1.5584 - while (*s && *s != '\n') 1.5585 - s++; 1.5586 - if (*s) 1.5587 - s++; 1.5588 - return s - string; 1.5589 - } 1.5590 - 1.5591 - static void LuaDisplayString(const char *string, int y, int x, uint32 color, uint32 outlineColor) 1.5592 - { 1.5593 - if (!string) 1.5594 - return; 1.5595 - 1.5596 - gui_prepare(); 1.5597 - 1.5598 - PutTextInternal(string, strlen(string), x, y, color, outlineColor); 1.5599 - 1.5600 - /* 1.5601 - const char* ptr = string; 1.5602 - while(*ptr && y < LUA_SCREEN_HEIGHT) 1.5603 - { 1.5604 - int len = strlinelen(ptr); 1.5605 - int skip = 0; 1.5606 - if(len < 1) len = 1; 1.5607 - 1.5608 - // break up the line if it's too long to display otherwise 1.5609 - if(len > 63) 1.5610 - { 1.5611 - len = 63; 1.5612 - const char* ptr2 = ptr + len-1; 1.5613 - for(int j = len-1; j; j--, ptr2--) 1.5614 - { 1.5615 - if(*ptr2 == ' ' || *ptr2 == '\t') 1.5616 - { 1.5617 - len = j; 1.5618 - skip = 1; 1.5619 - break; 1.5620 - } 1.5621 - } 1.5622 - } 1.5623 - 1.5624 - int xl = 0; 1.5625 - int yl = 0; 1.5626 - int xh = (LUA_SCREEN_WIDTH - 1 - 1) - 4*len; 1.5627 - int yh = LUA_SCREEN_HEIGHT - 1; 1.5628 - int x2 = min(max(x,xl),xh); 1.5629 - int y2 = min(max(y,yl),yh); 1.5630 - 1.5631 - PutTextInternal(ptr,len,x2,y2,color,outlineColor); 1.5632 - 1.5633 - ptr += len + skip; 1.5634 - y += 8; 1.5635 - } 1.5636 - */ 1.5637 - } 1.5638 +static int gui_transparency(lua_State *L) 1.5639 +{ 1.5640 + double trans = luaL_checknumber(L, 1); 1.5641 + transparencyModifier = (int)((4.0 - trans) / 4.0 * 255); 1.5642 + if (transparencyModifier < 0) 1.5643 + transparencyModifier = 0; 1.5644 + return 0; 1.5645 +} 1.5646 + 1.5647 +static const uint32 Small_Font_Data[] = 1.5648 + { 1.5649 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 32 1.5650 + 0x00000000, 0x00000300, 0x00000400, 0x00000500, 0x00000000, 0x00000700, 0x00000000, // 33 ! 1.5651 + 0x00000000, 0x00040002, 0x00050003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 34 " 1.5652 + 0x00000000, 0x00040002, 0x00050403, 0x00060004, 0x00070605, 0x00080006, 0x00000000, // 35 # 1.5653 + 0x00000000, 0x00040300, 0x00000403, 0x00000500, 0x00070600, 0x00000706, 0x00000000, // 36 $ 1.5654 + 0x00000000, 0x00000002, 0x00050000, 0x00000500, 0x00000005, 0x00080000, 0x00000000, // 37 % 1.5655 + 0x00000000, 0x00000300, 0x00050003, 0x00000500, 0x00070005, 0x00080700, 0x00000000, // 38 & 1.5656 + 0x00000000, 0x00000300, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 39 ' 1.5657 + 0x00000000, 0x00000300, 0x00000003, 0x00000004, 0x00000005, 0x00000700, 0x00000000, // 40 ( 1.5658 + 0x00000000, 0x00000300, 0x00050000, 0x00060000, 0x00070000, 0x00000700, 0x00000000, // 41 ) 1.5659 + 0x00000000, 0x00000000, 0x00000400, 0x00060504, 0x00000600, 0x00080006, 0x00000000, // 42 * 1.5660 + 0x00000000, 0x00000000, 0x00000400, 0x00060504, 0x00000600, 0x00000000, 0x00000000, // 43 + 1.5661 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000600, 0x00000700, 0x00000007, // 44 , 1.5662 + 0x00000000, 0x00000000, 0x00000000, 0x00060504, 0x00000000, 0x00000000, 0x00000000, // 45 - 1.5663 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000700, 0x00000000, // 46 . 1.5664 + 0x00030000, 0x00040000, 0x00000400, 0x00000500, 0x00000005, 0x00000006, 0x00000000, // 47 / 1.5665 + 0x00000000, 0x00000300, 0x00050003, 0x00060004, 0x00070005, 0x00000700, 0x00000000, // 48 0 1.5666 + 0x00000000, 0x00000300, 0x00000403, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 49 1 1.5667 + 0x00000000, 0x00000302, 0x00050000, 0x00000500, 0x00000005, 0x00080706, 0x00000000, // 50 2 1.5668 + 0x00000000, 0x00000302, 0x00050000, 0x00000504, 0x00070000, 0x00000706, 0x00000000, // 51 3 1.5669 + 0x00000000, 0x00000300, 0x00000003, 0x00060004, 0x00070605, 0x00080000, 0x00000000, // 52 4 1.5670 + 0x00000000, 0x00040302, 0x00000003, 0x00000504, 0x00070000, 0x00000706, 0x00000000, // 53 5 1.5671 + 0x00000000, 0x00000300, 0x00000003, 0x00000504, 0x00070005, 0x00000700, 0x00000000, // 54 6 1.5672 + 0x00000000, 0x00040302, 0x00050000, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 55 7 1.5673 + 0x00000000, 0x00000300, 0x00050003, 0x00000500, 0x00070005, 0x00000700, 0x00000000, // 56 8 1.5674 + 0x00000000, 0x00000300, 0x00050003, 0x00060500, 0x00070000, 0x00000700, 0x00000000, // 57 9 1.5675 + 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000700, 0x00000000, // 58 : 1.5676 + 0x00000000, 0x00000000, 0x00000000, 0x00000500, 0x00000000, 0x00000700, 0x00000007, // 59 ; 1.5677 + 0x00000000, 0x00040000, 0x00000400, 0x00000004, 0x00000600, 0x00080000, 0x00000000, // 60 < 1.5678 + 0x00000000, 0x00000000, 0x00050403, 0x00000000, 0x00070605, 0x00000000, 0x00000000, // 61 = 1.5679 + 0x00000000, 0x00000002, 0x00000400, 0x00060000, 0x00000600, 0x00000006, 0x00000000, // 62 > 1.5680 + 0x00000000, 0x00000302, 0x00050000, 0x00000500, 0x00000000, 0x00000700, 0x00000000, // 63 ? 1.5681 + 0x00000000, 0x00000300, 0x00050400, 0x00060004, 0x00070600, 0x00000000, 0x00000000, // 64 @ 1.5682 + 0x00000000, 0x00000300, 0x00050003, 0x00060504, 0x00070005, 0x00080006, 0x00000000, // 65 A 1.5683 + 0x00000000, 0x00000302, 0x00050003, 0x00000504, 0x00070005, 0x00000706, 0x00000000, // 66 B 1.5684 + 0x00000000, 0x00040300, 0x00000003, 0x00000004, 0x00000005, 0x00080700, 0x00000000, // 67 C 1.5685 + 0x00000000, 0x00000302, 0x00050003, 0x00060004, 0x00070005, 0x00000706, 0x00000000, // 68 D 1.5686 + 0x00000000, 0x00040302, 0x00000003, 0x00000504, 0x00000005, 0x00080706, 0x00000000, // 69 E 1.5687 + 0x00000000, 0x00040302, 0x00000003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 70 F 1.5688 + 0x00000000, 0x00040300, 0x00000003, 0x00060004, 0x00070005, 0x00080700, 0x00000000, // 71 G 1.5689 + 0x00000000, 0x00040002, 0x00050003, 0x00060504, 0x00070005, 0x00080006, 0x00000000, // 72 H 1.5690 + 0x00000000, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 73 I 1.5691 + 0x00000000, 0x00040000, 0x00050000, 0x00060000, 0x00070005, 0x00000700, 0x00000000, // 74 J 1.5692 + 0x00000000, 0x00040002, 0x00050003, 0x00000504, 0x00070005, 0x00080006, 0x00000000, // 75 K 1.5693 + 0x00000000, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00080706, 0x00000000, // 76 l 1.5694 + 0x00000000, 0x00040002, 0x00050403, 0x00060004, 0x00070005, 0x00080006, 0x00000000, // 77 M 1.5695 + 0x00000000, 0x00000302, 0x00050003, 0x00060004, 0x00070005, 0x00080006, 0x00000000, // 78 N 1.5696 + 0x00000000, 0x00040302, 0x00050003, 0x00060004, 0x00070005, 0x00080706, 0x00000000, // 79 O 1.5697 + 0x00000000, 0x00000302, 0x00050003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 80 P 1.5698 + 0x00000000, 0x00040302, 0x00050003, 0x00060004, 0x00070005, 0x00080706, 0x00090000, // 81 Q 1.5699 + 0x00000000, 0x00000302, 0x00050003, 0x00000504, 0x00070005, 0x00080006, 0x00000000, // 82 R 1.5700 + 0x00000000, 0x00040300, 0x00000003, 0x00000500, 0x00070000, 0x00000706, 0x00000000, // 83 S 1.5701 + 0x00000000, 0x00040302, 0x00000400, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 84 T 1.5702 + 0x00000000, 0x00040002, 0x00050003, 0x00060004, 0x00070005, 0x00080706, 0x00000000, // 85 U 1.5703 + 0x00000000, 0x00040002, 0x00050003, 0x00060004, 0x00000600, 0x00000700, 0x00000000, // 86 V 1.5704 + 0x00000000, 0x00040002, 0x00050003, 0x00060004, 0x00070605, 0x00080006, 0x00000000, // 87 W 1.5705 + 0x00000000, 0x00040002, 0x00050003, 0x00000500, 0x00070005, 0x00080006, 0x00000000, // 88 X 1.5706 + 0x00000000, 0x00040002, 0x00050003, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 89 Y 1.5707 + 0x00000000, 0x00040302, 0x00050000, 0x00000500, 0x00000005, 0x00080706, 0x00000000, // 90 Z 1.5708 + 0x00000000, 0x00040300, 0x00000400, 0x00000500, 0x00000600, 0x00080700, 0x00000000, // 91 [ 1.5709 + 0x00000000, 0x00000002, 0x00000400, 0x00000500, 0x00070000, 0x00080000, 0x00000000, // 92 '\' 1.5710 + 0x00000000, 0x00000302, 0x00000400, 0x00000500, 0x00000600, 0x00000706, 0x00000000, // 93 ] 1.5711 + 0x00000000, 0x00000300, 0x00050003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 94 ^ 1.5712 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080706, 0x00000000, // 95 _ 1.5713 + 0x00000000, 0x00000002, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 96 ` 1.5714 + 0x00000000, 0x00000000, 0x00050400, 0x00060004, 0x00070005, 0x00080700, 0x00000000, // 97 a 1.5715 + 0x00000000, 0x00000002, 0x00000003, 0x00000504, 0x00070005, 0x00000706, 0x00000000, // 98 b 1.5716 + 0x00000000, 0x00000000, 0x00050400, 0x00000004, 0x00000005, 0x00080700, 0x00000000, // 99 c 1.5717 + 0x00000000, 0x00040000, 0x00050000, 0x00060500, 0x00070005, 0x00080700, 0x00000000, // 100 d 1.5718 + 0x00000000, 0x00000000, 0x00050400, 0x00060504, 0x00000005, 0x00080700, 0x00000000, // 101 e 1.5719 + 0x00000000, 0x00040300, 0x00000003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 102 f 1.5720 + 0x00000000, 0x00000000, 0x00050400, 0x00060004, 0x00070600, 0x00080000, 0x00000807, // 103 g 1.5721 + 0x00000000, 0x00000002, 0x00000003, 0x00000504, 0x00070005, 0x00080006, 0x00000000, // 104 h 1.5722 + 0x00000000, 0x00000300, 0x00000000, 0x00000500, 0x00000600, 0x00000700, 0x00000000, // 105 i 1.5723 + 0x00000000, 0x00000300, 0x00000000, 0x00000500, 0x00000600, 0x00000700, 0x00000007, // 106 j 1.5724 + 0x00000000, 0x00000002, 0x00000003, 0x00060004, 0x00000605, 0x00080006, 0x00000000, // 107 k 1.5725 + 0x00000000, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00080000, 0x00000000, // 108 l 1.5726 + 0x00000000, 0x00000000, 0x00050003, 0x00060504, 0x00070005, 0x00080006, 0x00000000, // 109 m 1.5727 + 0x00000000, 0x00000000, 0x00000403, 0x00060004, 0x00070005, 0x00080006, 0x00000000, // 110 n 1.5728 + 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00070005, 0x00000700, 0x00000000, // 111 o 1.5729 + 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00000605, 0x00000006, 0x00000007, // 112 p 1.5730 + 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00070600, 0x00080000, 0x00090000, // 113 q 1.5731 + 0x00000000, 0x00000000, 0x00050003, 0x00000504, 0x00000005, 0x00000006, 0x00000000, // 114 r 1.5732 + 0x00000000, 0x00000000, 0x00050400, 0x00000004, 0x00070600, 0x00000706, 0x00000000, // 115 s 1.5733 + 0x00000000, 0x00000300, 0x00050403, 0x00000500, 0x00000600, 0x00080000, 0x00000000, // 116 t 1.5734 + 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00070005, 0x00080700, 0x00000000, // 117 u 1.5735 + 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00070005, 0x00000700, 0x00000000, // 118 v 1.5736 + 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00070605, 0x00080006, 0x00000000, // 119 w 1.5737 + 0x00000000, 0x00000000, 0x00050003, 0x00000500, 0x00070005, 0x00080006, 0x00000000, // 120 x 1.5738 + 0x00000000, 0x00000000, 0x00050003, 0x00060004, 0x00000600, 0x00000700, 0x00000007, // 121 y 1.5739 + 0x00000000, 0x00000000, 0x00050403, 0x00000500, 0x00000005, 0x00080706, 0x00000000, // 122 z 1.5740 + 0x00000000, 0x00040300, 0x00000400, 0x00000504, 0x00000600, 0x00080700, 0x00000000, // 123 { 1.5741 + 0x00000000, 0x00000300, 0x00000400, 0x00000000, 0x00000600, 0x00000700, 0x00000000, // 124 | 1.5742 + 0x00000000, 0x00000302, 0x00000400, 0x00060500, 0x00000600, 0x00000706, 0x00000000, // 125 } 1.5743 + 0x00000000, 0x00000302, 0x00050000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 126 ~ 1.5744 + 0x00000000, 0x00000000, 0x00000400, 0x00060004, 0x00070605, 0x00000000, 0x00000000, // 127 1.5745 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.5746 + }; 1.5747 + 1.5748 +static void PutTextInternal(const char *str, int len, short x, short y, int color, int backcolor) 1.5749 +{ 1.5750 + int Opac = (color >> 24) & 0xFF; 1.5751 + int backOpac = (backcolor >> 24) & 0xFF; 1.5752 + int origX = x; 1.5753 + 1.5754 + if (!Opac && !backOpac) 1.5755 + return; 1.5756 + 1.5757 + while (*str && len && y < LUA_SCREEN_HEIGHT) 1.5758 + { 1.5759 + int c = *str++; 1.5760 + while (x > LUA_SCREEN_WIDTH && c != '\n') 1.5761 + { 1.5762 + c = *str; 1.5763 + if (c == '\0') 1.5764 + break; 1.5765 + str++; 1.5766 + } 1.5767 + 1.5768 + if (c == '\n') 1.5769 + { 1.5770 + x = origX; 1.5771 + y += 8; 1.5772 + continue; 1.5773 + } 1.5774 + else if (c == '\t') // just in case 1.5775 + { 1.5776 + const int tabSpace = 8; 1.5777 + x += (tabSpace - (((x - origX) / 4) % tabSpace)) * 4; 1.5778 + continue; 1.5779 + } 1.5780 + 1.5781 + if ((unsigned int)(c - 32) >= 96) 1.5782 + continue; 1.5783 + 1.5784 + const unsigned char *Cur_Glyph = (const unsigned char *) &Small_Font_Data + (c - 32) * 7 * 4; 1.5785 + 1.5786 + for (int y2 = 0; y2 < 8; y2++) 1.5787 + { 1.5788 + unsigned int glyphLine = *((unsigned int *)Cur_Glyph + y2); 1.5789 + for (int x2 = -1; x2 < 4; x2++) 1.5790 + { 1.5791 + int shift = x2 << 3; 1.5792 + int mask = 0xFF << shift; 1.5793 + int intensity = (glyphLine & mask) >> shift; 1.5794 + 1.5795 + if (intensity && x2 >= 0 && y2 < 7) 1.5796 + { 1.5797 + //int xdraw = max(0,min(LUA_SCREEN_WIDTH - 1,x+x2)); 1.5798 + //int ydraw = max(0,min(LUA_SCREEN_HEIGHT - 1,y+y2)); 1.5799 + //gui_drawpixel_fast(xdraw, ydraw, color); 1.5800 + gui_drawpixel_internal(x + x2, y + y2, color); 1.5801 + } 1.5802 + else if (backOpac) 1.5803 + { 1.5804 + for (int y3 = max(0, y2 - 1); y3 <= min(6, y2 + 1); y3++) 1.5805 + { 1.5806 + unsigned int glyphLine = *((unsigned int *)Cur_Glyph + y3); 1.5807 + for (int x3 = max(0, x2 - 1); x3 <= min(3, x2 + 1); x3++) 1.5808 + { 1.5809 + int shift = x3 << 3; 1.5810 + int mask = 0xFF << shift; 1.5811 + intensity |= (glyphLine & mask) >> shift; 1.5812 + if (intensity) 1.5813 + goto draw_outline; // speedup? 1.5814 + } 1.5815 + } 1.5816 + 1.5817 + draw_outline: 1.5818 + if (intensity) 1.5819 + { 1.5820 + //int xdraw = max(0,min(LUA_SCREEN_WIDTH - 1,x+x2)); 1.5821 + //int ydraw = max(0,min(LUA_SCREEN_HEIGHT - 1,y+y2)); 1.5822 + //gui_drawpixel_fast(xdraw, ydraw, backcolor); 1.5823 + gui_drawpixel_internal(x + x2, y + y2, backcolor); 1.5824 + } 1.5825 + } 1.5826 + } 1.5827 + } 1.5828 + 1.5829 + x += 4; 1.5830 + len--; 1.5831 + } 1.5832 +} 1.5833 + 1.5834 +static int strlinelen(const char *string) 1.5835 +{ 1.5836 + const char *s = string; 1.5837 + while (*s && *s != '\n') 1.5838 + s++; 1.5839 + if (*s) 1.5840 + s++; 1.5841 + return s - string; 1.5842 +} 1.5843 + 1.5844 +static void LuaDisplayString(const char *string, int y, int x, uint32 color, uint32 outlineColor) 1.5845 +{ 1.5846 + if (!string) 1.5847 + return; 1.5848 + 1.5849 + gui_prepare(); 1.5850 + 1.5851 + PutTextInternal(string, strlen(string), x, y, color, outlineColor); 1.5852 + 1.5853 + /* 1.5854 + const char* ptr = string; 1.5855 + while(*ptr && y < LUA_SCREEN_HEIGHT) 1.5856 + { 1.5857 + int len = strlinelen(ptr); 1.5858 + int skip = 0; 1.5859 + if(len < 1) len = 1; 1.5860 + 1.5861 + // break up the line if it's too long to display otherwise 1.5862 + if(len > 63) 1.5863 + { 1.5864 + len = 63; 1.5865 + const char* ptr2 = ptr + len-1; 1.5866 + for(int j = len-1; j; j--, ptr2--) 1.5867 + { 1.5868 + if(*ptr2 == ' ' || *ptr2 == '\t') 1.5869 + { 1.5870 + len = j; 1.5871 + skip = 1; 1.5872 + break; 1.5873 + } 1.5874 + } 1.5875 + } 1.5876 + 1.5877 + int xl = 0; 1.5878 + int yl = 0; 1.5879 + int xh = (LUA_SCREEN_WIDTH - 1 - 1) - 4*len; 1.5880 + int yh = LUA_SCREEN_HEIGHT - 1; 1.5881 + int x2 = min(max(x,xl),xh); 1.5882 + int y2 = min(max(y,yl),yh); 1.5883 + 1.5884 + PutTextInternal(ptr,len,x2,y2,color,outlineColor); 1.5885 + 1.5886 + ptr += len + skip; 1.5887 + y += 8; 1.5888 + } 1.5889 + */ 1.5890 +} 1.5891 1.5892 // gui.text(int x, int y, string msg) 1.5893 // 1.5894 // Displays the given text on the screen, using the same font and techniques as the 1.5895 1.5896 // main HUD. 1.5897 - static int gui_text(lua_State *L) 1.5898 - { 1.5899 - //extern int font_height; 1.5900 - const char *msg; 1.5901 - int x, y; 1.5902 - uint32 colour, borderColour; 1.5903 - 1.5904 - x = luaL_checkinteger(L, 1); 1.5905 - y = luaL_checkinteger(L, 2); 1.5906 - //msg = luaL_checkstring(L, 3); 1.5907 - msg = toCString(L, 3); 1.5908 - 1.5909 - // if (x < 0 || x >= LUA_SCREEN_WIDTH || y < 0 || y >= (LUA_SCREEN_HEIGHT - font_height)) 1.5910 - // luaL_error(L,"bad coordinates"); 1.5911 - colour = gui_optcolour(L, 4, LUA_BUILD_PIXEL(255, 255, 255, 255)); 1.5912 - borderColour = gui_optcolour(L, 5, LUA_BUILD_PIXEL(255, 0, 0, 0)); 1.5913 - 1.5914 - gui_prepare(); 1.5915 - 1.5916 - LuaDisplayString(msg, y, x, colour, borderColour); 1.5917 - 1.5918 - return 0; 1.5919 - } 1.5920 +static int gui_text(lua_State *L) 1.5921 +{ 1.5922 + //extern int font_height; 1.5923 + const char *msg; 1.5924 + int x, y; 1.5925 + uint32 colour, borderColour; 1.5926 + 1.5927 + x = luaL_checkinteger(L, 1); 1.5928 + y = luaL_checkinteger(L, 2); 1.5929 + //msg = luaL_checkstring(L, 3); 1.5930 + msg = toCString(L, 3); 1.5931 + 1.5932 + // if (x < 0 || x >= LUA_SCREEN_WIDTH || y < 0 || y >= (LUA_SCREEN_HEIGHT - font_height)) 1.5933 + // luaL_error(L,"bad coordinates"); 1.5934 + colour = gui_optcolour(L, 4, LUA_BUILD_PIXEL(255, 255, 255, 255)); 1.5935 + borderColour = gui_optcolour(L, 5, LUA_BUILD_PIXEL(255, 0, 0, 0)); 1.5936 + 1.5937 + gui_prepare(); 1.5938 + 1.5939 + LuaDisplayString(msg, y, x, colour, borderColour); 1.5940 + 1.5941 + return 0; 1.5942 +} 1.5943 1.5944 // gui.gdoverlay([int dx=0, int dy=0,] string str [, sx=0, sy=0, sw, sh] [, float alphamul=1.0]) 1.5945 // 1.5946 // Overlays the given image on the screen. 1.5947 1.5948 // example: gui.gdoverlay(gd.createFromPng("myimage.png"):gdStr()) 1.5949 - static int gui_gdoverlay(lua_State *L) 1.5950 - { 1.5951 - int argCount = lua_gettop(L); 1.5952 - 1.5953 - int xStartDst = 0; 1.5954 - int yStartDst = 0; 1.5955 - int xStartSrc = 0; 1.5956 - int yStartSrc = 0; 1.5957 - 1.5958 - int index = 1; 1.5959 - if (lua_type(L, index) == LUA_TNUMBER) 1.5960 - { 1.5961 - xStartDst = lua_tointeger(L, index++); 1.5962 - if (lua_type(L, index) == LUA_TNUMBER) 1.5963 - yStartDst = lua_tointeger(L, index++); 1.5964 - } 1.5965 - 1.5966 - luaL_checktype(L, index, LUA_TSTRING); 1.5967 - 1.5968 - const unsigned char *ptr = (const unsigned char *)lua_tostring(L, index++); 1.5969 - 1.5970 - if (ptr[0] != 255 || (ptr[1] != 254 && ptr[1] != 255)) 1.5971 - luaL_error(L, "bad image data"); 1.5972 - 1.5973 - bool trueColor = (ptr[1] == 254); 1.5974 - ptr += 2; 1.5975 - 1.5976 - int imgwidth = *ptr++ << 8; 1.5977 - imgwidth |= *ptr++; 1.5978 - 1.5979 - int width = imgwidth; 1.5980 - int imgheight = *ptr++ << 8; 1.5981 - imgheight |= *ptr++; 1.5982 - 1.5983 - int height = imgheight; 1.5984 - if ((!trueColor && *ptr) || (trueColor && !*ptr)) 1.5985 - luaL_error(L, "bad image data"); 1.5986 - ptr++; 1.5987 - 1.5988 - int pitch = imgwidth * (trueColor ? 4 : 1); 1.5989 - 1.5990 - if ((argCount - index + 1) >= 4) 1.5991 - { 1.5992 - xStartSrc = luaL_checkinteger(L, index++); 1.5993 - yStartSrc = luaL_checkinteger(L, index++); 1.5994 - width = luaL_checkinteger(L, index++); 1.5995 - height = luaL_checkinteger(L, index++); 1.5996 - } 1.5997 - 1.5998 - int alphaMul = transparencyModifier; 1.5999 - if (lua_isnumber(L, index)) 1.6000 - alphaMul = (int)(alphaMul * lua_tonumber(L, index++)); 1.6001 - if (alphaMul <= 0) 1.6002 - return 0; 1.6003 - 1.6004 - // since there aren't that many possible opacity levels, 1.6005 - // do the opacity modification calculations beforehand instead of per pixel 1.6006 - int opacMap[256]; 1.6007 - for (int i = 0; i < 128; i++) 1.6008 - { 1.6009 - int opac = 255 - ((i << 1) | (i & 1)); // gdAlphaMax = 127, not 255 1.6010 - opac = (opac * alphaMul) / 255; 1.6011 - if (opac < 0) 1.6012 - opac = 0; 1.6013 - if (opac > 255) 1.6014 - opac = 255; 1.6015 - opacMap[i] = opac; 1.6016 - } 1.6017 - 1.6018 - for (int i = 128; i < 256; i++) 1.6019 - opacMap[i] = 0; // what should we do for them, actually? 1.6020 - int colorsTotal = 0; 1.6021 - if (!trueColor) 1.6022 - { 1.6023 - colorsTotal = *ptr++ << 8; 1.6024 - colorsTotal |= *ptr++; 1.6025 - } 1.6026 - 1.6027 - int transparent = *ptr++ << 24; 1.6028 - transparent |= *ptr++ << 16; 1.6029 - transparent |= *ptr++ << 8; 1.6030 - transparent |= *ptr++; 1.6031 - struct 1.6032 - { 1.6033 - uint8 r, g, b, a; 1.6034 - } pal[256]; 1.6035 - if (!trueColor) 1.6036 - for (int i = 0; i < 256; i++) 1.6037 - { 1.6038 - pal[i].r = *ptr++; 1.6039 - pal[i].g = *ptr++; 1.6040 - pal[i].b = *ptr++; 1.6041 - pal[i].a = opacMap[*ptr++]; 1.6042 - } 1.6043 - 1.6044 - // some of clippings 1.6045 - if (xStartSrc < 0) 1.6046 - { 1.6047 - width += xStartSrc; 1.6048 - xStartDst -= xStartSrc; 1.6049 - xStartSrc = 0; 1.6050 - } 1.6051 - 1.6052 - if (yStartSrc < 0) 1.6053 - { 1.6054 - height += yStartSrc; 1.6055 - yStartDst -= yStartSrc; 1.6056 - yStartSrc = 0; 1.6057 - } 1.6058 - 1.6059 - if (xStartSrc + width >= imgwidth) 1.6060 - width = imgwidth - xStartSrc; 1.6061 - if (yStartSrc + height >= imgheight) 1.6062 - height = imgheight - yStartSrc; 1.6063 - if (xStartDst < 0) 1.6064 - { 1.6065 - width += xStartDst; 1.6066 - if (width <= 0) 1.6067 - return 0; 1.6068 - xStartSrc = -xStartDst; 1.6069 - xStartDst = 0; 1.6070 - } 1.6071 - 1.6072 - if (yStartDst < 0) 1.6073 - { 1.6074 - height += yStartDst; 1.6075 - if (height <= 0) 1.6076 - return 0; 1.6077 - yStartSrc = -yStartDst; 1.6078 - yStartDst = 0; 1.6079 - } 1.6080 - 1.6081 - if (xStartDst + width >= LUA_SCREEN_WIDTH) 1.6082 - width = LUA_SCREEN_WIDTH - xStartDst; 1.6083 - if (yStartDst + height >= LUA_SCREEN_HEIGHT) 1.6084 - height = LUA_SCREEN_HEIGHT - yStartDst; 1.6085 - if (width <= 0 || height <= 0) 1.6086 - return 0; // out of screen or invalid size 1.6087 - gui_prepare(); 1.6088 - 1.6089 - const uint8 *pix = (const uint8 *)(&ptr[yStartSrc * pitch + (xStartSrc * (trueColor ? 4 : 1))]); 1.6090 - int bytesToNextLine = pitch - (width * (trueColor ? 4 : 1)); 1.6091 - if (trueColor) 1.6092 - { 1.6093 - for (int y = yStartDst; y < height + yStartDst && y < LUA_SCREEN_HEIGHT; y++, pix += bytesToNextLine) 1.6094 - { 1.6095 - for (int x = xStartDst; x < width + xStartDst && x < LUA_SCREEN_WIDTH; x++, pix += 4) 1.6096 - { 1.6097 - gui_drawpixel_fast(x, y, LUA_BUILD_PIXEL(opacMap[pix[0]], pix[1], pix[2], pix[3])); 1.6098 - } 1.6099 - } 1.6100 - } 1.6101 - else 1.6102 - { 1.6103 - for (int y = yStartDst; y < height + yStartDst && y < LUA_SCREEN_HEIGHT; y++, pix += bytesToNextLine) 1.6104 - { 1.6105 - for (int x = xStartDst; x < width + xStartDst && x < LUA_SCREEN_WIDTH; x++, pix++) 1.6106 - { 1.6107 - gui_drawpixel_fast(x, y, LUA_BUILD_PIXEL(pal[*pix].a, pal[*pix].r, pal[*pix].g, pal[*pix].b)); 1.6108 - } 1.6109 - } 1.6110 - } 1.6111 - 1.6112 - return 0; 1.6113 - } 1.6114 +static int gui_gdoverlay(lua_State *L) 1.6115 +{ 1.6116 + int argCount = lua_gettop(L); 1.6117 + 1.6118 + int xStartDst = 0; 1.6119 + int yStartDst = 0; 1.6120 + int xStartSrc = 0; 1.6121 + int yStartSrc = 0; 1.6122 + 1.6123 + int index = 1; 1.6124 + if (lua_type(L, index) == LUA_TNUMBER) 1.6125 + { 1.6126 + xStartDst = lua_tointeger(L, index++); 1.6127 + if (lua_type(L, index) == LUA_TNUMBER) 1.6128 + yStartDst = lua_tointeger(L, index++); 1.6129 + } 1.6130 + 1.6131 + luaL_checktype(L, index, LUA_TSTRING); 1.6132 + 1.6133 + const unsigned char *ptr = (const unsigned char *)lua_tostring(L, index++); 1.6134 + 1.6135 + if (ptr[0] != 255 || (ptr[1] != 254 && ptr[1] != 255)) 1.6136 + luaL_error(L, "bad image data"); 1.6137 + 1.6138 + bool trueColor = (ptr[1] == 254); 1.6139 + ptr += 2; 1.6140 + 1.6141 + int imgwidth = *ptr++ << 8; 1.6142 + imgwidth |= *ptr++; 1.6143 + 1.6144 + int width = imgwidth; 1.6145 + int imgheight = *ptr++ << 8; 1.6146 + imgheight |= *ptr++; 1.6147 + 1.6148 + int height = imgheight; 1.6149 + if ((!trueColor && *ptr) || (trueColor && !*ptr)) 1.6150 + luaL_error(L, "bad image data"); 1.6151 + ptr++; 1.6152 + 1.6153 + int pitch = imgwidth * (trueColor ? 4 : 1); 1.6154 + 1.6155 + if ((argCount - index + 1) >= 4) 1.6156 + { 1.6157 + xStartSrc = luaL_checkinteger(L, index++); 1.6158 + yStartSrc = luaL_checkinteger(L, index++); 1.6159 + width = luaL_checkinteger(L, index++); 1.6160 + height = luaL_checkinteger(L, index++); 1.6161 + } 1.6162 + 1.6163 + int alphaMul = transparencyModifier; 1.6164 + if (lua_isnumber(L, index)) 1.6165 + alphaMul = (int)(alphaMul * lua_tonumber(L, index++)); 1.6166 + if (alphaMul <= 0) 1.6167 + return 0; 1.6168 + 1.6169 + // since there aren't that many possible opacity levels, 1.6170 + // do the opacity modification calculations beforehand instead of per pixel 1.6171 + int opacMap[256]; 1.6172 + for (int i = 0; i < 128; i++) 1.6173 + { 1.6174 + int opac = 255 - ((i << 1) | (i & 1)); // gdAlphaMax = 127, not 255 1.6175 + opac = (opac * alphaMul) / 255; 1.6176 + if (opac < 0) 1.6177 + opac = 0; 1.6178 + if (opac > 255) 1.6179 + opac = 255; 1.6180 + opacMap[i] = opac; 1.6181 + } 1.6182 + 1.6183 + for (int i = 128; i < 256; i++) 1.6184 + opacMap[i] = 0; // what should we do for them, actually? 1.6185 + int colorsTotal = 0; 1.6186 + if (!trueColor) 1.6187 + { 1.6188 + colorsTotal = *ptr++ << 8; 1.6189 + colorsTotal |= *ptr++; 1.6190 + } 1.6191 + 1.6192 + int transparent = *ptr++ << 24; 1.6193 + transparent |= *ptr++ << 16; 1.6194 + transparent |= *ptr++ << 8; 1.6195 + transparent |= *ptr++; 1.6196 + struct 1.6197 + { 1.6198 + uint8 r, g, b, a; 1.6199 + } pal[256]; 1.6200 + if (!trueColor) 1.6201 + for (int i = 0; i < 256; i++) 1.6202 + { 1.6203 + pal[i].r = *ptr++; 1.6204 + pal[i].g = *ptr++; 1.6205 + pal[i].b = *ptr++; 1.6206 + pal[i].a = opacMap[*ptr++]; 1.6207 + } 1.6208 + 1.6209 + // some of clippings 1.6210 + if (xStartSrc < 0) 1.6211 + { 1.6212 + width += xStartSrc; 1.6213 + xStartDst -= xStartSrc; 1.6214 + xStartSrc = 0; 1.6215 + } 1.6216 + 1.6217 + if (yStartSrc < 0) 1.6218 + { 1.6219 + height += yStartSrc; 1.6220 + yStartDst -= yStartSrc; 1.6221 + yStartSrc = 0; 1.6222 + } 1.6223 + 1.6224 + if (xStartSrc + width >= imgwidth) 1.6225 + width = imgwidth - xStartSrc; 1.6226 + if (yStartSrc + height >= imgheight) 1.6227 + height = imgheight - yStartSrc; 1.6228 + if (xStartDst < 0) 1.6229 + { 1.6230 + width += xStartDst; 1.6231 + if (width <= 0) 1.6232 + return 0; 1.6233 + xStartSrc = -xStartDst; 1.6234 + xStartDst = 0; 1.6235 + } 1.6236 + 1.6237 + if (yStartDst < 0) 1.6238 + { 1.6239 + height += yStartDst; 1.6240 + if (height <= 0) 1.6241 + return 0; 1.6242 + yStartSrc = -yStartDst; 1.6243 + yStartDst = 0; 1.6244 + } 1.6245 + 1.6246 + if (xStartDst + width >= LUA_SCREEN_WIDTH) 1.6247 + width = LUA_SCREEN_WIDTH - xStartDst; 1.6248 + if (yStartDst + height >= LUA_SCREEN_HEIGHT) 1.6249 + height = LUA_SCREEN_HEIGHT - yStartDst; 1.6250 + if (width <= 0 || height <= 0) 1.6251 + return 0; // out of screen or invalid size 1.6252 + gui_prepare(); 1.6253 + 1.6254 + const uint8 *pix = (const uint8 *)(&ptr[yStartSrc * pitch + (xStartSrc * (trueColor ? 4 : 1))]); 1.6255 + int bytesToNextLine = pitch - (width * (trueColor ? 4 : 1)); 1.6256 + if (trueColor) 1.6257 + { 1.6258 + for (int y = yStartDst; y < height + yStartDst && y < LUA_SCREEN_HEIGHT; y++, pix += bytesToNextLine) 1.6259 + { 1.6260 + for (int x = xStartDst; x < width + xStartDst && x < LUA_SCREEN_WIDTH; x++, pix += 4) 1.6261 + { 1.6262 + gui_drawpixel_fast(x, y, LUA_BUILD_PIXEL(opacMap[pix[0]], pix[1], pix[2], pix[3])); 1.6263 + } 1.6264 + } 1.6265 + } 1.6266 + else 1.6267 + { 1.6268 + for (int y = yStartDst; y < height + yStartDst && y < LUA_SCREEN_HEIGHT; y++, pix += bytesToNextLine) 1.6269 + { 1.6270 + for (int x = xStartDst; x < width + xStartDst && x < LUA_SCREEN_WIDTH; x++, pix++) 1.6271 + { 1.6272 + gui_drawpixel_fast(x, y, LUA_BUILD_PIXEL(pal[*pix].a, pal[*pix].r, pal[*pix].g, pal[*pix].b)); 1.6273 + } 1.6274 + } 1.6275 + } 1.6276 + 1.6277 + return 0; 1.6278 +} 1.6279 1.6280 // function gui.register(function f) 1.6281 // 1.6282 @@ -3459,347 +3459,347 @@ 1.6283 // a previously registered function, and the previous function 1.6284 1.6285 // (if any) is returned, or nil if none. 1.6286 - static int gui_register(lua_State *L) 1.6287 - { 1.6288 - // We'll do this straight up. 1.6289 - // First set up the stack. 1.6290 - lua_settop(L, 1); 1.6291 - 1.6292 - // Verify the validity of the entry 1.6293 - if (!lua_isnil(L, 1)) 1.6294 - luaL_checktype(L, 1, LUA_TFUNCTION); 1.6295 - 1.6296 - // Get the old value 1.6297 - lua_getfield(L, LUA_REGISTRYINDEX, guiCallbackTable); 1.6298 - 1.6299 - // Save the new value 1.6300 - lua_pushvalue(L, 1); 1.6301 - lua_setfield(L, LUA_REGISTRYINDEX, guiCallbackTable); 1.6302 - 1.6303 - // The old value is on top of the stack. Return it. 1.6304 - return 1; 1.6305 - } 1.6306 +static int gui_register(lua_State *L) 1.6307 +{ 1.6308 + // We'll do this straight up. 1.6309 + // First set up the stack. 1.6310 + lua_settop(L, 1); 1.6311 + 1.6312 + // Verify the validity of the entry 1.6313 + if (!lua_isnil(L, 1)) 1.6314 + luaL_checktype(L, 1, LUA_TFUNCTION); 1.6315 + 1.6316 + // Get the old value 1.6317 + lua_getfield(L, LUA_REGISTRYINDEX, guiCallbackTable); 1.6318 + 1.6319 + // Save the new value 1.6320 + lua_pushvalue(L, 1); 1.6321 + lua_setfield(L, LUA_REGISTRYINDEX, guiCallbackTable); 1.6322 + 1.6323 + // The old value is on top of the stack. Return it. 1.6324 + return 1; 1.6325 +} 1.6326 1.6327 // string gui.popup(string message, [string type = "ok"]) 1.6328 // 1.6329 1.6330 // Popup dialog! 1.6331 - int gui_popup(lua_State *L) 1.6332 - { 1.6333 - const char *message = luaL_checkstring(L, 1); 1.6334 - const char *type = luaL_optstring(L, 2, "ok"); 1.6335 +int gui_popup(lua_State *L) 1.6336 +{ 1.6337 + const char *message = luaL_checkstring(L, 1); 1.6338 + const char *type = luaL_optstring(L, 2, "ok"); 1.6339 1.6340 #if (defined(WIN32) && !defined(SDL)) 1.6341 - int t; 1.6342 - if (strcmp(type, "ok") == 0) 1.6343 - t = MB_OK; 1.6344 - else if (strcmp(type, "yesno") == 0) 1.6345 - t = MB_YESNO; 1.6346 - else if (strcmp(type, "yesnocancel") == 0) 1.6347 - t = MB_YESNOCANCEL; 1.6348 - else 1.6349 - return luaL_error(L, "invalid popup type \"%s\"", type); 1.6350 - 1.6351 - theApp.winCheckFullscreen(); 1.6352 - systemSoundClearBuffer(); 1.6353 - int result = AfxGetApp()->m_pMainWnd->MessageBox(message, "Lua Script Pop-up", t); 1.6354 - 1.6355 - lua_settop(L, 1); 1.6356 - 1.6357 - if (t != MB_OK) 1.6358 - { 1.6359 - if (result == IDYES) 1.6360 - lua_pushstring(L, "yes"); 1.6361 - else if (result == IDNO) 1.6362 - lua_pushstring(L, "no"); 1.6363 - else if (result == IDCANCEL) 1.6364 - lua_pushstring(L, "cancel"); 1.6365 - else 1.6366 - luaL_error(L, "win32 unrecognized return value %d", result); 1.6367 - return 1; 1.6368 - } 1.6369 - 1.6370 - // else, we don't care. 1.6371 - return 0; 1.6372 + int t; 1.6373 + if (strcmp(type, "ok") == 0) 1.6374 + t = MB_OK; 1.6375 + else if (strcmp(type, "yesno") == 0) 1.6376 + t = MB_YESNO; 1.6377 + else if (strcmp(type, "yesnocancel") == 0) 1.6378 + t = MB_YESNOCANCEL; 1.6379 + else 1.6380 + return luaL_error(L, "invalid popup type \"%s\"", type); 1.6381 + 1.6382 + theApp.winCheckFullscreen(); 1.6383 + systemSoundClearBuffer(); 1.6384 + int result = AfxGetApp()->m_pMainWnd->MessageBox(message, "Lua Script Pop-up", t); 1.6385 + 1.6386 + lua_settop(L, 1); 1.6387 + 1.6388 + if (t != MB_OK) 1.6389 + { 1.6390 + if (result == IDYES) 1.6391 + lua_pushstring(L, "yes"); 1.6392 + else if (result == IDNO) 1.6393 + lua_pushstring(L, "no"); 1.6394 + else if (result == IDCANCEL) 1.6395 + lua_pushstring(L, "cancel"); 1.6396 + else 1.6397 + luaL_error(L, "win32 unrecognized return value %d", result); 1.6398 + return 1; 1.6399 + } 1.6400 + 1.6401 + // else, we don't care. 1.6402 + return 0; 1.6403 #else 1.6404 - char *t; 1.6405 - #ifdef __linux 1.6406 - // The Linux backend has a "FromPause" variable. 1.6407 - // If set to 1, assume some known external event has screwed with the flow of time. 1.6408 - // Since this pauses the emulator waiting for a response, we set it to 1. 1.6409 -// FIXME: Well, actually it doesn't 1.6410 -// extern int FromPause; 1.6411 -// FromPause = 1; 1.6412 - 1.6413 - int pid; // appease compiler 1.6414 - 1.6415 - // Before doing any work, verify the correctness of the parameters. 1.6416 - if (strcmp(type, "ok") == 0) 1.6417 - t = "OK:100"; 1.6418 - else if (strcmp(type, "yesno") == 0) 1.6419 - t = "Yes:100,No:101"; 1.6420 - else if (strcmp(type, "yesnocancel") == 0) 1.6421 - t = "Yes:100,No:101,Cancel:102"; 1.6422 - else 1.6423 - return luaL_error(L, "invalid popup type \"%s\"", type); 1.6424 - 1.6425 - // Can we find a copy of xmessage? Search the path. 1.6426 - char *path = strdup(getenv("PATH")); 1.6427 - 1.6428 - char *current = path; 1.6429 - 1.6430 - char *colon; 1.6431 - 1.6432 - int found = 0; 1.6433 - 1.6434 - while (current) 1.6435 - { 1.6436 - colon = strchr(current, ':'); 1.6437 - 1.6438 - // Clip off the colon. 1.6439 - *colon++ = 0; 1.6440 - 1.6441 - int len = strlen(current); 1.6442 - char *filename = (char *)malloc(len + 12); // always give excess 1.6443 - snprintf(filename, len + 12, "%s/xmessage", current); 1.6444 - 1.6445 - if (access(filename, X_OK) == 0) 1.6446 - { 1.6447 - free(filename); 1.6448 - found = 1; 1.6449 - break; 1.6450 - } 1.6451 - 1.6452 - // Failed, move on. 1.6453 - current = colon; 1.6454 - free(filename); 1.6455 - } 1.6456 - 1.6457 - free(path); 1.6458 - 1.6459 - // We've found it? 1.6460 - if (!found) 1.6461 - goto use_console; 1.6462 - 1.6463 - pid = fork(); 1.6464 - if (pid == 0) 1.6465 - { // I'm the virgin sacrifice 1.6466 - // I'm gonna be dead in a matter of microseconds anyways, so wasted memory doesn't matter to me. 1.6467 - // Go ahead and abuse strdup. 1.6468 - char *parameters[] = { "xmessage", "-buttons", t, strdup(message), NULL }; 1.6469 - 1.6470 - execvp("xmessage", parameters); 1.6471 - 1.6472 - // Aw shitty 1.6473 - perror("exec xmessage"); 1.6474 - exit(1); 1.6475 - } 1.6476 - else if (pid < 0) // something went wrong!!! Oh hell... use the console 1.6477 - goto use_console; 1.6478 - else 1.6479 - { 1.6480 - // We're the parent. Watch for the child. 1.6481 - int r; 1.6482 - int res = waitpid(pid, &r, 0); 1.6483 - if (res < 0) // wtf? 1.6484 - goto use_console; 1.6485 - 1.6486 - // The return value gets copmlicated... 1.6487 - if (!WIFEXITED(r)) 1.6488 - { 1.6489 - luaL_error(L, "don't screw with my xmessage process!"); 1.6490 - } 1.6491 - 1.6492 - r = WEXITSTATUS(r); 1.6493 - 1.6494 - // We assume it's worked. 1.6495 - if (r == 0) 1.6496 - { 1.6497 - return 0; // no parameters for an OK 1.6498 - } 1.6499 - 1.6500 - if (r == 100) 1.6501 - { 1.6502 - lua_pushstring(L, "yes"); 1.6503 - return 1; 1.6504 - } 1.6505 - 1.6506 - if (r == 101) 1.6507 - { 1.6508 - lua_pushstring(L, "no"); 1.6509 - return 1; 1.6510 - } 1.6511 - 1.6512 - if (r == 102) 1.6513 - { 1.6514 - lua_pushstring(L, "cancel"); 1.6515 - return 1; 1.6516 - } 1.6517 - 1.6518 - // Wtf? 1.6519 - return luaL_error(L, "popup failed due to unknown results involving xmessage (%d)", r); 1.6520 - } 1.6521 - 1.6522 -use_console: 1.6523 - #endif 1.6524 - 1.6525 - // All else has failed 1.6526 - if (strcmp(type, "ok") == 0) 1.6527 - t = ""; 1.6528 - else if (strcmp(type, "yesno") == 0) 1.6529 - t = "yn"; 1.6530 - else if (strcmp(type, "yesnocancel") == 0) 1.6531 - t = "ync"; 1.6532 - else 1.6533 - return luaL_error(L, "invalid popup type \"%s\"", type); 1.6534 - 1.6535 - fprintf(stderr, "Lua Message: %s\n", message); 1.6536 - 1.6537 - while (true) 1.6538 - { 1.6539 - char buffer[64]; 1.6540 - 1.6541 - // We don't want parameters 1.6542 - if (!t[0]) 1.6543 - { 1.6544 - fprintf(stderr, "[Press Enter]"); 1.6545 - fgets(buffer, sizeof(buffer), stdin); 1.6546 - 1.6547 - // We're done 1.6548 - return 0; 1.6549 - } 1.6550 - 1.6551 - fprintf(stderr, "(%s): ", t); 1.6552 - fgets(buffer, sizeof(buffer), stdin); 1.6553 - 1.6554 - // Check if the option is in the list 1.6555 - if (strchr(t, tolower(buffer[0]))) 1.6556 - { 1.6557 - switch (tolower(buffer[0])) 1.6558 - { 1.6559 - case 'y': 1.6560 - lua_pushstring(L, "yes"); 1.6561 - return 1; 1.6562 - case 'n': 1.6563 - lua_pushstring(L, "no"); 1.6564 - return 1; 1.6565 - case 'c': 1.6566 - lua_pushstring(L, "cancel"); 1.6567 - return 1; 1.6568 - default: 1.6569 - luaL_error(L, "internal logic error in console based prompts for gui.popup"); 1.6570 - } 1.6571 - } 1.6572 - 1.6573 - // We fell through, so we assume the user answered wrong and prompt again. 1.6574 - } 1.6575 - 1.6576 - // Nothing here, since the only way out is in the loop. 1.6577 + char *t; 1.6578 +#ifdef __linux 1.6579 + // The Linux backend has a "FromPause" variable. 1.6580 + // If set to 1, assume some known external event has screwed with the flow of time. 1.6581 + // Since this pauses the emulator waiting for a response, we set it to 1. 1.6582 + // FIXME: Well, actually it doesn't 1.6583 + // extern int FromPause; 1.6584 + // FromPause = 1; 1.6585 + 1.6586 + int pid; // appease compiler 1.6587 + 1.6588 + // Before doing any work, verify the correctness of the parameters. 1.6589 + if (strcmp(type, "ok") == 0) 1.6590 + t = "OK:100"; 1.6591 + else if (strcmp(type, "yesno") == 0) 1.6592 + t = "Yes:100,No:101"; 1.6593 + else if (strcmp(type, "yesnocancel") == 0) 1.6594 + t = "Yes:100,No:101,Cancel:102"; 1.6595 + else 1.6596 + return luaL_error(L, "invalid popup type \"%s\"", type); 1.6597 + 1.6598 + // Can we find a copy of xmessage? Search the path. 1.6599 + char *path = strdup(getenv("PATH")); 1.6600 + 1.6601 + char *current = path; 1.6602 + 1.6603 + char *colon; 1.6604 + 1.6605 + int found = 0; 1.6606 + 1.6607 + while (current) 1.6608 + { 1.6609 + colon = strchr(current, ':'); 1.6610 + 1.6611 + // Clip off the colon. 1.6612 + *colon++ = 0; 1.6613 + 1.6614 + int len = strlen(current); 1.6615 + char *filename = (char *)malloc(len + 12); // always give excess 1.6616 + snprintf(filename, len + 12, "%s/xmessage", current); 1.6617 + 1.6618 + if (access(filename, X_OK) == 0) 1.6619 + { 1.6620 + free(filename); 1.6621 + found = 1; 1.6622 + break; 1.6623 + } 1.6624 + 1.6625 + // Failed, move on. 1.6626 + current = colon; 1.6627 + free(filename); 1.6628 + } 1.6629 + 1.6630 + free(path); 1.6631 + 1.6632 + // We've found it? 1.6633 + if (!found) 1.6634 + goto use_console; 1.6635 + 1.6636 + pid = fork(); 1.6637 + if (pid == 0) 1.6638 + { // I'm the virgin sacrifice 1.6639 + // I'm gonna be dead in a matter of microseconds anyways, so wasted memory doesn't matter to me. 1.6640 + // Go ahead and abuse strdup. 1.6641 + char *parameters[] = { "xmessage", "-buttons", t, strdup(message), NULL }; 1.6642 + 1.6643 + execvp("xmessage", parameters); 1.6644 + 1.6645 + // Aw shitty 1.6646 + perror("exec xmessage"); 1.6647 + exit(1); 1.6648 + } 1.6649 + else if (pid < 0) // something went wrong!!! Oh hell... use the console 1.6650 + goto use_console; 1.6651 + else 1.6652 + { 1.6653 + // We're the parent. Watch for the child. 1.6654 + int r; 1.6655 + int res = waitpid(pid, &r, 0); 1.6656 + if (res < 0) // wtf? 1.6657 + goto use_console; 1.6658 + 1.6659 + // The return value gets copmlicated... 1.6660 + if (!WIFEXITED(r)) 1.6661 + { 1.6662 + luaL_error(L, "don't screw with my xmessage process!"); 1.6663 + } 1.6664 + 1.6665 + r = WEXITSTATUS(r); 1.6666 + 1.6667 + // We assume it's worked. 1.6668 + if (r == 0) 1.6669 + { 1.6670 + return 0; // no parameters for an OK 1.6671 + } 1.6672 + 1.6673 + if (r == 100) 1.6674 + { 1.6675 + lua_pushstring(L, "yes"); 1.6676 + return 1; 1.6677 + } 1.6678 + 1.6679 + if (r == 101) 1.6680 + { 1.6681 + lua_pushstring(L, "no"); 1.6682 + return 1; 1.6683 + } 1.6684 + 1.6685 + if (r == 102) 1.6686 + { 1.6687 + lua_pushstring(L, "cancel"); 1.6688 + return 1; 1.6689 + } 1.6690 + 1.6691 + // Wtf? 1.6692 + return luaL_error(L, "popup failed due to unknown results involving xmessage (%d)", r); 1.6693 + } 1.6694 + 1.6695 + use_console: 1.6696 #endif 1.6697 - } 1.6698 + 1.6699 + // All else has failed 1.6700 + if (strcmp(type, "ok") == 0) 1.6701 + t = ""; 1.6702 + else if (strcmp(type, "yesno") == 0) 1.6703 + t = "yn"; 1.6704 + else if (strcmp(type, "yesnocancel") == 0) 1.6705 + t = "ync"; 1.6706 + else 1.6707 + return luaL_error(L, "invalid popup type \"%s\"", type); 1.6708 + 1.6709 + fprintf(stderr, "Lua Message: %s\n", message); 1.6710 + 1.6711 + while (true) 1.6712 + { 1.6713 + char buffer[64]; 1.6714 + 1.6715 + // We don't want parameters 1.6716 + if (!t[0]) 1.6717 + { 1.6718 + fprintf(stderr, "[Press Enter]"); 1.6719 + fgets(buffer, sizeof(buffer), stdin); 1.6720 + 1.6721 + // We're done 1.6722 + return 0; 1.6723 + } 1.6724 + 1.6725 + fprintf(stderr, "(%s): ", t); 1.6726 + fgets(buffer, sizeof(buffer), stdin); 1.6727 + 1.6728 + // Check if the option is in the list 1.6729 + if (strchr(t, tolower(buffer[0]))) 1.6730 + { 1.6731 + switch (tolower(buffer[0])) 1.6732 + { 1.6733 + case 'y': 1.6734 + lua_pushstring(L, "yes"); 1.6735 + return 1; 1.6736 + case 'n': 1.6737 + lua_pushstring(L, "no"); 1.6738 + return 1; 1.6739 + case 'c': 1.6740 + lua_pushstring(L, "cancel"); 1.6741 + return 1; 1.6742 + default: 1.6743 + luaL_error(L, "internal logic error in console based prompts for gui.popup"); 1.6744 + } 1.6745 + } 1.6746 + 1.6747 + // We fell through, so we assume the user answered wrong and prompt again. 1.6748 + } 1.6749 + 1.6750 + // Nothing here, since the only way out is in the loop. 1.6751 +#endif 1.6752 +} 1.6753 1.6754 #if (defined(WIN32) && !defined(SDL)) 1.6755 - const char *s_keyToName[256] = 1.6756 - { 1.6757 - NULL, 1.6758 - "leftclick", 1.6759 - "rightclick", 1.6760 - NULL, 1.6761 - "middleclick", 1.6762 - NULL, 1.6763 - NULL, 1.6764 - NULL, 1.6765 - "backspace", 1.6766 - "tab", 1.6767 - NULL, 1.6768 - NULL, 1.6769 - NULL, 1.6770 - "enter", 1.6771 - NULL, 1.6772 - NULL, 1.6773 - "shift", // 0x10 1.6774 - "control", 1.6775 - "alt", 1.6776 - "pause", 1.6777 - "capslock", 1.6778 - NULL, 1.6779 - NULL, 1.6780 - NULL, 1.6781 - NULL, 1.6782 - NULL, 1.6783 - NULL, 1.6784 - "escape", 1.6785 - NULL, 1.6786 - NULL, 1.6787 - NULL, 1.6788 - NULL, 1.6789 - "space", // 0x20 1.6790 - "pageup", 1.6791 - "pagedown", 1.6792 - "end", 1.6793 - "home", 1.6794 - "left", 1.6795 - "up", 1.6796 - "right", 1.6797 - "down", 1.6798 - NULL, 1.6799 - NULL, 1.6800 - NULL, 1.6801 - NULL, 1.6802 - "insert", 1.6803 - "delete", 1.6804 - NULL, 1.6805 - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 1.6806 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6807 - "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", 1.6808 - "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", 1.6809 - "U", "V", "W", "X", "Y", "Z", 1.6810 - NULL, 1.6811 - NULL, 1.6812 - NULL, 1.6813 - NULL, 1.6814 - NULL, 1.6815 - "numpad0", "numpad1", "numpad2", "numpad3", "numpad4", "numpad5", "numpad6", "numpad7", "numpad8", "numpad9", 1.6816 - "numpad*", "numpad+", 1.6817 - NULL, 1.6818 - "numpad-", "numpad.", "numpad/", 1.6819 - "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", 1.6820 - "F12", 1.6821 - "F13", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23", 1.6822 - "F24", 1.6823 - NULL, 1.6824 - NULL, 1.6825 - NULL, 1.6826 - NULL, 1.6827 - NULL, 1.6828 - NULL, 1.6829 - NULL, 1.6830 - NULL, 1.6831 - "numlock", 1.6832 - "scrolllock", 1.6833 - NULL, // 0x92 1.6834 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6835 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6836 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6837 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6838 - NULL, // 0xB9 1.6839 - "semicolon", 1.6840 - "plus", 1.6841 - "comma", 1.6842 - "minus", 1.6843 - "period", 1.6844 - "slash", 1.6845 - "tilde", 1.6846 - NULL, // 0xC1 1.6847 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6848 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6849 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6850 - NULL, // 0xDA 1.6851 - "leftbracket", 1.6852 - "backslash", 1.6853 - "rightbracket", 1.6854 - "quote", 1.6855 - }; 1.6856 +const char *s_keyToName[256] = 1.6857 + { 1.6858 + NULL, 1.6859 + "leftclick", 1.6860 + "rightclick", 1.6861 + NULL, 1.6862 + "middleclick", 1.6863 + NULL, 1.6864 + NULL, 1.6865 + NULL, 1.6866 + "backspace", 1.6867 + "tab", 1.6868 + NULL, 1.6869 + NULL, 1.6870 + NULL, 1.6871 + "enter", 1.6872 + NULL, 1.6873 + NULL, 1.6874 + "shift", // 0x10 1.6875 + "control", 1.6876 + "alt", 1.6877 + "pause", 1.6878 + "capslock", 1.6879 + NULL, 1.6880 + NULL, 1.6881 + NULL, 1.6882 + NULL, 1.6883 + NULL, 1.6884 + NULL, 1.6885 + "escape", 1.6886 + NULL, 1.6887 + NULL, 1.6888 + NULL, 1.6889 + NULL, 1.6890 + "space", // 0x20 1.6891 + "pageup", 1.6892 + "pagedown", 1.6893 + "end", 1.6894 + "home", 1.6895 + "left", 1.6896 + "up", 1.6897 + "right", 1.6898 + "down", 1.6899 + NULL, 1.6900 + NULL, 1.6901 + NULL, 1.6902 + NULL, 1.6903 + "insert", 1.6904 + "delete", 1.6905 + NULL, 1.6906 + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 1.6907 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6908 + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", 1.6909 + "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", 1.6910 + "U", "V", "W", "X", "Y", "Z", 1.6911 + NULL, 1.6912 + NULL, 1.6913 + NULL, 1.6914 + NULL, 1.6915 + NULL, 1.6916 + "numpad0", "numpad1", "numpad2", "numpad3", "numpad4", "numpad5", "numpad6", "numpad7", "numpad8", "numpad9", 1.6917 + "numpad*", "numpad+", 1.6918 + NULL, 1.6919 + "numpad-", "numpad.", "numpad/", 1.6920 + "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", 1.6921 + "F12", 1.6922 + "F13", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23", 1.6923 + "F24", 1.6924 + NULL, 1.6925 + NULL, 1.6926 + NULL, 1.6927 + NULL, 1.6928 + NULL, 1.6929 + NULL, 1.6930 + NULL, 1.6931 + NULL, 1.6932 + "numlock", 1.6933 + "scrolllock", 1.6934 + NULL, // 0x92 1.6935 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6936 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6937 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6938 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6939 + NULL, // 0xB9 1.6940 + "semicolon", 1.6941 + "plus", 1.6942 + "comma", 1.6943 + "minus", 1.6944 + "period", 1.6945 + "slash", 1.6946 + "tilde", 1.6947 + NULL, // 0xC1 1.6948 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6949 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6950 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.6951 + NULL, // 0xDA 1.6952 + "leftbracket", 1.6953 + "backslash", 1.6954 + "rightbracket", 1.6955 + "quote", 1.6956 + }; 1.6957 #endif 1.6958 1.6959 // input.get() 1.6960 @@ -3810,412 +3810,412 @@ 1.6961 // and has the mouse at the bottom-right corner of the game screen, 1.6962 1.6963 // then this would return {W=true, leftclick=true, xmouse=255, ymouse=223} 1.6964 - static int input_getcurrentinputstatus(lua_State *L) 1.6965 - { 1.6966 - lua_newtable(L); 1.6967 +static int input_getcurrentinputstatus(lua_State *L) 1.6968 +{ 1.6969 + lua_newtable(L); 1.6970 1.6971 #if (defined(WIN32) && !defined(SDL)) 1.6972 - // keyboard and mouse button status 1.6973 - { 1.6974 - unsigned char keys[256]; 1.6975 - if (true /*!GUI.BackgroundInput*/) // TODO: background input 1.6976 - { 1.6977 - if (GetKeyboardState(keys)) 1.6978 - { 1.6979 - for (int i = 1; i < 255; i++) 1.6980 - { 1.6981 - int mask = (i == VK_CAPITAL || i == VK_NUMLOCK || i == VK_SCROLL) ? 0x01 : 0x80; 1.6982 - if (keys[i] & mask) 1.6983 - { 1.6984 - const char *name = s_keyToName[i]; 1.6985 - if (name) 1.6986 - { 1.6987 - lua_pushboolean(L, true); 1.6988 - lua_setfield(L, -2, name); 1.6989 - } 1.6990 - } 1.6991 - } 1.6992 - } 1.6993 - } 1.6994 - else // use a slightly different method that will detect background input: 1.6995 - { 1.6996 - for (int i = 1; i < 255; i++) 1.6997 - { 1.6998 - const char *name = s_keyToName[i]; 1.6999 - if (name) 1.7000 - { 1.7001 - int active; 1.7002 - if (i == VK_CAPITAL || i == VK_NUMLOCK || i == VK_SCROLL) 1.7003 - active = GetKeyState(i) & 0x01; 1.7004 - else 1.7005 - active = GetAsyncKeyState(i) & 0x8000; 1.7006 - if (active) 1.7007 - { 1.7008 - lua_pushboolean(L, true); 1.7009 - lua_setfield(L, -2, name); 1.7010 - } 1.7011 - } 1.7012 - } 1.7013 - } 1.7014 - } 1.7015 - 1.7016 - // mouse position in game screen pixel coordinates 1.7017 - { 1.7018 - POINT mouse; 1.7019 - 1.7020 - int xofs = 0, yofs = 0, width = 240, height = 160; 1.7021 - if (!systemIsRunningGBA()) 1.7022 - { 1.7023 - if (gbBorderOn) 1.7024 - width = 256, height = 224, xofs = 48, yofs = 40; 1.7025 - else 1.7026 - width = 160, height = 144; 1.7027 - } 1.7028 - 1.7029 - GetCursorPos(&mouse); 1.7030 - AfxGetApp()->m_pMainWnd->ScreenToClient(&mouse); 1.7031 - 1.7032 - // game screen is always fully stretched to window size, 1.7033 - // with no aspect rate correction, or something like that. 1.7034 - RECT clientRect; 1.7035 - AfxGetApp()->m_pMainWnd->GetClientRect(&clientRect); 1.7036 - 1.7037 - int wndWidth = clientRect.right - clientRect.left; 1.7038 - int wndHeight = clientRect.bottom - clientRect.top; 1.7039 - mouse.x = (LONG) (mouse.x * ((float)width / wndWidth)) - xofs; 1.7040 - mouse.y = (LONG) (mouse.y * ((float)height / wndHeight)) - yofs; 1.7041 - 1.7042 - lua_pushinteger(L, mouse.x); 1.7043 - lua_setfield(L, -2, "xmouse"); 1.7044 - lua_pushinteger(L, mouse.y); 1.7045 - lua_setfield(L, -2, "ymouse"); 1.7046 - } 1.7047 + // keyboard and mouse button status 1.7048 + { 1.7049 + unsigned char keys[256]; 1.7050 + if (true /*!GUI.BackgroundInput*/) // TODO: background input 1.7051 + { 1.7052 + if (GetKeyboardState(keys)) 1.7053 + { 1.7054 + for (int i = 1; i < 255; i++) 1.7055 + { 1.7056 + int mask = (i == VK_CAPITAL || i == VK_NUMLOCK || i == VK_SCROLL) ? 0x01 : 0x80; 1.7057 + if (keys[i] & mask) 1.7058 + { 1.7059 + const char *name = s_keyToName[i]; 1.7060 + if (name) 1.7061 + { 1.7062 + lua_pushboolean(L, true); 1.7063 + lua_setfield(L, -2, name); 1.7064 + } 1.7065 + } 1.7066 + } 1.7067 + } 1.7068 + } 1.7069 + else // use a slightly different method that will detect background input: 1.7070 + { 1.7071 + for (int i = 1; i < 255; i++) 1.7072 + { 1.7073 + const char *name = s_keyToName[i]; 1.7074 + if (name) 1.7075 + { 1.7076 + int active; 1.7077 + if (i == VK_CAPITAL || i == VK_NUMLOCK || i == VK_SCROLL) 1.7078 + active = GetKeyState(i) & 0x01; 1.7079 + else 1.7080 + active = GetAsyncKeyState(i) & 0x8000; 1.7081 + if (active) 1.7082 + { 1.7083 + lua_pushboolean(L, true); 1.7084 + lua_setfield(L, -2, name); 1.7085 + } 1.7086 + } 1.7087 + } 1.7088 + } 1.7089 + } 1.7090 + 1.7091 + // mouse position in game screen pixel coordinates 1.7092 + { 1.7093 + POINT mouse; 1.7094 + 1.7095 + int xofs = 0, yofs = 0, width = 240, height = 160; 1.7096 + if (!systemIsRunningGBA()) 1.7097 + { 1.7098 + if (gbBorderOn) 1.7099 + width = 256, height = 224, xofs = 48, yofs = 40; 1.7100 + else 1.7101 + width = 160, height = 144; 1.7102 + } 1.7103 + 1.7104 + GetCursorPos(&mouse); 1.7105 + AfxGetApp()->m_pMainWnd->ScreenToClient(&mouse); 1.7106 + 1.7107 + // game screen is always fully stretched to window size, 1.7108 + // with no aspect rate correction, or something like that. 1.7109 + RECT clientRect; 1.7110 + AfxGetApp()->m_pMainWnd->GetClientRect(&clientRect); 1.7111 + 1.7112 + int wndWidth = clientRect.right - clientRect.left; 1.7113 + int wndHeight = clientRect.bottom - clientRect.top; 1.7114 + mouse.x = (LONG) (mouse.x * ((float)width / wndWidth)) - xofs; 1.7115 + mouse.y = (LONG) (mouse.y * ((float)height / wndHeight)) - yofs; 1.7116 + 1.7117 + lua_pushinteger(L, mouse.x); 1.7118 + lua_setfield(L, -2, "xmouse"); 1.7119 + lua_pushinteger(L, mouse.y); 1.7120 + lua_setfield(L, -2, "ymouse"); 1.7121 + } 1.7122 1.7123 #else 1.7124 - // NYI (well, return an empty table) 1.7125 + // NYI (well, return an empty table) 1.7126 #endif 1.7127 - return 1; 1.7128 - } 1.7129 - 1.7130 - static int avi_framecount(lua_State *L) 1.7131 - { 1.7132 - #ifdef WIN32 1.7133 - if (theApp.aviRecorder != NULL) 1.7134 - { 1.7135 - lua_pushinteger(L, theApp.aviRecorder->videoFrames()); 1.7136 - } 1.7137 - else 1.7138 - #endif 1.7139 - { 1.7140 - lua_pushinteger(L, 0); 1.7141 - } 1.7142 - return 1; 1.7143 - } 1.7144 - 1.7145 - static int avi_pause(lua_State *L) 1.7146 - { 1.7147 - #ifdef WIN32 1.7148 - if (theApp.aviRecorder != NULL) 1.7149 - theApp.aviRecorder->Pause(true); 1.7150 - #endif 1.7151 - return 1; 1.7152 - } 1.7153 - 1.7154 - static int avi_resume(lua_State *L) 1.7155 - { 1.7156 - #ifdef WIN32 1.7157 - if (theApp.aviRecorder != NULL) 1.7158 - theApp.aviRecorder->Pause(false); 1.7159 - #endif 1.7160 - return 1; 1.7161 - } 1.7162 - 1.7163 - static int sound_get(lua_State *L) 1.7164 - { 1.7165 - extern int32 soundLevel1; 1.7166 - extern int32 soundLevel2; 1.7167 - extern int32 soundBalance; 1.7168 - extern int32 soundMasterOn; 1.7169 - extern int32 soundVIN; 1.7170 - extern int32 sound1On; 1.7171 - extern int32 sound1EnvelopeVolume; 1.7172 - extern int32 sound2On; 1.7173 - extern int32 sound2EnvelopeVolume; 1.7174 - extern int32 sound3On; 1.7175 - extern int32 sound3OutputLevel; 1.7176 - extern int32 sound3Bank; 1.7177 - extern int32 sound3DataSize; 1.7178 - extern int32 sound3ForcedOutput; 1.7179 - extern int32 sound4On; 1.7180 - extern int32 sound4EnvelopeVolume; 1.7181 - extern u8 sound3WaveRam[0x20]; 1.7182 - 1.7183 - int freqReg; 1.7184 - double freq; 1.7185 - double leftvolscale; 1.7186 - double rightvolscale; 1.7187 - double panpot; 1.7188 - bool gba = systemIsRunningGBA(); 1.7189 - u8* gbMem = gba ? ioMem : gbMemory; 1.7190 - const int rNR10 = gba ? 0x60 : 0xff10; 1.7191 - const int rNR11 = gba ? 0x62 : 0xff11; 1.7192 - const int rNR12 = gba ? 0x63 : 0xff12; 1.7193 - const int rNR13 = gba ? 0x64 : 0xff13; 1.7194 - const int rNR14 = gba ? 0x65 : 0xff14; 1.7195 - const int rNR21 = gba ? 0x68 : 0xff16; 1.7196 - const int rNR22 = gba ? 0x69 : 0xff17; 1.7197 - const int rNR23 = gba ? 0x6c : 0xff18; 1.7198 - const int rNR24 = gba ? 0x6d : 0xff19; 1.7199 - const int rNR30 = gba ? 0x70 : 0xff1a; 1.7200 - const int rNR31 = gba ? 0x72 : 0xff1b; 1.7201 - const int rNR32 = gba ? 0x73 : 0xff1c; 1.7202 - const int rNR33 = gba ? 0x74 : 0xff1d; 1.7203 - const int rNR34 = gba ? 0x75 : 0xff1e; 1.7204 - const int rNR41 = gba ? 0x78 : 0xff20; 1.7205 - const int rNR42 = gba ? 0x79 : 0xff21; 1.7206 - const int rNR43 = gba ? 0x7c : 0xff22; 1.7207 - const int rNR44 = gba ? 0x7d : 0xff23; 1.7208 - const int rNR50 = gba ? 0x80 : 0xff24; 1.7209 - const int rNR51 = gba ? 0x81 : 0xff25; 1.7210 - const int rNR52 = gba ? 0x84 : 0xff26; 1.7211 - const int rWAVE_RAM = gba ? 0x90 : 0xff30; 1.7212 - 1.7213 - const int32 _soundVIN = 0x88; // gba ? 0x88 : soundVIN; 1.7214 - const bool soundVINLeft = ((_soundVIN & 0x80) != 0); 1.7215 - const bool soundVINRight = ((_soundVIN & 0x08) != 0); 1.7216 - 1.7217 - lua_newtable(L); 1.7218 - 1.7219 - // square1 1.7220 - lua_newtable(L); 1.7221 - if(sound1On == 0 || soundMasterOn == 0) 1.7222 - { 1.7223 - lua_pushnumber(L, 0.0); 1.7224 - panpot = 0.5; 1.7225 - } 1.7226 - else 1.7227 - { 1.7228 - double envVolume = sound1EnvelopeVolume / 15.0; 1.7229 - if (soundVINLeft && (soundBalance & 0x10) != 0) 1.7230 - leftvolscale = ((soundLevel2 / 7.0) * envVolume); 1.7231 - else 1.7232 - leftvolscale = 0.0; 1.7233 - if (soundVINRight && (soundBalance & 0x01) != 0) 1.7234 - rightvolscale = ((soundLevel1 / 7.0) * envVolume); 1.7235 - else 1.7236 - rightvolscale = 0.0; 1.7237 - if ((leftvolscale + rightvolscale) != 0) 1.7238 - panpot = rightvolscale / (leftvolscale + rightvolscale); 1.7239 - else 1.7240 - panpot = 0.5; 1.7241 - lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 1.7242 - } 1.7243 - lua_setfield(L, -2, "volume"); 1.7244 - lua_pushnumber(L, panpot); 1.7245 - lua_setfield(L, -2, "panpot"); 1.7246 - freqReg = (((int)(gbMem[rNR14] & 7) << 8) | gbMem[rNR13]); 1.7247 - freq = 131072.0 / (2048 - freqReg); 1.7248 - lua_pushnumber(L, freq); 1.7249 - lua_setfield(L, -2, "frequency"); 1.7250 - lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 1.7251 - lua_setfield(L, -2, "midikey"); 1.7252 - lua_pushinteger(L, (gbMem[rNR11] & 0xC0) >> 6); 1.7253 - lua_setfield(L, -2, "duty"); 1.7254 - lua_newtable(L); 1.7255 - lua_pushinteger(L, freqReg); 1.7256 - lua_setfield(L, -2, "frequency"); 1.7257 - lua_setfield(L, -2, "regs"); 1.7258 - lua_setfield(L, -2, "square1"); 1.7259 - // square2 1.7260 - lua_newtable(L); 1.7261 - if(sound2On == 0 || soundMasterOn == 0) 1.7262 - { 1.7263 - lua_pushnumber(L, 0.0); 1.7264 - panpot = 0.5; 1.7265 - } 1.7266 - else 1.7267 - { 1.7268 - double envVolume = sound2EnvelopeVolume / 15.0; 1.7269 - if (soundVINLeft && (soundBalance & 0x20) != 0) 1.7270 - leftvolscale = ((soundLevel2 / 7.0) * envVolume); 1.7271 - else 1.7272 - leftvolscale = 0.0; 1.7273 - if (soundVINRight && (soundBalance & 0x02) != 0) 1.7274 - rightvolscale = ((soundLevel1 / 7.0) * envVolume); 1.7275 - else 1.7276 - rightvolscale = 0.0; 1.7277 - if ((leftvolscale + rightvolscale) != 0) 1.7278 - panpot = rightvolscale / (leftvolscale + rightvolscale); 1.7279 - else 1.7280 - panpot = 0.5; 1.7281 - lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 1.7282 - } 1.7283 - lua_setfield(L, -2, "volume"); 1.7284 - lua_pushnumber(L, panpot); 1.7285 - lua_setfield(L, -2, "panpot"); 1.7286 - freqReg = (((int)(gbMem[rNR24] & 7) << 8) | gbMem[rNR23]); 1.7287 - freq = 131072.0 / (2048 - freqReg); 1.7288 - lua_pushnumber(L, freq); 1.7289 - lua_setfield(L, -2, "frequency"); 1.7290 - lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 1.7291 - lua_setfield(L, -2, "midikey"); 1.7292 - lua_pushinteger(L, (gbMem[rNR21] & 0xC0) >> 6); 1.7293 - lua_setfield(L, -2, "duty"); 1.7294 - lua_newtable(L); 1.7295 - lua_pushinteger(L, freqReg); 1.7296 - lua_setfield(L, -2, "frequency"); 1.7297 - lua_setfield(L, -2, "regs"); 1.7298 - lua_setfield(L, -2, "square2"); 1.7299 - // wavememory 1.7300 - lua_newtable(L); 1.7301 - if(sound3On == 0 || soundMasterOn == 0) 1.7302 - { 1.7303 - lua_pushnumber(L, 0.0); 1.7304 - panpot = 0.5; 1.7305 - } 1.7306 - else 1.7307 - { 1.7308 - double envVolume; 1.7309 - if (gba && sound3ForcedOutput != 0) 1.7310 - envVolume = 0.75; 1.7311 - else 1.7312 - { 1.7313 - double volTable[4] = { 0.0, 1.0, 0.5, 0.25 }; 1.7314 - envVolume = volTable[sound3OutputLevel & 3]; 1.7315 - } 1.7316 - 1.7317 - if (soundVINLeft && (soundBalance & 0x40) != 0) 1.7318 - leftvolscale = ((soundLevel2 / 7.0) * envVolume); 1.7319 - else 1.7320 - leftvolscale = 0.0; 1.7321 - if (soundVINRight && (soundBalance & 0x04) != 0) 1.7322 - rightvolscale = ((soundLevel1 / 7.0) * envVolume); 1.7323 - else 1.7324 - rightvolscale = 0.0; 1.7325 - if ((leftvolscale + rightvolscale) != 0) 1.7326 - panpot = rightvolscale / (leftvolscale + rightvolscale); 1.7327 - else 1.7328 - panpot = 0.5; 1.7329 - lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 1.7330 - } 1.7331 - lua_setfield(L, -2, "volume"); 1.7332 - lua_pushnumber(L, panpot); 1.7333 - lua_setfield(L, -2, "panpot"); 1.7334 - int waveMemSamples = 32; 1.7335 - if (gba) 1.7336 - { 1.7337 - lua_pushlstring(L, (const char *) &sound3WaveRam[sound3Bank * 0x10], sound3DataSize ? 0x20 : 0x10); 1.7338 - waveMemSamples = sound3DataSize ? 64 : 32; 1.7339 - } 1.7340 - else 1.7341 - { 1.7342 - lua_pushlstring(L, (const char *) &gbMem[rWAVE_RAM], 0x10); 1.7343 - } 1.7344 - lua_setfield(L, -2, "waveform"); 1.7345 - freqReg = (((int)(gbMem[rNR34] & 7) << 8) | gbMem[rNR33]); 1.7346 - freq = 2097152.0 / (waveMemSamples * (2048 - freqReg)); 1.7347 - lua_pushnumber(L, freq); 1.7348 - lua_setfield(L, -2, "frequency"); 1.7349 - lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 1.7350 - lua_setfield(L, -2, "midikey"); 1.7351 - lua_newtable(L); 1.7352 - lua_pushinteger(L, freqReg); 1.7353 - lua_setfield(L, -2, "frequency"); 1.7354 - lua_setfield(L, -2, "regs"); 1.7355 - lua_setfield(L, -2, "wavememory"); 1.7356 - // noise 1.7357 - lua_newtable(L); 1.7358 - if(sound4On == 0 || soundMasterOn == 0) 1.7359 - { 1.7360 - lua_pushnumber(L, 0.0); 1.7361 - panpot = 0.5; 1.7362 - } 1.7363 - else 1.7364 - { 1.7365 - double envVolume = sound4EnvelopeVolume / 15.0; 1.7366 - if (soundVINLeft && (soundBalance & 0x80) != 0) 1.7367 - leftvolscale = ((soundLevel2 / 7.0) * envVolume); 1.7368 - else 1.7369 - leftvolscale = 0.0; 1.7370 - if (soundVINRight && (soundBalance & 0x08) != 0) 1.7371 - rightvolscale = ((soundLevel1 / 7.0) * envVolume); 1.7372 - else 1.7373 - rightvolscale = 0.0; 1.7374 - if ((leftvolscale + rightvolscale) != 0) 1.7375 - panpot = rightvolscale / (leftvolscale + rightvolscale); 1.7376 - else 1.7377 - panpot = 0.5; 1.7378 - lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 1.7379 - } 1.7380 - lua_setfield(L, -2, "volume"); 1.7381 - lua_pushnumber(L, panpot); 1.7382 - lua_setfield(L, -2, "panpot"); 1.7383 - const int gbNoiseFreqTable[8] = { 1, 2, 4, 6, 8, 10, 12, 14 }; 1.7384 - freqReg = gbNoiseFreqTable[gbMem[rNR43] & 7] << (1 + (gbMem[rNR43] >> 4)); 1.7385 - lua_pushboolean(L, (gbMem[rNR43] & 8) != 0); 1.7386 - lua_setfield(L, -2, "short"); 1.7387 - freq = 1048576.0 / freqReg; 1.7388 - lua_pushnumber(L, freq); 1.7389 - lua_setfield(L, -2, "frequency"); 1.7390 - lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 1.7391 - lua_setfield(L, -2, "midikey"); 1.7392 - lua_newtable(L); 1.7393 - lua_pushinteger(L, freqReg); 1.7394 - lua_setfield(L, -2, "frequency"); 1.7395 - lua_setfield(L, -2, "regs"); 1.7396 - lua_setfield(L, -2, "noise"); 1.7397 - 1.7398 - return 1; 1.7399 - } 1.7400 + return 1; 1.7401 +} 1.7402 + 1.7403 +static int avi_framecount(lua_State *L) 1.7404 +{ 1.7405 +#ifdef WIN32 1.7406 + if (theApp.aviRecorder != NULL) 1.7407 + { 1.7408 + lua_pushinteger(L, theApp.aviRecorder->videoFrames()); 1.7409 + } 1.7410 + else 1.7411 +#endif 1.7412 + { 1.7413 + lua_pushinteger(L, 0); 1.7414 + } 1.7415 + return 1; 1.7416 +} 1.7417 + 1.7418 +static int avi_pause(lua_State *L) 1.7419 +{ 1.7420 +#ifdef WIN32 1.7421 + if (theApp.aviRecorder != NULL) 1.7422 + theApp.aviRecorder->Pause(true); 1.7423 +#endif 1.7424 + return 1; 1.7425 +} 1.7426 + 1.7427 +static int avi_resume(lua_State *L) 1.7428 +{ 1.7429 +#ifdef WIN32 1.7430 + if (theApp.aviRecorder != NULL) 1.7431 + theApp.aviRecorder->Pause(false); 1.7432 +#endif 1.7433 + return 1; 1.7434 +} 1.7435 + 1.7436 +static int sound_get(lua_State *L) 1.7437 +{ 1.7438 + extern int32 soundLevel1; 1.7439 + extern int32 soundLevel2; 1.7440 + extern int32 soundBalance; 1.7441 + extern int32 soundMasterOn; 1.7442 + extern int32 soundVIN; 1.7443 + extern int32 sound1On; 1.7444 + extern int32 sound1EnvelopeVolume; 1.7445 + extern int32 sound2On; 1.7446 + extern int32 sound2EnvelopeVolume; 1.7447 + extern int32 sound3On; 1.7448 + extern int32 sound3OutputLevel; 1.7449 + extern int32 sound3Bank; 1.7450 + extern int32 sound3DataSize; 1.7451 + extern int32 sound3ForcedOutput; 1.7452 + extern int32 sound4On; 1.7453 + extern int32 sound4EnvelopeVolume; 1.7454 + extern u8 sound3WaveRam[0x20]; 1.7455 + 1.7456 + int freqReg; 1.7457 + double freq; 1.7458 + double leftvolscale; 1.7459 + double rightvolscale; 1.7460 + double panpot; 1.7461 + bool gba = systemIsRunningGBA(); 1.7462 + u8* gbMem = gba ? ioMem : gbMemory; 1.7463 + const int rNR10 = gba ? 0x60 : 0xff10; 1.7464 + const int rNR11 = gba ? 0x62 : 0xff11; 1.7465 + const int rNR12 = gba ? 0x63 : 0xff12; 1.7466 + const int rNR13 = gba ? 0x64 : 0xff13; 1.7467 + const int rNR14 = gba ? 0x65 : 0xff14; 1.7468 + const int rNR21 = gba ? 0x68 : 0xff16; 1.7469 + const int rNR22 = gba ? 0x69 : 0xff17; 1.7470 + const int rNR23 = gba ? 0x6c : 0xff18; 1.7471 + const int rNR24 = gba ? 0x6d : 0xff19; 1.7472 + const int rNR30 = gba ? 0x70 : 0xff1a; 1.7473 + const int rNR31 = gba ? 0x72 : 0xff1b; 1.7474 + const int rNR32 = gba ? 0x73 : 0xff1c; 1.7475 + const int rNR33 = gba ? 0x74 : 0xff1d; 1.7476 + const int rNR34 = gba ? 0x75 : 0xff1e; 1.7477 + const int rNR41 = gba ? 0x78 : 0xff20; 1.7478 + const int rNR42 = gba ? 0x79 : 0xff21; 1.7479 + const int rNR43 = gba ? 0x7c : 0xff22; 1.7480 + const int rNR44 = gba ? 0x7d : 0xff23; 1.7481 + const int rNR50 = gba ? 0x80 : 0xff24; 1.7482 + const int rNR51 = gba ? 0x81 : 0xff25; 1.7483 + const int rNR52 = gba ? 0x84 : 0xff26; 1.7484 + const int rWAVE_RAM = gba ? 0x90 : 0xff30; 1.7485 + 1.7486 + const int32 _soundVIN = 0x88; // gba ? 0x88 : soundVIN; 1.7487 + const bool soundVINLeft = ((_soundVIN & 0x80) != 0); 1.7488 + const bool soundVINRight = ((_soundVIN & 0x08) != 0); 1.7489 + 1.7490 + lua_newtable(L); 1.7491 + 1.7492 + // square1 1.7493 + lua_newtable(L); 1.7494 + if(sound1On == 0 || soundMasterOn == 0) 1.7495 + { 1.7496 + lua_pushnumber(L, 0.0); 1.7497 + panpot = 0.5; 1.7498 + } 1.7499 + else 1.7500 + { 1.7501 + double envVolume = sound1EnvelopeVolume / 15.0; 1.7502 + if (soundVINLeft && (soundBalance & 0x10) != 0) 1.7503 + leftvolscale = ((soundLevel2 / 7.0) * envVolume); 1.7504 + else 1.7505 + leftvolscale = 0.0; 1.7506 + if (soundVINRight && (soundBalance & 0x01) != 0) 1.7507 + rightvolscale = ((soundLevel1 / 7.0) * envVolume); 1.7508 + else 1.7509 + rightvolscale = 0.0; 1.7510 + if ((leftvolscale + rightvolscale) != 0) 1.7511 + panpot = rightvolscale / (leftvolscale + rightvolscale); 1.7512 + else 1.7513 + panpot = 0.5; 1.7514 + lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 1.7515 + } 1.7516 + lua_setfield(L, -2, "volume"); 1.7517 + lua_pushnumber(L, panpot); 1.7518 + lua_setfield(L, -2, "panpot"); 1.7519 + freqReg = (((int)(gbMem[rNR14] & 7) << 8) | gbMem[rNR13]); 1.7520 + freq = 131072.0 / (2048 - freqReg); 1.7521 + lua_pushnumber(L, freq); 1.7522 + lua_setfield(L, -2, "frequency"); 1.7523 + lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 1.7524 + lua_setfield(L, -2, "midikey"); 1.7525 + lua_pushinteger(L, (gbMem[rNR11] & 0xC0) >> 6); 1.7526 + lua_setfield(L, -2, "duty"); 1.7527 + lua_newtable(L); 1.7528 + lua_pushinteger(L, freqReg); 1.7529 + lua_setfield(L, -2, "frequency"); 1.7530 + lua_setfield(L, -2, "regs"); 1.7531 + lua_setfield(L, -2, "square1"); 1.7532 + // square2 1.7533 + lua_newtable(L); 1.7534 + if(sound2On == 0 || soundMasterOn == 0) 1.7535 + { 1.7536 + lua_pushnumber(L, 0.0); 1.7537 + panpot = 0.5; 1.7538 + } 1.7539 + else 1.7540 + { 1.7541 + double envVolume = sound2EnvelopeVolume / 15.0; 1.7542 + if (soundVINLeft && (soundBalance & 0x20) != 0) 1.7543 + leftvolscale = ((soundLevel2 / 7.0) * envVolume); 1.7544 + else 1.7545 + leftvolscale = 0.0; 1.7546 + if (soundVINRight && (soundBalance & 0x02) != 0) 1.7547 + rightvolscale = ((soundLevel1 / 7.0) * envVolume); 1.7548 + else 1.7549 + rightvolscale = 0.0; 1.7550 + if ((leftvolscale + rightvolscale) != 0) 1.7551 + panpot = rightvolscale / (leftvolscale + rightvolscale); 1.7552 + else 1.7553 + panpot = 0.5; 1.7554 + lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 1.7555 + } 1.7556 + lua_setfield(L, -2, "volume"); 1.7557 + lua_pushnumber(L, panpot); 1.7558 + lua_setfield(L, -2, "panpot"); 1.7559 + freqReg = (((int)(gbMem[rNR24] & 7) << 8) | gbMem[rNR23]); 1.7560 + freq = 131072.0 / (2048 - freqReg); 1.7561 + lua_pushnumber(L, freq); 1.7562 + lua_setfield(L, -2, "frequency"); 1.7563 + lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 1.7564 + lua_setfield(L, -2, "midikey"); 1.7565 + lua_pushinteger(L, (gbMem[rNR21] & 0xC0) >> 6); 1.7566 + lua_setfield(L, -2, "duty"); 1.7567 + lua_newtable(L); 1.7568 + lua_pushinteger(L, freqReg); 1.7569 + lua_setfield(L, -2, "frequency"); 1.7570 + lua_setfield(L, -2, "regs"); 1.7571 + lua_setfield(L, -2, "square2"); 1.7572 + // wavememory 1.7573 + lua_newtable(L); 1.7574 + if(sound3On == 0 || soundMasterOn == 0) 1.7575 + { 1.7576 + lua_pushnumber(L, 0.0); 1.7577 + panpot = 0.5; 1.7578 + } 1.7579 + else 1.7580 + { 1.7581 + double envVolume; 1.7582 + if (gba && sound3ForcedOutput != 0) 1.7583 + envVolume = 0.75; 1.7584 + else 1.7585 + { 1.7586 + double volTable[4] = { 0.0, 1.0, 0.5, 0.25 }; 1.7587 + envVolume = volTable[sound3OutputLevel & 3]; 1.7588 + } 1.7589 + 1.7590 + if (soundVINLeft && (soundBalance & 0x40) != 0) 1.7591 + leftvolscale = ((soundLevel2 / 7.0) * envVolume); 1.7592 + else 1.7593 + leftvolscale = 0.0; 1.7594 + if (soundVINRight && (soundBalance & 0x04) != 0) 1.7595 + rightvolscale = ((soundLevel1 / 7.0) * envVolume); 1.7596 + else 1.7597 + rightvolscale = 0.0; 1.7598 + if ((leftvolscale + rightvolscale) != 0) 1.7599 + panpot = rightvolscale / (leftvolscale + rightvolscale); 1.7600 + else 1.7601 + panpot = 0.5; 1.7602 + lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 1.7603 + } 1.7604 + lua_setfield(L, -2, "volume"); 1.7605 + lua_pushnumber(L, panpot); 1.7606 + lua_setfield(L, -2, "panpot"); 1.7607 + int waveMemSamples = 32; 1.7608 + if (gba) 1.7609 + { 1.7610 + lua_pushlstring(L, (const char *) &sound3WaveRam[sound3Bank * 0x10], sound3DataSize ? 0x20 : 0x10); 1.7611 + waveMemSamples = sound3DataSize ? 64 : 32; 1.7612 + } 1.7613 + else 1.7614 + { 1.7615 + lua_pushlstring(L, (const char *) &gbMem[rWAVE_RAM], 0x10); 1.7616 + } 1.7617 + lua_setfield(L, -2, "waveform"); 1.7618 + freqReg = (((int)(gbMem[rNR34] & 7) << 8) | gbMem[rNR33]); 1.7619 + freq = 2097152.0 / (waveMemSamples * (2048 - freqReg)); 1.7620 + lua_pushnumber(L, freq); 1.7621 + lua_setfield(L, -2, "frequency"); 1.7622 + lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 1.7623 + lua_setfield(L, -2, "midikey"); 1.7624 + lua_newtable(L); 1.7625 + lua_pushinteger(L, freqReg); 1.7626 + lua_setfield(L, -2, "frequency"); 1.7627 + lua_setfield(L, -2, "regs"); 1.7628 + lua_setfield(L, -2, "wavememory"); 1.7629 + // noise 1.7630 + lua_newtable(L); 1.7631 + if(sound4On == 0 || soundMasterOn == 0) 1.7632 + { 1.7633 + lua_pushnumber(L, 0.0); 1.7634 + panpot = 0.5; 1.7635 + } 1.7636 + else 1.7637 + { 1.7638 + double envVolume = sound4EnvelopeVolume / 15.0; 1.7639 + if (soundVINLeft && (soundBalance & 0x80) != 0) 1.7640 + leftvolscale = ((soundLevel2 / 7.0) * envVolume); 1.7641 + else 1.7642 + leftvolscale = 0.0; 1.7643 + if (soundVINRight && (soundBalance & 0x08) != 0) 1.7644 + rightvolscale = ((soundLevel1 / 7.0) * envVolume); 1.7645 + else 1.7646 + rightvolscale = 0.0; 1.7647 + if ((leftvolscale + rightvolscale) != 0) 1.7648 + panpot = rightvolscale / (leftvolscale + rightvolscale); 1.7649 + else 1.7650 + panpot = 0.5; 1.7651 + lua_pushnumber(L, (leftvolscale + rightvolscale) / 2.0); 1.7652 + } 1.7653 + lua_setfield(L, -2, "volume"); 1.7654 + lua_pushnumber(L, panpot); 1.7655 + lua_setfield(L, -2, "panpot"); 1.7656 + const int gbNoiseFreqTable[8] = { 1, 2, 4, 6, 8, 10, 12, 14 }; 1.7657 + freqReg = gbNoiseFreqTable[gbMem[rNR43] & 7] << (1 + (gbMem[rNR43] >> 4)); 1.7658 + lua_pushboolean(L, (gbMem[rNR43] & 8) != 0); 1.7659 + lua_setfield(L, -2, "short"); 1.7660 + freq = 1048576.0 / freqReg; 1.7661 + lua_pushnumber(L, freq); 1.7662 + lua_setfield(L, -2, "frequency"); 1.7663 + lua_pushnumber(L, (log(freq / 440.0) * 12 / log(2.0)) + 69); 1.7664 + lua_setfield(L, -2, "midikey"); 1.7665 + lua_newtable(L); 1.7666 + lua_pushinteger(L, freqReg); 1.7667 + lua_setfield(L, -2, "frequency"); 1.7668 + lua_setfield(L, -2, "regs"); 1.7669 + lua_setfield(L, -2, "noise"); 1.7670 + 1.7671 + return 1; 1.7672 +} 1.7673 1.7674 // same as math.random, but uses SFMT instead of C rand() 1.7675 // FIXME: this function doesn't care multi-instance, 1.7676 1.7677 // original math.random either though (Lua 5.1) 1.7678 - static int sfmt_random(lua_State *L) 1.7679 - { 1.7680 - lua_Number r = (lua_Number) genrand_real2(); 1.7681 - switch (lua_gettop(L)) 1.7682 - { // check number of arguments 1.7683 - case 0: 1.7684 - { // no arguments 1.7685 - lua_pushnumber(L, r); // Number between 0 and 1 1.7686 - break; 1.7687 - } 1.7688 - 1.7689 - case 1: 1.7690 - { // only upper limit 1.7691 - int u = luaL_checkint(L, 1); 1.7692 - luaL_argcheck(L, 1 <= u, 1, "interval is empty"); 1.7693 - lua_pushnumber(L, floor(r * u) + 1); // int between 1 and `u' 1.7694 - break; 1.7695 - } 1.7696 - 1.7697 - case 2: 1.7698 - { // lower and upper limits 1.7699 - int l = luaL_checkint(L, 1); 1.7700 - int u = luaL_checkint(L, 2); 1.7701 - luaL_argcheck(L, l <= u, 2, "interval is empty"); 1.7702 - lua_pushnumber(L, floor(r * (u - l + 1)) + l); // int between `l' and `u' 1.7703 - break; 1.7704 - } 1.7705 - 1.7706 - default: 1.7707 - return luaL_error(L, "wrong number of arguments"); 1.7708 - } 1.7709 - 1.7710 - return 1; 1.7711 - } 1.7712 +static int sfmt_random(lua_State *L) 1.7713 +{ 1.7714 + lua_Number r = (lua_Number) genrand_real2(); 1.7715 + switch (lua_gettop(L)) 1.7716 + { // check number of arguments 1.7717 + case 0: 1.7718 + { // no arguments 1.7719 + lua_pushnumber(L, r); // Number between 0 and 1 1.7720 + break; 1.7721 + } 1.7722 + 1.7723 + case 1: 1.7724 + { // only upper limit 1.7725 + int u = luaL_checkint(L, 1); 1.7726 + luaL_argcheck(L, 1 <= u, 1, "interval is empty"); 1.7727 + lua_pushnumber(L, floor(r * u) + 1); // int between 1 and `u' 1.7728 + break; 1.7729 + } 1.7730 + 1.7731 + case 2: 1.7732 + { // lower and upper limits 1.7733 + int l = luaL_checkint(L, 1); 1.7734 + int u = luaL_checkint(L, 2); 1.7735 + luaL_argcheck(L, l <= u, 2, "interval is empty"); 1.7736 + lua_pushnumber(L, floor(r * (u - l + 1)) + l); // int between `l' and `u' 1.7737 + break; 1.7738 + } 1.7739 + 1.7740 + default: 1.7741 + return luaL_error(L, "wrong number of arguments"); 1.7742 + } 1.7743 + 1.7744 + return 1; 1.7745 +} 1.7746 1.7747 // same as math.randomseed, but uses SFMT instead of C srand() 1.7748 // FIXME: this function doesn't care multi-instance, 1.7749 1.7750 // original math.randomseed either though (Lua 5.1) 1.7751 - static int sfmt_randomseed(lua_State *L) 1.7752 - { 1.7753 - init_gen_rand(luaL_checkint(L, 1)); 1.7754 - return 0; 1.7755 - } 1.7756 +static int sfmt_randomseed(lua_State *L) 1.7757 +{ 1.7758 + init_gen_rand(luaL_checkint(L, 1)); 1.7759 + return 0; 1.7760 +} 1.7761 1.7762 // the following bit operations are ported from LuaBitOp 1.0.1, 1.7763 // because it can handle the sign bit (bit 31) correctly. 1.7764 @@ -4250,123 +4250,123 @@ 1.7765 1.7766 #ifdef _MSC_VER 1.7767 /* MSVC is stuck in the last century and doesn't have C99's stdint.h. */ 1.7768 - typedef __int32 int32_t; 1.7769 - typedef unsigned __int32 uint32_t; 1.7770 - typedef unsigned __int64 uint64_t; 1.7771 +typedef __int32 int32_t; 1.7772 +typedef unsigned __int32 uint32_t; 1.7773 +typedef unsigned __int64 uint64_t; 1.7774 #else 1.7775 #include <stdint.h> 1.7776 #endif 1.7777 1.7778 - typedef int32_t SBits; 1.7779 - typedef uint32_t UBits; 1.7780 - 1.7781 - typedef union 1.7782 - { 1.7783 - lua_Number n; 1.7784 +typedef int32_t SBits; 1.7785 +typedef uint32_t UBits; 1.7786 + 1.7787 +typedef union 1.7788 +{ 1.7789 + lua_Number n; 1.7790 #ifdef LUA_NUMBER_DOUBLE 1.7791 - uint64_t b; 1.7792 + uint64_t b; 1.7793 #else 1.7794 - UBits b; 1.7795 + UBits b; 1.7796 #endif 1.7797 - } BitNum; 1.7798 +} BitNum; 1.7799 1.7800 /* Convert argument to bit type. */ 1.7801 - static UBits barg(lua_State *L, int idx) 1.7802 - { 1.7803 - BitNum bn; 1.7804 - UBits b; 1.7805 - bn.n = lua_tonumber(L, idx); 1.7806 +static UBits barg(lua_State *L, int idx) 1.7807 +{ 1.7808 + BitNum bn; 1.7809 + UBits b; 1.7810 + bn.n = lua_tonumber(L, idx); 1.7811 #if defined(LUA_NUMBER_DOUBLE) 1.7812 - bn.n += 6755399441055744.0; /* 2^52+2^51 */ 1.7813 + bn.n += 6755399441055744.0; /* 2^52+2^51 */ 1.7814 #ifdef SWAPPED_DOUBLE 1.7815 - b = (UBits)(bn.b >> 32); 1.7816 + b = (UBits)(bn.b >> 32); 1.7817 #else 1.7818 - b = (UBits)(bn.b & 0xffffffff); 1.7819 + b = (UBits)(bn.b & 0xffffffff); 1.7820 #endif 1.7821 -#elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \ 1.7822 - defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \ 1.7823 - defined(LUA_NUMBER_LLONG) 1.7824 - if (sizeof(UBits) == sizeof(lua_Number)) 1.7825 - b = bn.b; 1.7826 - else 1.7827 - b = (UBits)(SBits)bn.n; 1.7828 +#elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \ 1.7829 + defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \ 1.7830 + defined(LUA_NUMBER_LLONG) 1.7831 + if (sizeof(UBits) == sizeof(lua_Number)) 1.7832 + b = bn.b; 1.7833 + else 1.7834 + b = (UBits)(SBits)bn.n; 1.7835 #elif defined(LUA_NUMBER_FLOAT) 1.7836 #error "A 'float' lua_Number type is incompatible with this library" 1.7837 #else 1.7838 #error "Unknown number type, check LUA_NUMBER_* in luaconf.h" 1.7839 #endif 1.7840 - if (b == 0 && !lua_isnumber(L, idx)) 1.7841 - luaL_typerror(L, idx, "number"); 1.7842 - return b; 1.7843 - } 1.7844 + if (b == 0 && !lua_isnumber(L, idx)) 1.7845 + luaL_typerror(L, idx, "number"); 1.7846 + return b; 1.7847 +} 1.7848 1.7849 /* Return bit type. */ 1.7850 #define BRET(b) lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1; 1.7851 1.7852 - static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) } 1.7853 - static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) } 1.7854 - 1.7855 -#define BIT_OP(func, opr) \ 1.7856 - static int func(lua_State * L) { int i; UBits b = barg(L, 1); \ 1.7857 - for (i = lua_gettop(L); i > 1; i--) \ 1.7858 - b opr barg(L, i); BRET(b) } 1.7859 - BIT_OP(bit_band, &= ) 1.7860 - BIT_OP(bit_bor, |= ) 1.7861 - BIT_OP(bit_bxor, ^= ) 1.7862 +static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) } 1.7863 +static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) } 1.7864 + 1.7865 +#define BIT_OP(func, opr) \ 1.7866 + static int func(lua_State * L) { int i; UBits b = barg(L, 1); \ 1.7867 + for (i = lua_gettop(L); i > 1; i--) \ 1.7868 + b opr barg(L, i); BRET(b) } 1.7869 +BIT_OP(bit_band, &= ) 1.7870 +BIT_OP(bit_bor, |= ) 1.7871 +BIT_OP(bit_bxor, ^= ) 1.7872 1.7873 #define bshl(b, n) (b << n) 1.7874 #define bshr(b, n) (b >> n) 1.7875 #define bsar(b, n) ((SBits)b >> n) 1.7876 #define brol(b, n) ((b << n) | (b >> (32 - n))) 1.7877 #define bror(b, n) ((b << (32 - n)) | (b >> n)) 1.7878 -#define BIT_SH(func, fn) \ 1.7879 - static int func(lua_State * L) { \ 1.7880 - UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) } 1.7881 - BIT_SH(bit_lshift, bshl) 1.7882 - BIT_SH(bit_rshift, bshr) 1.7883 - BIT_SH(bit_arshift, bsar) 1.7884 - BIT_SH(bit_rol, brol) 1.7885 - BIT_SH(bit_ror, bror) 1.7886 - 1.7887 - static int bit_bswap(lua_State *L) 1.7888 - { 1.7889 - UBits b = barg(L, 1); 1.7890 - b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24); 1.7891 - BRET(b) 1.7892 - } 1.7893 - 1.7894 - static int bit_tohex(lua_State *L) 1.7895 - { 1.7896 - UBits b = barg(L, 1); 1.7897 - SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2); 1.7898 - const char *hexdigits = "0123456789abcdef"; 1.7899 - char buf[8]; 1.7900 - int i; 1.7901 - if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } 1.7902 - if (n > 8) n = 8; 1.7903 - for (i = (int)n; --i >= 0; ) 1.7904 - { 1.7905 - buf[i] = hexdigits[b & 15]; b >>= 4; 1.7906 - } 1.7907 - lua_pushlstring(L, buf, (size_t)n); 1.7908 - return 1; 1.7909 - } 1.7910 - 1.7911 - static const struct luaL_Reg bit_funcs[] = { 1.7912 - { "tobit", bit_tobit }, 1.7913 - { "bnot", bit_bnot }, 1.7914 - { "band", bit_band }, 1.7915 - { "bor", bit_bor }, 1.7916 - { "bxor", bit_bxor }, 1.7917 - { "lshift", bit_lshift }, 1.7918 - { "rshift", bit_rshift }, 1.7919 - { "arshift", bit_arshift }, 1.7920 - { "rol", bit_rol }, 1.7921 - { "ror", bit_ror }, 1.7922 - { "bswap", bit_bswap }, 1.7923 - { "tohex", bit_tohex }, 1.7924 - { NULL, NULL } 1.7925 - }; 1.7926 +#define BIT_SH(func, fn) \ 1.7927 + static int func(lua_State * L) { \ 1.7928 + UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) } 1.7929 +BIT_SH(bit_lshift, bshl) 1.7930 +BIT_SH(bit_rshift, bshr) 1.7931 +BIT_SH(bit_arshift, bsar) 1.7932 +BIT_SH(bit_rol, brol) 1.7933 +BIT_SH(bit_ror, bror) 1.7934 + 1.7935 +static int bit_bswap(lua_State *L) 1.7936 +{ 1.7937 + UBits b = barg(L, 1); 1.7938 + b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24); 1.7939 + BRET(b) 1.7940 + } 1.7941 + 1.7942 +static int bit_tohex(lua_State *L) 1.7943 +{ 1.7944 + UBits b = barg(L, 1); 1.7945 + SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2); 1.7946 + const char *hexdigits = "0123456789abcdef"; 1.7947 + char buf[8]; 1.7948 + int i; 1.7949 + if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } 1.7950 + if (n > 8) n = 8; 1.7951 + for (i = (int)n; --i >= 0; ) 1.7952 + { 1.7953 + buf[i] = hexdigits[b & 15]; b >>= 4; 1.7954 + } 1.7955 + lua_pushlstring(L, buf, (size_t)n); 1.7956 + return 1; 1.7957 +} 1.7958 + 1.7959 +static const struct luaL_Reg bit_funcs[] = { 1.7960 + { "tobit", bit_tobit }, 1.7961 + { "bnot", bit_bnot }, 1.7962 + { "band", bit_band }, 1.7963 + { "bor", bit_bor }, 1.7964 + { "bxor", bit_bxor }, 1.7965 + { "lshift", bit_lshift }, 1.7966 + { "rshift", bit_rshift }, 1.7967 + { "arshift", bit_arshift }, 1.7968 + { "rol", bit_rol }, 1.7969 + { "ror", bit_ror }, 1.7970 + { "bswap", bit_bswap }, 1.7971 + { "tohex", bit_tohex }, 1.7972 + { NULL, NULL } 1.7973 +}; 1.7974 1.7975 /* Signed right-shifts are implementation-defined per C89/C99. 1.7976 ** But the de facto standard are arithmetic right-shifts on two's 1.7977 @@ -4374,364 +4374,364 @@ 1.7978 */ 1.7979 #define BAD_SAR (bsar(-8, 2) != (SBits) - 2) 1.7980 1.7981 - bool luabitop_validate(lua_State *L) // originally named as luaopen_bit 1.7982 - { 1.7983 - UBits b; 1.7984 - lua_pushnumber(L, (lua_Number)1437217655L); 1.7985 - b = barg(L, -1); 1.7986 - if (b != (UBits)1437217655L || BAD_SAR) /* Perform a simple self-test. */ 1.7987 - { 1.7988 - const char *msg = "compiled with incompatible luaconf.h"; 1.7989 +bool luabitop_validate(lua_State *L) // originally named as luaopen_bit 1.7990 +{ 1.7991 + UBits b; 1.7992 + lua_pushnumber(L, (lua_Number)1437217655L); 1.7993 + b = barg(L, -1); 1.7994 + if (b != (UBits)1437217655L || BAD_SAR) /* Perform a simple self-test. */ 1.7995 + { 1.7996 + const char *msg = "compiled with incompatible luaconf.h"; 1.7997 #ifdef LUA_NUMBER_DOUBLE 1.7998 #ifdef WIN32 1.7999 - if (b == (UBits)1610612736L) 1.8000 - msg = "use D3DCREATE_FPU_PRESERVE with DirectX"; 1.8001 + if (b == (UBits)1610612736L) 1.8002 + msg = "use D3DCREATE_FPU_PRESERVE with DirectX"; 1.8003 #endif 1.8004 - if (b == (UBits)1127743488L) 1.8005 - msg = "not compiled with SWAPPED_DOUBLE"; 1.8006 + if (b == (UBits)1127743488L) 1.8007 + msg = "not compiled with SWAPPED_DOUBLE"; 1.8008 #endif 1.8009 - if (BAD_SAR) 1.8010 - msg = "arithmetic right-shift broken"; 1.8011 - luaL_error(L, "bit library self-test failed (%s)", msg); 1.8012 - return false; 1.8013 - } 1.8014 - return true; 1.8015 - } 1.8016 + if (BAD_SAR) 1.8017 + msg = "arithmetic right-shift broken"; 1.8018 + luaL_error(L, "bit library self-test failed (%s)", msg); 1.8019 + return false; 1.8020 + } 1.8021 + return true; 1.8022 +} 1.8023 1.8024 // LuaBitOp ends here 1.8025 1.8026 - static int bit_bshift_emulua(lua_State *L) 1.8027 - { 1.8028 - int shift = luaL_checkinteger(L, 2); 1.8029 - if (shift < 0) 1.8030 - { 1.8031 - lua_pushinteger(L, -shift); 1.8032 - lua_replace(L, 2); 1.8033 - return bit_lshift(L); 1.8034 - } 1.8035 - else 1.8036 - return bit_rshift(L); 1.8037 - } 1.8038 - 1.8039 - static int bitbit(lua_State *L) 1.8040 - { 1.8041 - int rv = 0; 1.8042 - int numArgs = lua_gettop(L); 1.8043 - for (int i = 1; i <= numArgs; i++) 1.8044 - { 1.8045 - int where = luaL_checkinteger(L, i); 1.8046 - if (where >= 0 && where < 32) 1.8047 - rv |= (1 << where); 1.8048 - } 1.8049 - lua_settop(L, 0); 1.8050 - BRET(rv); 1.8051 - } 1.8052 +static int bit_bshift_emulua(lua_State *L) 1.8053 +{ 1.8054 + int shift = luaL_checkinteger(L, 2); 1.8055 + if (shift < 0) 1.8056 + { 1.8057 + lua_pushinteger(L, -shift); 1.8058 + lua_replace(L, 2); 1.8059 + return bit_lshift(L); 1.8060 + } 1.8061 + else 1.8062 + return bit_rshift(L); 1.8063 +} 1.8064 + 1.8065 +static int bitbit(lua_State *L) 1.8066 +{ 1.8067 + int rv = 0; 1.8068 + int numArgs = lua_gettop(L); 1.8069 + for (int i = 1; i <= numArgs; i++) 1.8070 + { 1.8071 + int where = luaL_checkinteger(L, i); 1.8072 + if (where >= 0 && where < 32) 1.8073 + rv |= (1 << where); 1.8074 + } 1.8075 + lua_settop(L, 0); 1.8076 + BRET(rv); 1.8077 +} 1.8078 1.8079 // The function called periodically to ensure Lua doesn't run amok. 1.8080 - static void VBALuaHookFunction(lua_State *L, lua_Debug *dbg) 1.8081 - { 1.8082 - if (numTries-- == 0) 1.8083 - { 1.8084 - int kill = 0; 1.8085 +static void VBALuaHookFunction(lua_State *L, lua_Debug *dbg) 1.8086 +{ 1.8087 + if (numTries-- == 0) 1.8088 + { 1.8089 + int kill = 0; 1.8090 1.8091 #if (defined(WIN32) && !defined(SDL)) 1.8092 - // Uh oh 1.8093 - theApp.winCheckFullscreen(); 1.8094 - systemSoundClearBuffer(); 1.8095 - int ret = AfxGetApp()->m_pMainWnd->MessageBox( 1.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)", 1.8097 - "Lua Script Gone Nuts?", 1.8098 - MB_YESNO); 1.8099 - 1.8100 - if (ret == IDYES) 1.8101 - { 1.8102 - kill = 1; 1.8103 - } 1.8104 + // Uh oh 1.8105 + theApp.winCheckFullscreen(); 1.8106 + systemSoundClearBuffer(); 1.8107 + int ret = AfxGetApp()->m_pMainWnd->MessageBox( 1.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)", 1.8109 + "Lua Script Gone Nuts?", 1.8110 + MB_YESNO); 1.8111 + 1.8112 + if (ret == IDYES) 1.8113 + { 1.8114 + kill = 1; 1.8115 + } 1.8116 1.8117 #else 1.8118 - fprintf( 1.8119 - stderr, 1.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"); 1.8121 - 1.8122 - char buffer[64]; 1.8123 - while (true) 1.8124 - { 1.8125 - fprintf(stderr, "(y/n): "); 1.8126 - fgets(buffer, sizeof(buffer), stdin); 1.8127 - if (buffer[0] == 'y' || buffer[0] == 'Y') 1.8128 - { 1.8129 - kill = 1; 1.8130 - break; 1.8131 - } 1.8132 - 1.8133 - if (buffer[0] == 'n' || buffer[0] == 'N') 1.8134 - break; 1.8135 - } 1.8136 + fprintf( 1.8137 + stderr, 1.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"); 1.8139 + 1.8140 + char buffer[64]; 1.8141 + while (true) 1.8142 + { 1.8143 + fprintf(stderr, "(y/n): "); 1.8144 + fgets(buffer, sizeof(buffer), stdin); 1.8145 + if (buffer[0] == 'y' || buffer[0] == 'Y') 1.8146 + { 1.8147 + kill = 1; 1.8148 + break; 1.8149 + } 1.8150 + 1.8151 + if (buffer[0] == 'n' || buffer[0] == 'N') 1.8152 + break; 1.8153 + } 1.8154 #endif 1.8155 - if (kill) 1.8156 - { 1.8157 - luaL_error(L, "Killed by user request."); 1.8158 - VBALuaOnStop(); 1.8159 - } 1.8160 - 1.8161 - // else, kill the debug hook. 1.8162 - lua_sethook(L, NULL, 0, 0); 1.8163 - } 1.8164 - } 1.8165 - 1.8166 - static const struct luaL_reg vbalib[] = { 1.8167 - // {"speedmode", vba_speedmode}, // TODO: NYI 1.8168 - { "frameadvance", vba_frameadvance }, 1.8169 - { "pause", vba_pause }, 1.8170 - { "framecount", vba_framecount }, 1.8171 - { "lagcount", vba_getlagcount }, 1.8172 - { "lagged", vba_lagged }, 1.8173 - { "emulating", vba_emulating }, 1.8174 - { "registerbefore", vba_registerbefore }, 1.8175 - { "registerafter", vba_registerafter }, 1.8176 - { "registerexit", vba_registerexit }, 1.8177 - { "message", vba_message }, 1.8178 - { "print", print }, // sure, why not 1.8179 - { NULL, NULL } 1.8180 - }; 1.8181 - 1.8182 - static const struct luaL_reg memorylib[] = { 1.8183 - { "readbyte", memory_readbyte }, 1.8184 - { "readbytesigned", memory_readbytesigned }, 1.8185 - { "readword", memory_readword }, 1.8186 - { "readwordsigned", memory_readwordsigned }, 1.8187 - { "readdword", memory_readdword }, 1.8188 - { "readdwordsigned", memory_readdwordsigned }, 1.8189 - { "readbyterange", memory_readbyterange }, 1.8190 - { "writebyte", memory_writebyte }, 1.8191 - { "writeword", memory_writeword }, 1.8192 - { "writedword", memory_writedword }, 1.8193 - { "getregister", memory_getregister }, 1.8194 - { "setregister", memory_setregister }, 1.8195 - { "gbromreadbyte", memory_gbromreadbyte }, 1.8196 - { "gbromreadbytesigned", memory_gbromreadbytesigned }, 1.8197 - { "gbromreadword", memory_gbromreadword }, 1.8198 - { "gbromreadwordsigned", memory_gbromreadwordsigned }, 1.8199 - { "gbromreaddword", memory_gbromreaddword }, 1.8200 - { "gbromreaddwordsigned", memory_gbromreaddwordsigned }, 1.8201 - { "gbromreadbyterange", memory_gbromreadbyterange }, 1.8202 - 1.8203 - // alternate naming scheme for word and double-word and unsigned 1.8204 - { "readbyteunsigned", memory_readbyte }, 1.8205 - { "readwordunsigned", memory_readword }, 1.8206 - { "readdwordunsigned", memory_readdword }, 1.8207 - { "readshort", memory_readword }, 1.8208 - { "readshortunsigned", memory_readword }, 1.8209 - { "readshortsigned", memory_readwordsigned }, 1.8210 - { "readlong", memory_readdword }, 1.8211 - { "readlongunsigned", memory_readdword }, 1.8212 - { "readlongsigned", memory_readdwordsigned }, 1.8213 - { "writeshort", memory_writeword }, 1.8214 - { "writelong", memory_writedword }, 1.8215 - { "gbromreadbyteunsigned", memory_gbromreadbyte }, 1.8216 - { "gbromreadwordunsigned", memory_gbromreadword }, 1.8217 - { "gbromreaddwordunsigned", memory_gbromreaddword }, 1.8218 - { "gbromreadshort", memory_gbromreadword }, 1.8219 - { "gbromreadshortunsigned", memory_gbromreadword }, 1.8220 - { "gbromreadshortsigned", memory_gbromreadwordsigned }, 1.8221 - { "gbromreadlong", memory_gbromreaddword }, 1.8222 - { "gbromreadlongunsigned", memory_gbromreaddword }, 1.8223 - { "gbromreadlongsigned", memory_gbromreaddwordsigned }, 1.8224 - 1.8225 - // memory hooks 1.8226 - { "registerwrite", memory_registerwrite }, 1.8227 - //{"registerread", memory_registerread}, 1.8228 - { "registerexec", memory_registerexec }, 1.8229 - // alternate names 1.8230 - { "register", memory_registerwrite }, 1.8231 - { "registerrun", memory_registerexec }, 1.8232 - { "registerexecute", memory_registerexec }, 1.8233 - 1.8234 - { NULL, NULL } 1.8235 - }; 1.8236 - 1.8237 - static const struct luaL_reg joypadlib[] = { 1.8238 - { "get", joypad_get }, 1.8239 - { "getdown", joypad_getdown }, 1.8240 - { "getup", joypad_getup }, 1.8241 - { "set", joypad_set }, 1.8242 - 1.8243 - // alternative names 1.8244 - { "read", joypad_get }, 1.8245 - { "write", joypad_set }, 1.8246 - { "readdown", joypad_getdown }, 1.8247 - { "readup", joypad_getup }, 1.8248 - { NULL, NULL } 1.8249 - }; 1.8250 - 1.8251 - static const struct luaL_reg savestatelib[] = { 1.8252 - { "create", savestate_create }, 1.8253 - { "save", savestate_save }, 1.8254 - { "load", savestate_load }, 1.8255 - 1.8256 - { NULL, NULL } 1.8257 - }; 1.8258 - 1.8259 - static const struct luaL_reg movielib[] = { 1.8260 - { "active", movie_isactive }, 1.8261 - { "recording", movie_isrecording }, 1.8262 - { "playing", movie_isplaying }, 1.8263 - { "mode", movie_getmode }, 1.8264 - 1.8265 - { "length", movie_getlength }, 1.8266 - { "author", movie_getauthor }, 1.8267 - { "name", movie_getfilename }, 1.8268 - { "rerecordcount", movie_rerecordcount }, 1.8269 - { "setrerecordcount", movie_setrerecordcount }, 1.8270 - 1.8271 - { "rerecordcounting", movie_rerecordcounting }, 1.8272 - { "framecount", vba_framecount }, // for those familiar with 1.8273 - // other emulators that have 1.8274 - // movie.framecount() 1.8275 - // instead of 1.8276 - // emulatorname.framecount() 1.8277 - 1.8278 - { "stop", movie_stop }, 1.8279 - 1.8280 - // alternative names 1.8281 - { "close", movie_stop }, 1.8282 - { "getauthor", movie_getauthor }, 1.8283 - { "getname", movie_getfilename }, 1.8284 - { NULL, NULL } 1.8285 - }; 1.8286 - 1.8287 - static const struct luaL_reg guilib[] = { 1.8288 - { "register", gui_register }, 1.8289 - { "text", gui_text }, 1.8290 - { "box", gui_drawbox }, 1.8291 - { "line", gui_drawline }, 1.8292 - { "pixel", gui_drawpixel }, 1.8293 - { "opacity", gui_setopacity }, 1.8294 - { "transparency", gui_transparency }, 1.8295 - { "popup", gui_popup }, 1.8296 - { "parsecolor", gui_parsecolor }, 1.8297 - { "gdscreenshot", gui_gdscreenshot }, 1.8298 - { "gdoverlay", gui_gdoverlay }, 1.8299 - { "getpixel", gui_getpixel }, 1.8300 - 1.8301 - // alternative names 1.8302 - { "drawtext", gui_text }, 1.8303 - { "drawbox", gui_drawbox }, 1.8304 - { "drawline", gui_drawline }, 1.8305 - { "drawpixel", gui_drawpixel }, 1.8306 - { "setpixel", gui_drawpixel }, 1.8307 - { "writepixel", gui_drawpixel }, 1.8308 - { "rect", gui_drawbox }, 1.8309 - { "drawrect", gui_drawbox }, 1.8310 - { "drawimage", gui_gdoverlay }, 1.8311 - { "image", gui_gdoverlay }, 1.8312 - { "readpixel", gui_getpixel }, 1.8313 - { NULL, NULL } 1.8314 - }; 1.8315 - 1.8316 - static const struct luaL_reg inputlib[] = { 1.8317 - { "get", input_getcurrentinputstatus }, 1.8318 - 1.8319 - // alternative names 1.8320 - { "read", input_getcurrentinputstatus }, 1.8321 - { NULL, NULL } 1.8322 - }; 1.8323 - 1.8324 - static const struct luaL_reg soundlib[] = { 1.8325 - { "get", sound_get }, 1.8326 - 1.8327 - // alternative names 1.8328 - { NULL, NULL } 1.8329 - }; 1.8330 + if (kill) 1.8331 + { 1.8332 + luaL_error(L, "Killed by user request."); 1.8333 + VBALuaOnStop(); 1.8334 + } 1.8335 + 1.8336 + // else, kill the debug hook. 1.8337 + lua_sethook(L, NULL, 0, 0); 1.8338 + } 1.8339 +} 1.8340 + 1.8341 +static const struct luaL_reg vbalib[] = { 1.8342 + // {"speedmode", vba_speedmode}, // TODO: NYI 1.8343 + { "frameadvance", vba_frameadvance }, 1.8344 + { "pause", vba_pause }, 1.8345 + { "framecount", vba_framecount }, 1.8346 + { "lagcount", vba_getlagcount }, 1.8347 + { "lagged", vba_lagged }, 1.8348 + { "emulating", vba_emulating }, 1.8349 + { "registerbefore", vba_registerbefore }, 1.8350 + { "registerafter", vba_registerafter }, 1.8351 + { "registerexit", vba_registerexit }, 1.8352 + { "message", vba_message }, 1.8353 + { "print", print }, // sure, why not 1.8354 + { NULL, NULL } 1.8355 +}; 1.8356 + 1.8357 +static const struct luaL_reg memorylib[] = { 1.8358 + { "readbyte", memory_readbyte }, 1.8359 + { "readbytesigned", memory_readbytesigned }, 1.8360 + { "readword", memory_readword }, 1.8361 + { "readwordsigned", memory_readwordsigned }, 1.8362 + { "readdword", memory_readdword }, 1.8363 + { "readdwordsigned", memory_readdwordsigned }, 1.8364 + { "readbyterange", memory_readbyterange }, 1.8365 + { "writebyte", memory_writebyte }, 1.8366 + { "writeword", memory_writeword }, 1.8367 + { "writedword", memory_writedword }, 1.8368 + { "getregister", memory_getregister }, 1.8369 + { "setregister", memory_setregister }, 1.8370 + { "gbromreadbyte", memory_gbromreadbyte }, 1.8371 + { "gbromreadbytesigned", memory_gbromreadbytesigned }, 1.8372 + { "gbromreadword", memory_gbromreadword }, 1.8373 + { "gbromreadwordsigned", memory_gbromreadwordsigned }, 1.8374 + { "gbromreaddword", memory_gbromreaddword }, 1.8375 + { "gbromreaddwordsigned", memory_gbromreaddwordsigned }, 1.8376 + { "gbromreadbyterange", memory_gbromreadbyterange }, 1.8377 + 1.8378 + // alternate naming scheme for word and double-word and unsigned 1.8379 + { "readbyteunsigned", memory_readbyte }, 1.8380 + { "readwordunsigned", memory_readword }, 1.8381 + { "readdwordunsigned", memory_readdword }, 1.8382 + { "readshort", memory_readword }, 1.8383 + { "readshortunsigned", memory_readword }, 1.8384 + { "readshortsigned", memory_readwordsigned }, 1.8385 + { "readlong", memory_readdword }, 1.8386 + { "readlongunsigned", memory_readdword }, 1.8387 + { "readlongsigned", memory_readdwordsigned }, 1.8388 + { "writeshort", memory_writeword }, 1.8389 + { "writelong", memory_writedword }, 1.8390 + { "gbromreadbyteunsigned", memory_gbromreadbyte }, 1.8391 + { "gbromreadwordunsigned", memory_gbromreadword }, 1.8392 + { "gbromreaddwordunsigned", memory_gbromreaddword }, 1.8393 + { "gbromreadshort", memory_gbromreadword }, 1.8394 + { "gbromreadshortunsigned", memory_gbromreadword }, 1.8395 + { "gbromreadshortsigned", memory_gbromreadwordsigned }, 1.8396 + { "gbromreadlong", memory_gbromreaddword }, 1.8397 + { "gbromreadlongunsigned", memory_gbromreaddword }, 1.8398 + { "gbromreadlongsigned", memory_gbromreaddwordsigned }, 1.8399 + 1.8400 + // memory hooks 1.8401 + { "registerwrite", memory_registerwrite }, 1.8402 + //{"registerread", memory_registerread}, 1.8403 + { "registerexec", memory_registerexec }, 1.8404 + // alternate names 1.8405 + { "register", memory_registerwrite }, 1.8406 + { "registerrun", memory_registerexec }, 1.8407 + { "registerexecute", memory_registerexec }, 1.8408 + 1.8409 + { NULL, NULL } 1.8410 +}; 1.8411 + 1.8412 +static const struct luaL_reg joypadlib[] = { 1.8413 + { "get", joypad_get }, 1.8414 + { "getdown", joypad_getdown }, 1.8415 + { "getup", joypad_getup }, 1.8416 + { "set", joypad_set }, 1.8417 + 1.8418 + // alternative names 1.8419 + { "read", joypad_get }, 1.8420 + { "write", joypad_set }, 1.8421 + { "readdown", joypad_getdown }, 1.8422 + { "readup", joypad_getup }, 1.8423 + { NULL, NULL } 1.8424 +}; 1.8425 + 1.8426 +static const struct luaL_reg savestatelib[] = { 1.8427 + { "create", savestate_create }, 1.8428 + { "save", savestate_save }, 1.8429 + { "load", savestate_load }, 1.8430 + 1.8431 + { NULL, NULL } 1.8432 +}; 1.8433 + 1.8434 +static const struct luaL_reg movielib[] = { 1.8435 + { "active", movie_isactive }, 1.8436 + { "recording", movie_isrecording }, 1.8437 + { "playing", movie_isplaying }, 1.8438 + { "mode", movie_getmode }, 1.8439 + 1.8440 + { "length", movie_getlength }, 1.8441 + { "author", movie_getauthor }, 1.8442 + { "name", movie_getfilename }, 1.8443 + { "rerecordcount", movie_rerecordcount }, 1.8444 + { "setrerecordcount", movie_setrerecordcount }, 1.8445 + 1.8446 + { "rerecordcounting", movie_rerecordcounting }, 1.8447 + { "framecount", vba_framecount }, // for those familiar with 1.8448 + // other emulators that have 1.8449 + // movie.framecount() 1.8450 + // instead of 1.8451 + // emulatorname.framecount() 1.8452 + 1.8453 + { "stop", movie_stop }, 1.8454 + 1.8455 + // alternative names 1.8456 + { "close", movie_stop }, 1.8457 + { "getauthor", movie_getauthor }, 1.8458 + { "getname", movie_getfilename }, 1.8459 + { NULL, NULL } 1.8460 +}; 1.8461 + 1.8462 +static const struct luaL_reg guilib[] = { 1.8463 + { "register", gui_register }, 1.8464 + { "text", gui_text }, 1.8465 + { "box", gui_drawbox }, 1.8466 + { "line", gui_drawline }, 1.8467 + { "pixel", gui_drawpixel }, 1.8468 + { "opacity", gui_setopacity }, 1.8469 + { "transparency", gui_transparency }, 1.8470 + { "popup", gui_popup }, 1.8471 + { "parsecolor", gui_parsecolor }, 1.8472 + { "gdscreenshot", gui_gdscreenshot }, 1.8473 + { "gdoverlay", gui_gdoverlay }, 1.8474 + { "getpixel", gui_getpixel }, 1.8475 + 1.8476 + // alternative names 1.8477 + { "drawtext", gui_text }, 1.8478 + { "drawbox", gui_drawbox }, 1.8479 + { "drawline", gui_drawline }, 1.8480 + { "drawpixel", gui_drawpixel }, 1.8481 + { "setpixel", gui_drawpixel }, 1.8482 + { "writepixel", gui_drawpixel }, 1.8483 + { "rect", gui_drawbox }, 1.8484 + { "drawrect", gui_drawbox }, 1.8485 + { "drawimage", gui_gdoverlay }, 1.8486 + { "image", gui_gdoverlay }, 1.8487 + { "readpixel", gui_getpixel }, 1.8488 + { NULL, NULL } 1.8489 +}; 1.8490 + 1.8491 +static const struct luaL_reg inputlib[] = { 1.8492 + { "get", input_getcurrentinputstatus }, 1.8493 + 1.8494 + // alternative names 1.8495 + { "read", input_getcurrentinputstatus }, 1.8496 + { NULL, NULL } 1.8497 +}; 1.8498 + 1.8499 +static const struct luaL_reg soundlib[] = { 1.8500 + { "get", sound_get }, 1.8501 + 1.8502 + // alternative names 1.8503 + { NULL, NULL } 1.8504 +}; 1.8505 1.8506 // gocha: since vba dumps avi so badly, 1.8507 // I add avilib as a workaround for enhanced video encoding. 1.8508 - static const struct luaL_reg avilib[] = { 1.8509 - { "framecount", avi_framecount }, 1.8510 - { "pause", avi_pause }, 1.8511 - { "resume", avi_resume }, 1.8512 - { NULL, NULL } 1.8513 - }; 1.8514 - 1.8515 - void CallExitFunction(void) 1.8516 - { 1.8517 - if (!LUA) 1.8518 - return; 1.8519 - 1.8520 - lua_settop(LUA, 0); 1.8521 - lua_getfield(LUA, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEXIT]); 1.8522 - 1.8523 - int errorcode = 0; 1.8524 - if (lua_isfunction(LUA, -1)) 1.8525 - { 1.8526 - errorcode = lua_pcall(LUA, 0, 0, 0); 1.8527 - } 1.8528 - 1.8529 - if (errorcode) 1.8530 - HandleCallbackError(LUA); 1.8531 - } 1.8532 - 1.8533 - void VBALuaFrameBoundary(void) 1.8534 - { 1.8535 - // printf("Lua Frame\n"); 1.8536 - 1.8537 - lua_joypads_used = 0; 1.8538 - 1.8539 - // HA! 1.8540 - if (!LUA || !luaRunning) 1.8541 - return; 1.8542 - 1.8543 - // Our function needs calling 1.8544 - lua_settop(LUA, 0); 1.8545 - lua_getfield(LUA, LUA_REGISTRYINDEX, frameAdvanceThread); 1.8546 - 1.8547 - lua_State *thread = lua_tothread(LUA, 1); 1.8548 - 1.8549 - // Lua calling C must know that we're busy inside a frame boundary 1.8550 - frameBoundary = true; 1.8551 - frameAdvanceWaiting = false; 1.8552 - 1.8553 - numTries = 1000; 1.8554 - 1.8555 - int result = lua_resume(thread, 0); 1.8556 - 1.8557 - if (result == LUA_YIELD) 1.8558 - { 1.8559 - // Okay, we're fine with that. 1.8560 - } 1.8561 - else if (result != 0) 1.8562 - { 1.8563 - // Done execution by bad causes 1.8564 - VBALuaOnStop(); 1.8565 - lua_pushnil(LUA); 1.8566 - lua_setfield(LUA, LUA_REGISTRYINDEX, frameAdvanceThread); 1.8567 - lua_pushnil(LUA); 1.8568 - lua_setfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 1.8569 - 1.8570 - // Error? 1.8571 -//#if (defined(WIN32) && !defined(SDL)) 1.8572 -// info_print(info_uid, lua_tostring(thread, -1)); //Clear_Sound_Buffer(); 1.8573 -// AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(thread, -1), "Lua run error", MB_OK | MB_ICONSTOP); 1.8574 -//#else 1.8575 -// fprintf(stderr, "Lua thread bombed out: %s\n", lua_tostring(thread, -1)); 1.8576 -//#endif 1.8577 - printerror(thread, -1); 1.8578 - } 1.8579 - else 1.8580 - { 1.8581 - VBALuaOnStop(); 1.8582 - printf("Script died of natural causes.\n"); 1.8583 - } 1.8584 - 1.8585 - // Past here, VBA actually runs, so any Lua code is called mid-frame. We must 1.8586 - // not do anything too stupid, so let ourselves know. 1.8587 - frameBoundary = false; 1.8588 - 1.8589 - if (!frameAdvanceWaiting) 1.8590 - { 1.8591 - VBALuaOnStop(); 1.8592 - } 1.8593 - } 1.8594 +static const struct luaL_reg avilib[] = { 1.8595 + { "framecount", avi_framecount }, 1.8596 + { "pause", avi_pause }, 1.8597 + { "resume", avi_resume }, 1.8598 + { NULL, NULL } 1.8599 +}; 1.8600 + 1.8601 +void CallExitFunction(void) 1.8602 +{ 1.8603 + if (!LUA) 1.8604 + return; 1.8605 + 1.8606 + lua_settop(LUA, 0); 1.8607 + lua_getfield(LUA, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_BEFOREEXIT]); 1.8608 + 1.8609 + int errorcode = 0; 1.8610 + if (lua_isfunction(LUA, -1)) 1.8611 + { 1.8612 + errorcode = lua_pcall(LUA, 0, 0, 0); 1.8613 + } 1.8614 + 1.8615 + if (errorcode) 1.8616 + HandleCallbackError(LUA); 1.8617 +} 1.8618 + 1.8619 +void VBALuaFrameBoundary(void) 1.8620 +{ 1.8621 + // printf("Lua Frame\n"); 1.8622 + 1.8623 + lua_joypads_used = 0; 1.8624 + 1.8625 + // HA! 1.8626 + if (!LUA || !luaRunning) 1.8627 + return; 1.8628 + 1.8629 + // Our function needs calling 1.8630 + lua_settop(LUA, 0); 1.8631 + lua_getfield(LUA, LUA_REGISTRYINDEX, frameAdvanceThread); 1.8632 + 1.8633 + lua_State *thread = lua_tothread(LUA, 1); 1.8634 + 1.8635 + // Lua calling C must know that we're busy inside a frame boundary 1.8636 + frameBoundary = true; 1.8637 + frameAdvanceWaiting = false; 1.8638 + 1.8639 + numTries = 1000; 1.8640 + 1.8641 + int result = lua_resume(thread, 0); 1.8642 + 1.8643 + if (result == LUA_YIELD) 1.8644 + { 1.8645 + // Okay, we're fine with that. 1.8646 + } 1.8647 + else if (result != 0) 1.8648 + { 1.8649 + // Done execution by bad causes 1.8650 + VBALuaOnStop(); 1.8651 + lua_pushnil(LUA); 1.8652 + lua_setfield(LUA, LUA_REGISTRYINDEX, frameAdvanceThread); 1.8653 + lua_pushnil(LUA); 1.8654 + lua_setfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 1.8655 + 1.8656 + // Error? 1.8657 + //#if (defined(WIN32) && !defined(SDL)) 1.8658 + // info_print(info_uid, lua_tostring(thread, -1)); //Clear_Sound_Buffer(); 1.8659 + // AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(thread, -1), "Lua run error", MB_OK | MB_ICONSTOP); 1.8660 + //#else 1.8661 + // fprintf(stderr, "Lua thread bombed out: %s\n", lua_tostring(thread, -1)); 1.8662 + //#endif 1.8663 + printerror(thread, -1); 1.8664 + } 1.8665 + else 1.8666 + { 1.8667 + VBALuaOnStop(); 1.8668 + printf("Script died of natural causes.\n"); 1.8669 + } 1.8670 + 1.8671 + // Past here, VBA actually runs, so any Lua code is called mid-frame. We must 1.8672 + // not do anything too stupid, so let ourselves know. 1.8673 + frameBoundary = false; 1.8674 + 1.8675 + if (!frameAdvanceWaiting) 1.8676 + { 1.8677 + VBALuaOnStop(); 1.8678 + } 1.8679 +} 1.8680 1.8681 /** 1.8682 * Loads and runs the given Lua script. 1.8683 @@ -4740,165 +4740,165 @@ 1.8684 * 1.8685 * Returns true on success, false on failure. 1.8686 */ 1.8687 - int VBALoadLuaCode(const char *filename) 1.8688 - { 1.8689 - static bool sfmtInitialized = false; 1.8690 - if (!sfmtInitialized) 1.8691 - { 1.8692 - init_gen_rand((unsigned)time(NULL)); 1.8693 - sfmtInitialized = true; 1.8694 - } 1.8695 - 1.8696 - if (filename != luaScriptName) 1.8697 - { 1.8698 - if (luaScriptName) 1.8699 - free(luaScriptName); 1.8700 - luaScriptName = strdup(filename); 1.8701 - } 1.8702 - 1.8703 - //stop any lua we might already have had running 1.8704 - VBALuaStop(); 1.8705 - 1.8706 - // Set current directory from filename (for dofile) 1.8707 - char dir[_MAX_PATH]; 1.8708 - char *slash, *backslash; 1.8709 - strcpy(dir, filename); 1.8710 - slash = strrchr(dir, '/'); 1.8711 - backslash = strrchr(dir, '\\'); 1.8712 - if (!slash || (backslash && backslash < slash)) 1.8713 - slash = backslash; 1.8714 - if (slash) 1.8715 - { 1.8716 - slash[1] = '\0'; // keep slash itself for some reasons 1.8717 - chdir(dir); 1.8718 - } 1.8719 - 1.8720 - if (!LUA) 1.8721 - { 1.8722 - LUA = lua_open(); 1.8723 - luaL_openlibs(LUA); 1.8724 - 1.8725 - luaL_register(LUA, "emu", vbalib); // added for better cross-emulator compatibility 1.8726 - luaL_register(LUA, "vba", vbalib); // kept for backward compatibility 1.8727 - luaL_register(LUA, "memory", memorylib); 1.8728 - luaL_register(LUA, "joypad", joypadlib); 1.8729 - luaL_register(LUA, "savestate", savestatelib); 1.8730 - luaL_register(LUA, "movie", movielib); 1.8731 - luaL_register(LUA, "gui", guilib); 1.8732 - luaL_register(LUA, "input", inputlib); 1.8733 - luaL_register(LUA, "sound", soundlib); 1.8734 - luaL_register(LUA, "bit", bit_funcs); // LuaBitOp library 1.8735 - luaL_register(LUA, "avi", avilib); // workaround for enhanced video encoding 1.8736 - lua_settop(LUA, 0); // clean the stack, because each call to luaL_register leaves a table on top 1.8737 - 1.8738 - // register a few utility functions outside of libraries (in the global namespace) 1.8739 - lua_register(LUA, "print", print); 1.8740 - lua_register(LUA, "tostring", tostring); 1.8741 - lua_register(LUA, "addressof", addressof); 1.8742 - lua_register(LUA, "copytable", copytable); 1.8743 - 1.8744 - // old bit operation functions 1.8745 - lua_register(LUA, "AND", bit_band); 1.8746 - lua_register(LUA, "OR", bit_bor); 1.8747 - lua_register(LUA, "XOR", bit_bxor); 1.8748 - lua_register(LUA, "SHIFT", bit_bshift_emulua); 1.8749 - lua_register(LUA, "BIT", bitbit); 1.8750 - 1.8751 - luabitop_validate(LUA); 1.8752 - 1.8753 - lua_pushstring(LUA, "math"); 1.8754 - lua_gettable(LUA, LUA_GLOBALSINDEX); 1.8755 - lua_pushcfunction(LUA, sfmt_random); 1.8756 - lua_setfield(LUA, -2, "random"); 1.8757 - lua_pushcfunction(LUA, sfmt_randomseed); 1.8758 - lua_setfield(LUA, -2, "randomseed"); 1.8759 - lua_settop(LUA, 0); 1.8760 - 1.8761 - // push arrays for storing hook functions in 1.8762 - for (int i = 0; i < LUAMEMHOOK_COUNT; i++) 1.8763 - { 1.8764 - lua_newtable(LUA); 1.8765 - lua_setfield(LUA, LUA_REGISTRYINDEX, luaMemHookTypeStrings[i]); 1.8766 - } 1.8767 - } 1.8768 - 1.8769 - // We make our thread NOW because we want it at the bottom of the stack. 1.8770 - // If all goes wrong, we let the garbage collector remove it. 1.8771 - lua_State *thread = lua_newthread(LUA); 1.8772 - 1.8773 - // Load the data 1.8774 - int result = luaL_loadfile(LUA, filename); 1.8775 - 1.8776 - if (result) 1.8777 - { 1.8778 -//#if (defined(WIN32) && !defined(SDL)) 1.8779 -// info_print(info_uid, lua_tostring(LUA, -1)); //Clear_Sound_Buffer(); 1.8780 -// AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(LUA, -1), "Lua load error", MB_OK | MB_ICONSTOP); 1.8781 -//#else 1.8782 -// fprintf(stderr, "Failed to compile file: %s\n", lua_tostring(LUA, -1)); 1.8783 -//#endif 1.8784 - printerror(LUA, -1); 1.8785 - 1.8786 - // Wipe the stack. Our thread 1.8787 - lua_settop(LUA, 0); 1.8788 - return 0; // Oh shit. 1.8789 - } 1.8790 - 1.8791 - // Get our function into it 1.8792 - lua_xmove(LUA, thread, 1); 1.8793 - 1.8794 - // Save the thread to the registry. This is why I make the thread FIRST. 1.8795 - lua_setfield(LUA, LUA_REGISTRYINDEX, frameAdvanceThread); 1.8796 - 1.8797 - // Initialize settings 1.8798 - luaRunning = true; 1.8799 - skipRerecords = false; 1.8800 - numMemHooks = 0; 1.8801 - transparencyModifier = 255; // opaque 1.8802 - lua_joypads_used = 0; // not used 1.8803 - //wasPaused = systemIsPaused(); 1.8804 - //systemSetPause(false); 1.8805 - 1.8806 - // Set up our protection hook to be executed once every 10,000 bytecode instructions. 1.8807 - lua_sethook(thread, VBALuaHookFunction, LUA_MASKCOUNT, 10000); 1.8808 +int VBALoadLuaCode(const char *filename) 1.8809 +{ 1.8810 + static bool sfmtInitialized = false; 1.8811 + if (!sfmtInitialized) 1.8812 + { 1.8813 + init_gen_rand((unsigned)time(NULL)); 1.8814 + sfmtInitialized = true; 1.8815 + } 1.8816 + 1.8817 + if (filename != luaScriptName) 1.8818 + { 1.8819 + if (luaScriptName) 1.8820 + free(luaScriptName); 1.8821 + luaScriptName = strdup(filename); 1.8822 + } 1.8823 + 1.8824 + //stop any lua we might already have had running 1.8825 + VBALuaStop(); 1.8826 + 1.8827 + // Set current directory from filename (for dofile) 1.8828 + char dir[_MAX_PATH]; 1.8829 + char *slash, *backslash; 1.8830 + strcpy(dir, filename); 1.8831 + slash = strrchr(dir, '/'); 1.8832 + backslash = strrchr(dir, '\\'); 1.8833 + if (!slash || (backslash && backslash < slash)) 1.8834 + slash = backslash; 1.8835 + if (slash) 1.8836 + { 1.8837 + slash[1] = '\0'; // keep slash itself for some reasons 1.8838 + chdir(dir); 1.8839 + } 1.8840 + 1.8841 + if (!LUA) 1.8842 + { 1.8843 + LUA = lua_open(); 1.8844 + luaL_openlibs(LUA); 1.8845 + 1.8846 + luaL_register(LUA, "emu", vbalib); // added for better cross-emulator compatibility 1.8847 + luaL_register(LUA, "vba", vbalib); // kept for backward compatibility 1.8848 + luaL_register(LUA, "memory", memorylib); 1.8849 + luaL_register(LUA, "joypad", joypadlib); 1.8850 + luaL_register(LUA, "savestate", savestatelib); 1.8851 + luaL_register(LUA, "movie", movielib); 1.8852 + luaL_register(LUA, "gui", guilib); 1.8853 + luaL_register(LUA, "input", inputlib); 1.8854 + luaL_register(LUA, "sound", soundlib); 1.8855 + luaL_register(LUA, "bit", bit_funcs); // LuaBitOp library 1.8856 + luaL_register(LUA, "avi", avilib); // workaround for enhanced video encoding 1.8857 + lua_settop(LUA, 0); // clean the stack, because each call to luaL_register leaves a table on top 1.8858 + 1.8859 + // register a few utility functions outside of libraries (in the global namespace) 1.8860 + lua_register(LUA, "print", print); 1.8861 + lua_register(LUA, "tostring", tostring); 1.8862 + lua_register(LUA, "addressof", addressof); 1.8863 + lua_register(LUA, "copytable", copytable); 1.8864 + 1.8865 + // old bit operation functions 1.8866 + lua_register(LUA, "AND", bit_band); 1.8867 + lua_register(LUA, "OR", bit_bor); 1.8868 + lua_register(LUA, "XOR", bit_bxor); 1.8869 + lua_register(LUA, "SHIFT", bit_bshift_emulua); 1.8870 + lua_register(LUA, "BIT", bitbit); 1.8871 + 1.8872 + luabitop_validate(LUA); 1.8873 + 1.8874 + lua_pushstring(LUA, "math"); 1.8875 + lua_gettable(LUA, LUA_GLOBALSINDEX); 1.8876 + lua_pushcfunction(LUA, sfmt_random); 1.8877 + lua_setfield(LUA, -2, "random"); 1.8878 + lua_pushcfunction(LUA, sfmt_randomseed); 1.8879 + lua_setfield(LUA, -2, "randomseed"); 1.8880 + lua_settop(LUA, 0); 1.8881 + 1.8882 + // push arrays for storing hook functions in 1.8883 + for (int i = 0; i < LUAMEMHOOK_COUNT; i++) 1.8884 + { 1.8885 + lua_newtable(LUA); 1.8886 + lua_setfield(LUA, LUA_REGISTRYINDEX, luaMemHookTypeStrings[i]); 1.8887 + } 1.8888 + } 1.8889 + 1.8890 + // We make our thread NOW because we want it at the bottom of the stack. 1.8891 + // If all goes wrong, we let the garbage collector remove it. 1.8892 + lua_State *thread = lua_newthread(LUA); 1.8893 + 1.8894 + // Load the data 1.8895 + int result = luaL_loadfile(LUA, filename); 1.8896 + 1.8897 + if (result) 1.8898 + { 1.8899 + //#if (defined(WIN32) && !defined(SDL)) 1.8900 + // info_print(info_uid, lua_tostring(LUA, -1)); //Clear_Sound_Buffer(); 1.8901 + // AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(LUA, -1), "Lua load error", MB_OK | MB_ICONSTOP); 1.8902 + //#else 1.8903 + // fprintf(stderr, "Failed to compile file: %s\n", lua_tostring(LUA, -1)); 1.8904 + //#endif 1.8905 + printerror(LUA, -1); 1.8906 + 1.8907 + // Wipe the stack. Our thread 1.8908 + lua_settop(LUA, 0); 1.8909 + return 0; // Oh shit. 1.8910 + } 1.8911 + 1.8912 + // Get our function into it 1.8913 + lua_xmove(LUA, thread, 1); 1.8914 + 1.8915 + // Save the thread to the registry. This is why I make the thread FIRST. 1.8916 + lua_setfield(LUA, LUA_REGISTRYINDEX, frameAdvanceThread); 1.8917 + 1.8918 + // Initialize settings 1.8919 + luaRunning = true; 1.8920 + skipRerecords = false; 1.8921 + numMemHooks = 0; 1.8922 + transparencyModifier = 255; // opaque 1.8923 + lua_joypads_used = 0; // not used 1.8924 + //wasPaused = systemIsPaused(); 1.8925 + //systemSetPause(false); 1.8926 + 1.8927 + // Set up our protection hook to be executed once every 10,000 bytecode instructions. 1.8928 + lua_sethook(thread, VBALuaHookFunction, LUA_MASKCOUNT, 10000); 1.8929 1.8930 #ifdef WIN32 1.8931 - info_print = PrintToWindowConsole; 1.8932 - info_onstart = WinLuaOnStart; 1.8933 - info_onstop = WinLuaOnStop; 1.8934 - if (!LuaConsoleHWnd) 1.8935 - LuaConsoleHWnd = CreateDialog(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDD_LUA), 1.8936 - AfxGetMainWnd()->GetSafeHwnd(), (DLGPROC) DlgLuaScriptDialog); 1.8937 - info_uid = (int)LuaConsoleHWnd; 1.8938 + info_print = PrintToWindowConsole; 1.8939 + info_onstart = WinLuaOnStart; 1.8940 + info_onstop = WinLuaOnStop; 1.8941 + if (!LuaConsoleHWnd) 1.8942 + LuaConsoleHWnd = CreateDialog(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDD_LUA), 1.8943 + AfxGetMainWnd()->GetSafeHwnd(), (DLGPROC) DlgLuaScriptDialog); 1.8944 + info_uid = (int)LuaConsoleHWnd; 1.8945 #else 1.8946 - info_print = NULL; 1.8947 - info_onstart = NULL; 1.8948 - info_onstop = NULL; 1.8949 + info_print = NULL; 1.8950 + info_onstart = NULL; 1.8951 + info_onstop = NULL; 1.8952 #endif 1.8953 - if (info_onstart) 1.8954 - info_onstart(info_uid); 1.8955 - 1.8956 - // And run it right now. :) 1.8957 - VBALuaFrameBoundary(); 1.8958 - systemRenderFrame(); 1.8959 - 1.8960 - // We're done. 1.8961 - return 1; 1.8962 - } 1.8963 + if (info_onstart) 1.8964 + info_onstart(info_uid); 1.8965 + 1.8966 + // And run it right now. :) 1.8967 + VBALuaFrameBoundary(); 1.8968 + systemRenderFrame(); 1.8969 + 1.8970 + // We're done. 1.8971 + return 1; 1.8972 +} 1.8973 1.8974 /** 1.8975 * Equivalent to repeating the last VBALoadLuaCode() call. 1.8976 */ 1.8977 - int VBAReloadLuaCode(void) 1.8978 - { 1.8979 - if (!luaScriptName) 1.8980 - { 1.8981 - systemScreenMessage("There's no script to reload."); 1.8982 - return 0; 1.8983 - } 1.8984 - else 1.8985 - return VBALoadLuaCode(luaScriptName); 1.8986 - } 1.8987 +int VBAReloadLuaCode(void) 1.8988 +{ 1.8989 + if (!luaScriptName) 1.8990 + { 1.8991 + systemScreenMessage("There's no script to reload."); 1.8992 + return 0; 1.8993 + } 1.8994 + else 1.8995 + return VBALoadLuaCode(luaScriptName); 1.8996 +} 1.8997 1.8998 /** 1.8999 * Terminates a running Lua script by killing the whole Lua engine. 1.9000 @@ -4906,55 +4906,55 @@ 1.9001 * Always safe to call, except from within a lua call itself (duh). 1.9002 * 1.9003 */ 1.9004 - void VBALuaStop(void) 1.9005 - { 1.9006 - //already killed 1.9007 - if (!LUA) 1.9008 - return; 1.9009 - 1.9010 - //execute the user's shutdown callbacks 1.9011 - CallExitFunction(); 1.9012 - 1.9013 - /*info.*/ numMemHooks = 0; 1.9014 - for (int i = 0; i < LUAMEMHOOK_COUNT; i++) 1.9015 - CalculateMemHookRegions((LuaMemHookType)i); 1.9016 - 1.9017 - //sometimes iup uninitializes com 1.9018 - //MBG TODO - test whether this is really necessary. i dont think it is 1.9019 +void VBALuaStop(void) 1.9020 +{ 1.9021 + //already killed 1.9022 + if (!LUA) 1.9023 + return; 1.9024 + 1.9025 + //execute the user's shutdown callbacks 1.9026 + CallExitFunction(); 1.9027 + 1.9028 + /*info.*/ numMemHooks = 0; 1.9029 + for (int i = 0; i < LUAMEMHOOK_COUNT; i++) 1.9030 + CalculateMemHookRegions((LuaMemHookType)i); 1.9031 + 1.9032 + //sometimes iup uninitializes com 1.9033 + //MBG TODO - test whether this is really necessary. i dont think it is 1.9034 #if (defined(WIN32) && !defined(SDL)) 1.9035 - CoInitialize(0); 1.9036 + CoInitialize(0); 1.9037 #endif 1.9038 1.9039 - if (info_onstop) 1.9040 - info_onstop(info_uid); 1.9041 - 1.9042 - //lua_gc(LUA,LUA_GCCOLLECT,0); 1.9043 - lua_close(LUA); // this invokes our garbage collectors for us 1.9044 - LUA = NULL; 1.9045 - VBALuaOnStop(); 1.9046 - } 1.9047 + if (info_onstop) 1.9048 + info_onstop(info_uid); 1.9049 + 1.9050 + //lua_gc(LUA,LUA_GCCOLLECT,0); 1.9051 + lua_close(LUA); // this invokes our garbage collectors for us 1.9052 + LUA = NULL; 1.9053 + VBALuaOnStop(); 1.9054 +} 1.9055 1.9056 /** 1.9057 * Returns true if there is a Lua script running. 1.9058 * 1.9059 */ 1.9060 - int VBALuaRunning(void) 1.9061 - { 1.9062 - // FIXME: return false when no callback functions are registered. 1.9063 - return (int) (LUA != NULL); // should return true if callback functions are active. 1.9064 - } 1.9065 +int VBALuaRunning(void) 1.9066 +{ 1.9067 + // FIXME: return false when no callback functions are registered. 1.9068 + return (int) (LUA != NULL); // should return true if callback functions are active. 1.9069 +} 1.9070 1.9071 /** 1.9072 * Returns true if Lua would like to steal the given joypad control. 1.9073 * 1.9074 * Range is 0 through 3 1.9075 */ 1.9076 - int VBALuaUsingJoypad(int which) 1.9077 - { 1.9078 - if (which < 0 || which > 3) 1.9079 - which = systemGetDefaultJoypad(); 1.9080 - return lua_joypads_used & (1 << which); 1.9081 - } 1.9082 +int VBALuaUsingJoypad(int which) 1.9083 +{ 1.9084 + if (which < 0 || which > 3) 1.9085 + which = systemGetDefaultJoypad(); 1.9086 + return lua_joypads_used & (1 << which); 1.9087 +} 1.9088 1.9089 /** 1.9090 * Reads the buttons Lua is feeding for the given joypad, in the same 1.9091 @@ -4963,14 +4963,14 @@ 1.9092 * <del>This function must not be called more than once per frame. </del>Ideally exactly once 1.9093 * per frame (if VBALuaUsingJoypad says it's safe to do so) 1.9094 */ 1.9095 - int VBALuaReadJoypad(int which) 1.9096 - { 1.9097 - if (which < 0 || which > 3) 1.9098 - which = systemGetDefaultJoypad(); 1.9099 - 1.9100 - //lua_joypads_used &= ~(1 << which); 1.9101 - return lua_joypads[which]; 1.9102 - } 1.9103 +int VBALuaReadJoypad(int which) 1.9104 +{ 1.9105 + if (which < 0 || which > 3) 1.9106 + which = systemGetDefaultJoypad(); 1.9107 + 1.9108 + //lua_joypads_used &= ~(1 << which); 1.9109 + return lua_joypads[which]; 1.9110 +} 1.9111 1.9112 /** 1.9113 * If this function returns true, the movie code should NOT increment 1.9114 @@ -4978,125 +4978,125 @@ 1.9115 * 1.9116 * This function will not return true if a script is not running. 1.9117 */ 1.9118 - bool8 VBALuaRerecordCountSkip(void) 1.9119 - { 1.9120 - // FIXME: return true if (there are any active callback functions && skipRerecords) 1.9121 - return LUA && luaRunning && skipRerecords; 1.9122 - } 1.9123 +bool8 VBALuaRerecordCountSkip(void) 1.9124 +{ 1.9125 + // FIXME: return true if (there are any active callback functions && skipRerecords) 1.9126 + return LUA && luaRunning && skipRerecords; 1.9127 +} 1.9128 1.9129 /** 1.9130 * Given a screen with the indicated resolution, 1.9131 * draw the current GUI onto it. 1.9132 */ 1.9133 - void VBALuaGui(uint8 *screen, int ppl, int width, int height) 1.9134 - { 1.9135 - if (!LUA /* || !luaRunning*/) 1.9136 - return; 1.9137 - 1.9138 - // First, check if we're being called by anybody 1.9139 - lua_getfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 1.9140 - 1.9141 - if (lua_isfunction(LUA, -1)) 1.9142 - { 1.9143 - // We call it now 1.9144 - numTries = 1000; 1.9145 - 1.9146 - int ret = lua_pcall(LUA, 0, 0, 0); 1.9147 - if (ret != 0) 1.9148 - { 1.9149 - // This is grounds for trashing the function 1.9150 - // Note: This must be done before the messagebox pops up, 1.9151 - // otherwise the messagebox will cause a paint event which causes a weird 1.9152 - // infinite call sequence that makes Snes9x silently exit with error code 3, 1.9153 - // if a Lua GUI function crashes. (nitsuja) 1.9154 - lua_pushnil(LUA); 1.9155 - lua_setfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 1.9156 - 1.9157 -//#if (defined(WIN32) && !defined(SDL)) 1.9158 -// info_print(info_uid, lua_tostring(LUA, -1)); //AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(LUA, -1), "Lua Error 1.9159 -// in GUI function", MB_OK); 1.9160 -//#else 1.9161 -// fprintf(stderr, "Lua error in gui.register function: %s\n", lua_tostring(LUA, -1)); 1.9162 -//#endif 1.9163 - printerror(LUA, -1); 1.9164 - } 1.9165 - } 1.9166 - 1.9167 - // And wreak the stack 1.9168 - lua_settop(LUA, 0); 1.9169 - 1.9170 - if (!gui_used) 1.9171 - return; 1.9172 - 1.9173 - gui_used = false; 1.9174 - 1.9175 - int x, y; 1.9176 - 1.9177 - //int pitch = (((ppl * systemColorDepth + 7)>>3)+3)&~3; 1.9178 - int pitch = ppl * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); 1.9179 - 1.9180 - if (width > LUA_SCREEN_WIDTH) 1.9181 - width = LUA_SCREEN_WIDTH; 1.9182 - if (height > LUA_SCREEN_HEIGHT) 1.9183 - height = LUA_SCREEN_HEIGHT; 1.9184 - 1.9185 - GetColorFunc getColor; 1.9186 - SetColorFunc setColor; 1.9187 - getColorIOFunc(systemColorDepth, &getColor, &setColor); 1.9188 - 1.9189 - for (y = 0; y < height; y++) 1.9190 - { 1.9191 - uint8 *scr = &screen[y * pitch]; 1.9192 - for (x = 0; x < width; x++, scr += systemColorDepth / 8) 1.9193 - { 1.9194 - const uint8 gui_alpha = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4 + 3]; 1.9195 - if (gui_alpha == 0) 1.9196 - { 1.9197 - // do nothing 1.9198 - continue; 1.9199 - } 1.9200 - 1.9201 - const uint8 gui_red = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4 + 2]; 1.9202 - const uint8 gui_green = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4 + 1]; 1.9203 - const uint8 gui_blue = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4]; 1.9204 - int red, green, blue; 1.9205 - 1.9206 - if (gui_alpha == 255) 1.9207 - { 1.9208 - // direct copy 1.9209 - red = gui_red; 1.9210 - green = gui_green; 1.9211 - blue = gui_blue; 1.9212 - } 1.9213 - else 1.9214 - { 1.9215 - // alpha-blending 1.9216 - uint8 scr_red, scr_green, scr_blue; 1.9217 - getColor(scr, &scr_red, &scr_green, &scr_blue); 1.9218 - red = (((int)gui_red - scr_red) * gui_alpha / 255 + scr_red) & 255; 1.9219 - green = (((int)gui_green - scr_green) * gui_alpha / 255 + scr_green) & 255; 1.9220 - blue = (((int)gui_blue - scr_blue) * gui_alpha / 255 + scr_blue) & 255; 1.9221 - } 1.9222 - 1.9223 - setColor(scr, (uint8) red, (uint8) green, (uint8) blue); 1.9224 - } 1.9225 - } 1.9226 - 1.9227 - return; 1.9228 - } 1.9229 - 1.9230 - void VBALuaClearGui(void) 1.9231 - { 1.9232 - gui_used = false; 1.9233 - } 1.9234 - 1.9235 - lua_State *VBAGetLuaState() 1.9236 - { 1.9237 - return LUA; 1.9238 - } 1.9239 - 1.9240 - char *VBAGetLuaScriptName() 1.9241 - { 1.9242 - return luaScriptName; 1.9243 - } 1.9244 - 1.9245 +void VBALuaGui(uint8 *screen, int ppl, int width, int height) 1.9246 +{ 1.9247 + if (!LUA /* || !luaRunning*/) 1.9248 + return; 1.9249 + 1.9250 + // First, check if we're being called by anybody 1.9251 + lua_getfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 1.9252 + 1.9253 + if (lua_isfunction(LUA, -1)) 1.9254 + { 1.9255 + // We call it now 1.9256 + numTries = 1000; 1.9257 + 1.9258 + int ret = lua_pcall(LUA, 0, 0, 0); 1.9259 + if (ret != 0) 1.9260 + { 1.9261 + // This is grounds for trashing the function 1.9262 + // Note: This must be done before the messagebox pops up, 1.9263 + // otherwise the messagebox will cause a paint event which causes a weird 1.9264 + // infinite call sequence that makes Snes9x silently exit with error code 3, 1.9265 + // if a Lua GUI function crashes. (nitsuja) 1.9266 + lua_pushnil(LUA); 1.9267 + lua_setfield(LUA, LUA_REGISTRYINDEX, guiCallbackTable); 1.9268 + 1.9269 + //#if (defined(WIN32) && !defined(SDL)) 1.9270 + // info_print(info_uid, lua_tostring(LUA, -1)); //AfxGetApp()->m_pMainWnd->MessageBox(lua_tostring(LUA, -1), "Lua Error 1.9271 + // in GUI function", MB_OK); 1.9272 + //#else 1.9273 + // fprintf(stderr, "Lua error in gui.register function: %s\n", lua_tostring(LUA, -1)); 1.9274 + //#endif 1.9275 + printerror(LUA, -1); 1.9276 + } 1.9277 + } 1.9278 + 1.9279 + // And wreak the stack 1.9280 + lua_settop(LUA, 0); 1.9281 + 1.9282 + if (!gui_used) 1.9283 + return; 1.9284 + 1.9285 + gui_used = false; 1.9286 + 1.9287 + int x, y; 1.9288 + 1.9289 + //int pitch = (((ppl * systemColorDepth + 7)>>3)+3)&~3; 1.9290 + int pitch = ppl * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); 1.9291 + 1.9292 + if (width > LUA_SCREEN_WIDTH) 1.9293 + width = LUA_SCREEN_WIDTH; 1.9294 + if (height > LUA_SCREEN_HEIGHT) 1.9295 + height = LUA_SCREEN_HEIGHT; 1.9296 + 1.9297 + GetColorFunc getColor; 1.9298 + SetColorFunc setColor; 1.9299 + getColorIOFunc(systemColorDepth, &getColor, &setColor); 1.9300 + 1.9301 + for (y = 0; y < height; y++) 1.9302 + { 1.9303 + uint8 *scr = &screen[y * pitch]; 1.9304 + for (x = 0; x < width; x++, scr += systemColorDepth / 8) 1.9305 + { 1.9306 + const uint8 gui_alpha = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4 + 3]; 1.9307 + if (gui_alpha == 0) 1.9308 + { 1.9309 + // do nothing 1.9310 + continue; 1.9311 + } 1.9312 + 1.9313 + const uint8 gui_red = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4 + 2]; 1.9314 + const uint8 gui_green = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4 + 1]; 1.9315 + const uint8 gui_blue = gui_data[(y * LUA_SCREEN_WIDTH + x) * 4]; 1.9316 + int red, green, blue; 1.9317 + 1.9318 + if (gui_alpha == 255) 1.9319 + { 1.9320 + // direct copy 1.9321 + red = gui_red; 1.9322 + green = gui_green; 1.9323 + blue = gui_blue; 1.9324 + } 1.9325 + else 1.9326 + { 1.9327 + // alpha-blending 1.9328 + uint8 scr_red, scr_green, scr_blue; 1.9329 + getColor(scr, &scr_red, &scr_green, &scr_blue); 1.9330 + red = (((int)gui_red - scr_red) * gui_alpha / 255 + scr_red) & 255; 1.9331 + green = (((int)gui_green - scr_green) * gui_alpha / 255 + scr_green) & 255; 1.9332 + blue = (((int)gui_blue - scr_blue) * gui_alpha / 255 + scr_blue) & 255; 1.9333 + } 1.9334 + 1.9335 + setColor(scr, (uint8) red, (uint8) green, (uint8) blue); 1.9336 + } 1.9337 + } 1.9338 + 1.9339 + return; 1.9340 +} 1.9341 + 1.9342 +void VBALuaClearGui(void) 1.9343 +{ 1.9344 + gui_used = false; 1.9345 +} 1.9346 + 1.9347 +lua_State *VBAGetLuaState() 1.9348 +{ 1.9349 + return LUA; 1.9350 +} 1.9351 + 1.9352 +char *VBAGetLuaScriptName() 1.9353 +{ 1.9354 + return luaScriptName; 1.9355 +} 1.9356 +