this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

organized folders structure

Nesbox 0f5a8364 8f398802

+1744 -1743
+31 -30
CMakeLists.txt
··· 317 317 318 318 set(TIC80CORE_DIR ${CMAKE_SOURCE_DIR}/src) 319 319 set(TIC80CORE_SRC 320 - ${TIC80CORE_DIR}/tic80.c 321 - ${TIC80CORE_DIR}/tic.c 322 - ${TIC80CORE_DIR}/tilesheet.c 320 + ${TIC80CORE_DIR}/core/tic80.c 321 + ${TIC80CORE_DIR}/core/tic.c 322 + ${TIC80CORE_DIR}/core/cart.c 323 + ${TIC80CORE_DIR}/core/tilesheet.c 324 + ${TIC80CORE_DIR}/api/js.c 325 + ${TIC80CORE_DIR}/api/lua.c 326 + ${TIC80CORE_DIR}/api/wren.c 327 + ${TIC80CORE_DIR}/api/squirrel.c 328 + ${TIC80CORE_DIR}/ext/gif.c 323 329 ${TIC80CORE_DIR}/tools.c 324 - ${TIC80CORE_DIR}/jsapi.c 325 - ${TIC80CORE_DIR}/luaapi.c 326 - ${TIC80CORE_DIR}/wrenapi.c 327 - ${TIC80CORE_DIR}/squirrelapi.c 328 - ${TIC80CORE_DIR}/ext/gif.c 329 - ${TIC80CORE_DIR}/cart.c 330 330 ) 331 331 332 332 add_library(tic80core STATIC ${TIC80CORE_SRC}) ··· 336 336 ${THIRDPARTY_DIR}/moonscript 337 337 ${THIRDPARTY_DIR}/fennel 338 338 PUBLIC 339 - ${CMAKE_SOURCE_DIR}/include) 339 + ${CMAKE_SOURCE_DIR}/include 340 + ${CMAKE_SOURCE_DIR}/src) 340 341 341 342 target_link_libraries(tic80core lua lpeg wren squirrel giflib blipbuf duktape zlib) 342 343 ··· 574 575 575 576 if(BUILD_DEMO_CARTS) 576 577 577 - add_executable(cart2prj ${TOOLS_DIR}/cart2prj.c ${CMAKE_SOURCE_DIR}/src/project.c) 578 + add_executable(cart2prj ${TOOLS_DIR}/cart2prj.c ${CMAKE_SOURCE_DIR}/src/studio/project.c) 578 579 target_include_directories(cart2prj PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/include) 579 580 target_link_libraries(cart2prj tic80core) 580 581 581 - add_executable(prj2cart ${TOOLS_DIR}/prj2cart.c ${CMAKE_SOURCE_DIR}/src/project.c) 582 + add_executable(prj2cart ${TOOLS_DIR}/prj2cart.c ${CMAKE_SOURCE_DIR}/src/studio/project.c) 582 583 target_include_directories(prj2cart PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/include) 583 584 target_link_libraries(prj2cart tic80core) 584 585 ··· 624 625 625 626 set(TIC80LIB_DIR ${CMAKE_SOURCE_DIR}/src) 626 627 set(TIC80LIB_SRC 627 - ${TIC80LIB_DIR}/studio.c 628 - ${TIC80LIB_DIR}/console.c 629 - ${TIC80LIB_DIR}/run.c 628 + ${TIC80LIB_DIR}/studio/studio.c 629 + ${TIC80LIB_DIR}/studio/console.c 630 + ${TIC80LIB_DIR}/studio/run.c 631 + ${TIC80LIB_DIR}/studio/fs.c 632 + ${TIC80LIB_DIR}/studio/start.c 633 + ${TIC80LIB_DIR}/studio/sprite.c 634 + ${TIC80LIB_DIR}/studio/map.c 635 + ${TIC80LIB_DIR}/studio/sfx.c 636 + ${TIC80LIB_DIR}/studio/music.c 637 + ${TIC80LIB_DIR}/studio/world.c 638 + ${TIC80LIB_DIR}/studio/config.c 639 + ${TIC80LIB_DIR}/studio/code.c 640 + ${TIC80LIB_DIR}/studio/dialog.c 641 + ${TIC80LIB_DIR}/studio/menu.c 642 + ${TIC80LIB_DIR}/studio/surf.c 643 + ${TIC80LIB_DIR}/studio/project.c 630 644 ${TIC80LIB_DIR}/ext/md5.c 631 645 ${TIC80LIB_DIR}/ext/gif.c 632 - ${TIC80LIB_DIR}/fs.c 646 + ${TIC80LIB_DIR}/ext/history.c 647 + ${TIC80LIB_DIR}/ext/net.c 633 648 ${TIC80LIB_DIR}/tools.c 634 - ${TIC80LIB_DIR}/start.c 635 - ${TIC80LIB_DIR}/sprite.c 636 - ${TIC80LIB_DIR}/map.c 637 - ${TIC80LIB_DIR}/sfx.c 638 - ${TIC80LIB_DIR}/music.c 639 - ${TIC80LIB_DIR}/history.c 640 - ${TIC80LIB_DIR}/world.c 641 - ${TIC80LIB_DIR}/config.c 642 - ${TIC80LIB_DIR}/code.c 643 - ${TIC80LIB_DIR}/dialog.c 644 - ${TIC80LIB_DIR}/menu.c 645 - ${TIC80LIB_DIR}/surf.c 646 - ${TIC80LIB_DIR}/net.c 647 - ${TIC80LIB_DIR}/project.c 648 649 ) 649 650 650 651 set(TIC80_OUTPUT tic80)
+1 -1
build/tools/cart2prj.c
··· 22 22 23 23 #include <stdio.h> 24 24 #include <stdlib.h> 25 - #include "project.h" 25 + #include "studio/project.h" 26 26 27 27 int main(int argc, char** argv) 28 28 {
+1 -1
build/tools/prj2cart.c
··· 22 22 23 23 #include <stdio.h> 24 24 #include <stdlib.h> 25 - #include "project.h" 25 + #include "studio/project.h" 26 26 27 27 int main(int argc, char** argv) 28 28 {
+1 -1
src/cart.c src/core/cart.c
··· 20 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 21 // SOFTWARE. 22 22 23 - #include "cart.h" 23 + #include "core/cart.h" 24 24 #include "tools.h" 25 25 #include <string.h> 26 26 #include <stdlib.h>
src/cart.h src/core/cart.h
+1 -1
src/code.c src/studio/code.c
··· 21 21 // SOFTWARE. 22 22 23 23 #include "code.h" 24 - #include "history.h" 24 + #include "ext/history.h" 25 25 26 26 #include <ctype.h> 27 27
src/code.h src/studio/code.h
+1 -1
src/config.c src/studio/config.c
··· 22 22 23 23 #include "config.h" 24 24 #include "fs.h" 25 - #include "cart.h" 25 + #include "core/cart.h" 26 26 27 27 #include <lua.h> 28 28 #include <lauxlib.h>
src/config.h src/studio/config.h
+1 -1
src/console.c src/studio/console.c
··· 25 25 #include "config.h" 26 26 #include "ext/gif.h" 27 27 #include "ext/file_dialog.h" 28 - #include "project.h" 28 + #include "studio/project.h" 29 29 30 30 #include <ctype.h> 31 31 #include <string.h>
src/console.h src/studio/console.h
src/dialog.c src/studio/dialog.c
src/dialog.h src/studio/dialog.h
src/font.inl src/core/font.inl
src/fs.c src/studio/fs.c
src/fs.h src/studio/fs.h
src/history.c src/ext/history.c
src/history.h src/ext/history.h
+1 -1
src/jsapi.c src/api/js.c
··· 20 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 21 // SOFTWARE. 22 22 23 - #include "machine.h" 23 + #include "core/machine.h" 24 24 25 25 #if defined(TIC_BUILD_WITH_JS) 26 26
+1 -1
src/luaapi.c src/api/lua.c
··· 20 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 21 // SOFTWARE. 22 22 23 - #include "machine.h" 23 + #include "core/machine.h" 24 24 25 25 #if defined(TIC_BUILD_WITH_LUA) 26 26
+1 -1
src/machine.h src/core/machine.h
··· 22 22 23 23 #pragma once 24 24 25 - #include "ticapi.h" 25 + #include "api.h" 26 26 #include "tools.h" 27 27 #include "blip_buf.h" 28 28
+1 -1
src/map.c src/studio/map.c
··· 21 21 // SOFTWARE. 22 22 23 23 #include "map.h" 24 - #include "history.h" 24 + #include "ext/history.h" 25 25 26 26 #define SHEET_COLS (TIC_SPRITESHEET_SIZE / TIC_SPRITESIZE) 27 27
src/map.h src/studio/map.h
src/menu.c src/studio/menu.c
src/menu.h src/studio/menu.h
+1 -1
src/music.c src/studio/music.c
··· 21 21 // SOFTWARE. 22 22 23 23 #include "music.h" 24 - #include "history.h" 24 + #include "ext/history.h" 25 25 26 26 #include <ctype.h> 27 27
src/music.h src/studio/music.h
src/net.c src/ext/net.c
src/net.h src/ext/net.h
src/project.c src/studio/project.c
+1 -1
src/project.h src/studio/project.h
··· 22 22 23 23 #pragma once 24 24 25 - #include "cart.h" 25 + #include "core/cart.h" 26 26 27 27 #define PROJECT_LUA_EXT ".lua" 28 28 #define PROJECT_MOON_EXT ".moon"
src/run.c src/studio/run.c
src/run.h src/studio/run.h
+1 -1
src/sfx.c src/studio/sfx.c
··· 21 21 // SOFTWARE. 22 22 23 23 #include "sfx.h" 24 - #include "history.h" 24 + #include "ext/history.h" 25 25 26 26 #define DEFAULT_CHANNEL 0 27 27
src/sfx.h src/studio/sfx.h
+1 -1
src/sprite.c src/studio/sprite.c
··· 21 21 // SOFTWARE. 22 22 23 23 #include "sprite.h" 24 - #include "history.h" 24 + #include "ext/history.h" 25 25 26 26 #define CANVAS_SIZE (64) 27 27 #define PALETTE_CELL_SIZE 8
+1 -1
src/sprite.h src/studio/sprite.h
··· 23 23 #pragma once 24 24 25 25 #include "studio.h" 26 - #include "tilesheet.h" 26 + #include "core/tilesheet.h" 27 27 28 28 typedef struct Sprite Sprite; 29 29
+1677 -1677
src/squirrelapi.c src/api/squirrel.c
··· 1 - // MIT License 2 - 3 - // Copyright (c) 2017 Vadim Grigoruk @nesbox // grigoruk@gmail.com 4 - 5 - // Permission is hereby granted, free of charge, to any person obtaining a copy 6 - // of this software and associated documentation files (the "Software"), to deal 7 - // in the Software without restriction, including without limitation the rights 8 - // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 - // copies of the Software, and to permit persons to whom the Software is 10 - // furnished to do so, subject to the following conditions: 11 - 12 - // The above copyright notice and this permission notice shall be included in all 13 - // copies or substantial portions of the Software. 14 - 15 - // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 - // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 - // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 - // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 - // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 - // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 - // SOFTWARE. 22 - 23 - #include "machine.h" 24 - 25 - #if defined(TIC_BUILD_WITH_SQUIRREL) 26 - 27 - //#define USE_FOREIGN_POINTER 28 - //#define CHECK_FORCE_EXIT 29 - 30 - #include <stdlib.h> 31 - #include <stdio.h> 32 - #include <string.h> 33 - #include <squirrel.h> 34 - #include <sqstdmath.h> 35 - #include <sqstdstring.h> 36 - #include <sqstdblob.h> 37 - #include <ctype.h> 38 - 39 - static const char TicMachine[] = "_TIC80"; 40 - 41 - 42 - // !TODO: get rid of this wrap 43 - static s32 getSquirrelNumber(HSQUIRRELVM vm, s32 index) 44 - { 45 - SQInteger i; 46 - if (SQ_SUCCEEDED(sq_getinteger(vm, index, &i))) 47 - return (s32)i; 48 - 49 - SQFloat f; 50 - if (SQ_SUCCEEDED(sq_getfloat(vm, index, &f))) 51 - return (s32)f; 52 - 53 - return 0; 54 - } 55 - 56 - static void registerSquirrelFunction(tic_machine* machine, SQFUNCTION func, const char *name) 57 - { 58 - sq_pushroottable(machine->squirrel); 59 - sq_pushstring(machine->squirrel, name, -1); 60 - sq_newclosure(machine->squirrel, func, 0); 61 - sq_newslot(machine->squirrel, -3, SQTrue); 62 - sq_poptop(machine->squirrel); // remove root table. 63 - } 64 - 65 - static tic_machine* getSquirrelMachine(HSQUIRRELVM vm) 66 - { 67 - #if USE_FOREIGN_POINTER 68 - return (tic_machine*)sq_getforeignpointer(vm); 69 - #else 70 - sq_pushregistrytable(vm); 71 - sq_pushstring(vm, TicMachine, -1); 72 - if (SQ_FAILED(sq_get(vm, -2))) 73 - { 74 - fprintf(stderr, "FATAL ERROR: TicMachine not found!\n"); 75 - abort(); 76 - } 77 - SQUserPointer ptr; 78 - if (SQ_FAILED(sq_getuserpointer(vm, -1, &ptr))) 79 - { 80 - fprintf(stderr, "FATAL ERROR: Cannot get user pointer for TicMachine!\n"); 81 - abort(); 82 - } 83 - tic_machine* machine = (tic_machine*)ptr; 84 - sq_pop(vm, 2); // user pointer and registry table. 85 - return machine; 86 - #endif 87 - } 88 - 89 - void squirrel_compilerError(HSQUIRRELVM vm, const SQChar* desc, const SQChar* source, 90 - SQInteger line, SQInteger column) 91 - { 92 - tic_machine* machine = getSquirrelMachine(vm); 93 - char buffer[1024]; 94 - snprintf(buffer, 1023, "%.40s line %.6d column %.6d: %s\n", source, (int)line, (int)column, desc); 95 - 96 - if (machine->data) 97 - machine->data->error(machine->data->data, buffer); 98 - } 99 - 100 - static SQInteger squirrel_errorHandler(HSQUIRRELVM vm) 101 - { 102 - tic_machine* machine = getSquirrelMachine(vm); 103 - 104 - SQStackInfos si; 105 - SQInteger level = 0; 106 - while (SQ_SUCCEEDED(sq_stackinfos(vm, level, &si))) 107 - { 108 - char buffer[100]; 109 - snprintf(buffer, 99, "%.40s %.40s %.6d\n", si.funcname, si.source, (int)si.line); 110 - 111 - if (machine->data) 112 - machine->data->error(machine->data->data, buffer); 113 - ++level; 114 - } 115 - 116 - return 0; 117 - } 118 - 119 - 120 - static SQInteger squirrel_peek(HSQUIRRELVM vm) 121 - { 122 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 123 - 124 - // check number of args 125 - if (sq_gettop(vm) != 2) 126 - return sq_throwerror(vm, "invalid parameters, peek(address)"); 127 - s32 address = getSquirrelNumber(vm, 2); 128 - 129 - sq_pushinteger(vm, tic_api_peek(tic, address)); 130 - return 1; 131 - } 132 - 133 - static SQInteger squirrel_poke(HSQUIRRELVM vm) 134 - { 135 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 136 - 137 - if (sq_gettop(vm) != 3) 138 - return sq_throwerror( vm, "invalid parameters, poke(address,value)" ); 139 - 140 - s32 address = getSquirrelNumber(vm, 2); 141 - u8 value = getSquirrelNumber(vm, 3); 142 - 143 - tic_api_poke(tic, address, value); 144 - 145 - return 0; 146 - } 147 - 148 - static SQInteger squirrel_peek4(HSQUIRRELVM vm) 149 - { 150 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 151 - 152 - // check number of args 153 - if (sq_gettop(vm) != 2) 154 - return sq_throwerror(vm, "invalid parameters, peek4(address)"); 155 - s32 address = getSquirrelNumber(vm, 2); 156 - 157 - sq_pushinteger(vm, tic_api_peek4(tic, address)); 158 - return 1; 159 - } 160 - 161 - static SQInteger squirrel_poke4(HSQUIRRELVM vm) 162 - { 163 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 164 - 165 - if (sq_gettop(vm) != 3) 166 - return sq_throwerror( vm, "invalid parameters, poke4(address,value)" ); 167 - 168 - s32 address = getSquirrelNumber(vm, 2); 169 - u8 value = getSquirrelNumber(vm, 3); 170 - 171 - tic_api_poke4(tic, address, value); 172 - 173 - return 0; 174 - } 175 - 176 - static SQInteger squirrel_cls(HSQUIRRELVM vm) 177 - { 178 - SQInteger top = sq_gettop(vm); 179 - 180 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 181 - 182 - tic_api_cls(tic, top == 2 ? getSquirrelNumber(vm, 2) : 0); 183 - 184 - return 0; 185 - } 186 - 187 - static SQInteger squirrel_pix(HSQUIRRELVM vm) 188 - { 189 - SQInteger top = sq_gettop(vm); 190 - 191 - if(top >= 3) 192 - { 193 - s32 x = getSquirrelNumber(vm, 2); 194 - s32 y = getSquirrelNumber(vm, 3); 195 - 196 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 197 - 198 - if(top >= 4) 199 - { 200 - s32 color = getSquirrelNumber(vm, 4); 201 - tic_api_pix(tic, x, y, color, false); 202 - } 203 - else 204 - { 205 - sq_pushinteger(vm, tic_api_pix(tic, x, y, 0, true)); 206 - return 1; 207 - } 208 - 209 - } 210 - else return sq_throwerror(vm, "invalid parameters, pix(x y [color])\n"); 211 - 212 - return 0; 213 - } 214 - 215 - 216 - 217 - static SQInteger squirrel_line(HSQUIRRELVM vm) 218 - { 219 - SQInteger top = sq_gettop(vm); 220 - 221 - if(top == 6) 222 - { 223 - s32 x0 = getSquirrelNumber(vm, 2); 224 - s32 y0 = getSquirrelNumber(vm, 3); 225 - s32 x1 = getSquirrelNumber(vm, 4); 226 - s32 y1 = getSquirrelNumber(vm, 5); 227 - s32 color = getSquirrelNumber(vm, 6); 228 - 229 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 230 - 231 - tic_api_line(tic, x0, y0, x1, y1, color); 232 - } 233 - else return sq_throwerror(vm, "invalid parameters, line(x0,y0,x1,y1,color)\n"); 234 - 235 - return 0; 236 - } 237 - 238 - static SQInteger squirrel_rect(HSQUIRRELVM vm) 239 - { 240 - SQInteger top = sq_gettop(vm); 241 - 242 - if(top == 6) 243 - { 244 - s32 x = getSquirrelNumber(vm, 2); 245 - s32 y = getSquirrelNumber(vm, 3); 246 - s32 w = getSquirrelNumber(vm, 4); 247 - s32 h = getSquirrelNumber(vm, 5); 248 - s32 color = getSquirrelNumber(vm, 6); 249 - 250 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 251 - 252 - tic_api_rect(tic, x, y, w, h, color); 253 - } 254 - else return sq_throwerror(vm, "invalid parameters, rect(x,y,w,h,color)\n"); 255 - 256 - return 0; 257 - } 258 - 259 - static SQInteger squirrel_rectb(HSQUIRRELVM vm) 260 - { 261 - SQInteger top = sq_gettop(vm); 262 - 263 - if(top == 6) 264 - { 265 - s32 x = getSquirrelNumber(vm, 2); 266 - s32 y = getSquirrelNumber(vm, 3); 267 - s32 w = getSquirrelNumber(vm, 4); 268 - s32 h = getSquirrelNumber(vm, 5); 269 - s32 color = getSquirrelNumber(vm, 6); 270 - 271 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 272 - 273 - tic_api_rectb(tic, x, y, w, h, color); 274 - } 275 - else return sq_throwerror(vm, "invalid parameters, rectb(x,y,w,h,color)\n"); 276 - 277 - return 0; 278 - } 279 - 280 - static SQInteger squirrel_circ(HSQUIRRELVM vm) 281 - { 282 - SQInteger top = sq_gettop(vm); 283 - 284 - if(top == 5) 285 - { 286 - s32 radius = getSquirrelNumber(vm, 4); 287 - if(radius < 0) return 0; 288 - 289 - s32 x = getSquirrelNumber(vm, 2); 290 - s32 y = getSquirrelNumber(vm, 3); 291 - s32 color = getSquirrelNumber(vm, 5); 292 - 293 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 294 - 295 - tic_api_circ(tic, x, y, radius, color); 296 - } 297 - else return sq_throwerror(vm, "invalid parameters, circ(x,y,radius,color)\n"); 298 - 299 - return 0; 300 - } 301 - 302 - static SQInteger squirrel_circb(HSQUIRRELVM vm) 303 - { 304 - SQInteger top = sq_gettop(vm); 305 - 306 - if(top == 5) 307 - { 308 - s32 radius = getSquirrelNumber(vm, 4); 309 - if(radius < 0) return 0; 310 - 311 - s32 x = getSquirrelNumber(vm, 2); 312 - s32 y = getSquirrelNumber(vm, 3); 313 - s32 color = getSquirrelNumber(vm, 5); 314 - 315 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 316 - 317 - tic_api_circb(tic, x, y, radius, color); 318 - } 319 - else return sq_throwerror(vm, "invalid parameters, circb(x,y,radius,color)\n"); 320 - 321 - return 0; 322 - } 323 - 324 - static SQInteger squirrel_tri(HSQUIRRELVM vm) 325 - { 326 - SQInteger top = sq_gettop(vm); 327 - 328 - if(top == 8) 329 - { 330 - s32 pt[6]; 331 - 332 - for(s32 i = 0; i < COUNT_OF(pt); i++) 333 - pt[i] = getSquirrelNumber(vm, i+2); 334 - 335 - s32 color = getSquirrelNumber(vm, 8); 336 - 337 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 338 - 339 - tic_api_tri(tic, pt[0], pt[1], pt[2], pt[3], pt[4], pt[5], color); 340 - } 341 - else return sq_throwerror(vm, "invalid parameters, tri(x1,y1,x2,y2,x3,y3,color)\n"); 342 - 343 - return 0; 344 - } 345 - 346 - static SQInteger squirrel_textri(HSQUIRRELVM vm) 347 - { 348 - SQInteger top = sq_gettop(vm); 349 - 350 - if (top >= 13) 351 - { 352 - float pt[12]; 353 - 354 - for (s32 i = 0; i < COUNT_OF(pt); i++) 355 - { 356 - SQFloat f = 0.0; 357 - sq_getfloat(vm, i + 2, &f); 358 - pt[i] = (float)f; 359 - } 360 - 361 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 362 - static u8 colors[TIC_PALETTE_SIZE]; 363 - s32 count = 0; 364 - bool use_map = false; 365 - 366 - // check for use map 367 - if (top >= 14) 368 - { 369 - SQBool b = SQFalse; 370 - sq_getbool(vm, 14, &b); 371 - use_map = (b != SQFalse); 372 - } 373 - // check for chroma 374 - if(OT_ARRAY == sq_gettype(vm, 15)) 375 - { 376 - for(s32 i = 0; i < TIC_PALETTE_SIZE; i++) 377 - { 378 - sq_pushinteger(vm, (SQInteger)i); 379 - sq_rawget(vm, 15); 380 - if(sq_gettype(vm, -1) & (OT_FLOAT|OT_INTEGER)) 381 - { 382 - colors[i-1] = getSquirrelNumber(vm, -1); 383 - count++; 384 - sq_poptop(vm); 385 - } 386 - else 387 - { 388 - sq_poptop(vm); 389 - break; 390 - } 391 - } 392 - } 393 - else 394 - { 395 - colors[0] = getSquirrelNumber(vm, 15); 396 - count = 1; 397 - } 398 - 399 - tic_api_textri(tic, pt[0], pt[1], // xy 1 400 - pt[2], pt[3], // xy 2 401 - pt[4], pt[5], // xy 3 402 - pt[6], pt[7], // uv 1 403 - pt[8], pt[9], // uv 2 404 - pt[10], pt[11], // uv 3 405 - use_map, // use map 406 - colors, count); // chroma 407 - } 408 - else return sq_throwerror(vm, "invalid parameters, textri(x1,y1,x2,y2,x3,y3,u1,v1,u2,v2,u3,v3,[use_map=false],[chroma=off])\n"); 409 - return 0; 410 - } 411 - 412 - 413 - static SQInteger squirrel_clip(HSQUIRRELVM vm) 414 - { 415 - SQInteger top = sq_gettop(vm); 416 - 417 - if(top == 1) 418 - { 419 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 420 - 421 - tic_api_clip(tic, 0, 0, TIC80_WIDTH, TIC80_HEIGHT); 422 - } 423 - else if(top == 5) 424 - { 425 - s32 x = getSquirrelNumber(vm, 2); 426 - s32 y = getSquirrelNumber(vm, 3); 427 - s32 w = getSquirrelNumber(vm, 4); 428 - s32 h = getSquirrelNumber(vm, 5); 429 - 430 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 431 - 432 - tic_api_clip((tic_mem*)getSquirrelMachine(vm), x, y, w, h); 433 - } 434 - else return sq_throwerror(vm, "invalid parameters, use clip(x,y,w,h) or clip()\n"); 435 - 436 - return 0; 437 - } 438 - 439 - static SQInteger squirrel_btnp(HSQUIRRELVM vm) 440 - { 441 - tic_machine* machine = getSquirrelMachine(vm); 442 - tic_mem* tic = (tic_mem*)machine; 443 - 444 - SQInteger top = sq_gettop(vm); 445 - 446 - if (top == 1) 447 - { 448 - sq_pushinteger(vm, tic_api_btnp(tic, -1, -1, -1)); 449 - } 450 - else if(top == 2) 451 - { 452 - s32 index = getSquirrelNumber(vm, 2) & 0x1f; 453 - 454 - sq_pushbool(vm, (tic_api_btnp(tic, index, -1, -1) ? SQTrue : SQFalse)); 455 - } 456 - else if (top == 4) 457 - { 458 - s32 index = getSquirrelNumber(vm, 2) & 0x1f; 459 - u32 hold = getSquirrelNumber(vm, 3); 460 - u32 period = getSquirrelNumber(vm, 4); 461 - 462 - sq_pushbool(vm, (tic_api_btnp(tic, index, hold, period) ? SQTrue : SQFalse)); 463 - } 464 - else 465 - { 466 - return sq_throwerror(vm, "invalid params, btnp [ id [ hold period ] ]\n"); 467 - } 468 - 469 - return 1; 470 - } 471 - 472 - static SQInteger squirrel_btn(HSQUIRRELVM vm) 473 - { 474 - tic_machine* machine = getSquirrelMachine(vm); 475 - 476 - SQInteger top = sq_gettop(vm); 477 - 478 - if (top == 1) 479 - { 480 - sq_pushinteger(vm, machine->memory.ram.input.gamepads.data); 481 - } 482 - else if (top == 2) 483 - { 484 - u32 index = getSquirrelNumber(vm, 2) & 0x1f; 485 - bool pressed = (machine->memory.ram.input.gamepads.data & (1 << index)) != 0; 486 - sq_pushbool(vm, pressed ? SQTrue : SQFalse); 487 - } 488 - else 489 - { 490 - return sq_throwerror(vm, "invalid params, btn [ id ]\n"); 491 - } 492 - 493 - return 1; 494 - } 495 - 496 - static SQInteger squirrel_spr(HSQUIRRELVM vm) 497 - { 498 - SQInteger top = sq_gettop(vm); 499 - 500 - s32 index = 0; 501 - s32 x = 0; 502 - s32 y = 0; 503 - s32 w = 1; 504 - s32 h = 1; 505 - s32 scale = 1; 506 - tic_flip flip = tic_no_flip; 507 - tic_rotate rotate = tic_no_rotate; 508 - static u8 colors[TIC_PALETTE_SIZE]; 509 - s32 count = 0; 510 - 511 - if(top >= 2) 512 - { 513 - index = getSquirrelNumber(vm, 2); 514 - 515 - if(top >= 4) 516 - { 517 - x = getSquirrelNumber(vm, 3); 518 - y = getSquirrelNumber(vm, 4); 519 - 520 - if(top >= 5) 521 - { 522 - if(OT_ARRAY == sq_gettype(vm, 5)) 523 - { 524 - for(s32 i = 0; i < TIC_PALETTE_SIZE; i++) 525 - { 526 - sq_pushinteger(vm, (SQInteger)i); 527 - sq_rawget(vm, 5); 528 - if(sq_gettype(vm, -1) & (OT_FLOAT|OT_INTEGER)) 529 - { 530 - colors[i-1] = getSquirrelNumber(vm, -1); 531 - count++; 532 - sq_poptop(vm); 533 - } 534 - else 535 - { 536 - sq_poptop(vm); 537 - break; 538 - } 539 - } 540 - } 541 - else 542 - { 543 - colors[0] = getSquirrelNumber(vm, 5); 544 - count = 1; 545 - } 546 - 547 - if(top >= 6) 548 - { 549 - scale = getSquirrelNumber(vm, 6); 550 - 551 - if(top >= 7) 552 - { 553 - flip = getSquirrelNumber(vm, 7); 554 - 555 - if(top >= 8) 556 - { 557 - rotate = getSquirrelNumber(vm, 8); 558 - 559 - if(top >= 10) 560 - { 561 - w = getSquirrelNumber(vm, 9); 562 - h = getSquirrelNumber(vm, 10); 563 - } 564 - } 565 - } 566 - } 567 - } 568 - } 569 - } 570 - 571 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 572 - 573 - tic_api_spr(tic, index, x, y, w, h, colors, count, scale, flip, rotate); 574 - 575 - return 0; 576 - } 577 - 578 - static SQInteger squirrel_mget(HSQUIRRELVM vm) 579 - { 580 - SQInteger top = sq_gettop(vm); 581 - 582 - if(top == 3) 583 - { 584 - s32 x = getSquirrelNumber(vm, 2); 585 - s32 y = getSquirrelNumber(vm, 3); 586 - 587 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 588 - 589 - u8 value = tic_api_mget(tic, x, y); 590 - sq_pushinteger(vm, value); 591 - return 1; 592 - } 593 - else return sq_throwerror(vm, "invalid params, mget(x,y)\n"); 594 - 595 - return 0; 596 - } 597 - 598 - static SQInteger squirrel_mset(HSQUIRRELVM vm) 599 - { 600 - SQInteger top = sq_gettop(vm); 601 - 602 - if(top == 4) 603 - { 604 - s32 x = getSquirrelNumber(vm, 2); 605 - s32 y = getSquirrelNumber(vm, 3); 606 - u8 val = getSquirrelNumber(vm, 4); 607 - 608 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 609 - 610 - tic_api_mset(tic, x, y, val); 611 - } 612 - else return sq_throwerror(vm, "invalid params, mget(x,y)\n"); 613 - 614 - return 0; 615 - } 616 - 617 - typedef struct 618 - { 619 - HSQUIRRELVM vm; 620 - HSQOBJECT reg; 621 - } RemapData; 622 - 623 - static void remapCallback(void* data, s32 x, s32 y, RemapResult* result) 624 - { 625 - RemapData* remap = (RemapData*)data; 626 - HSQUIRRELVM vm = remap->vm; 627 - 628 - SQInteger top = sq_gettop(vm); 629 - 630 - sq_pushobject(vm, remap->reg); 631 - sq_pushroottable(vm); 632 - sq_pushinteger(vm, result->index); 633 - sq_pushinteger(vm, x); 634 - sq_pushinteger(vm, y); 635 - //lua_pcall(lua, 3, 3, 0); 636 - 637 - if (SQ_SUCCEEDED(sq_call(vm, 4, SQTrue, SQTrue))) 638 - { 639 - sq_pushinteger(vm, 0); 640 - if (SQ_SUCCEEDED(sq_get(vm, -2))) 641 - { 642 - result->index = getSquirrelNumber(vm, -1); 643 - sq_poptop(vm); 644 - sq_pushinteger(vm, 1); 645 - if (SQ_SUCCEEDED(sq_get(vm, -2))) 646 - { 647 - result->flip = getSquirrelNumber(vm, -1); 648 - sq_poptop(vm); 649 - sq_pushinteger(vm, 2); 650 - if (SQ_SUCCEEDED(sq_get(vm, -2))) 651 - { 652 - result->rotate = getSquirrelNumber(vm, -1); 653 - sq_poptop(vm); 654 - } 655 - } 656 - } 657 - } 658 - 659 - sq_settop(vm, top); 660 - } 661 - 662 - static SQInteger squirrel_map(HSQUIRRELVM vm) 663 - { 664 - s32 x = 0; 665 - s32 y = 0; 666 - s32 w = TIC_MAP_SCREEN_WIDTH; 667 - s32 h = TIC_MAP_SCREEN_HEIGHT; 668 - s32 sx = 0; 669 - s32 sy = 0; 670 - s32 scale = 1; 671 - static u8 colors[TIC_PALETTE_SIZE]; 672 - s32 count = 0; 673 - 674 - SQInteger top = sq_gettop(vm); 675 - 676 - if(top >= 3) 677 - { 678 - x = getSquirrelNumber(vm, 2); 679 - y = getSquirrelNumber(vm, 3); 680 - 681 - if(top >= 5) 682 - { 683 - w = getSquirrelNumber(vm, 4); 684 - h = getSquirrelNumber(vm, 5); 685 - 686 - if(top >= 7) 687 - { 688 - sx = getSquirrelNumber(vm, 6); 689 - sy = getSquirrelNumber(vm, 7); 690 - 691 - if(top >= 8) 692 - { 693 - if(OT_ARRAY == sq_gettype(vm, 8)) 694 - { 695 - for(s32 i = 0; i < TIC_PALETTE_SIZE; i++) 696 - { 697 - sq_pushinteger(vm, (SQInteger)i); 698 - sq_rawget(vm, 8); 699 - if(sq_gettype(vm, -1) & (OT_FLOAT|OT_INTEGER)) 700 - { 701 - colors[i-1] = getSquirrelNumber(vm, -1); 702 - count++; 703 - sq_poptop(vm); 704 - } 705 - else 706 - { 707 - sq_poptop(vm); 708 - break; 709 - } 710 - } 711 - } 712 - else 713 - { 714 - colors[0] = getSquirrelNumber(vm, 8); 715 - count = 1; 716 - } 717 - 718 - if(top >= 9) 719 - { 720 - scale = getSquirrelNumber(vm, 9); 721 - 722 - if(top >= 10) 723 - { 724 - SQObjectType type = sq_gettype(vm, 10); 725 - if (type & (OT_CLOSURE|OT_NATIVECLOSURE|OT_INSTANCE)) 726 - { 727 - RemapData data = {vm}; 728 - sq_resetobject(&data.reg); 729 - sq_getstackobj(vm, 10, &data.reg); 730 - sq_addref(vm, &data.reg); 731 - 732 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 733 - 734 - tic_api_map(tic, x, y, w, h, sx, sy, colors, count, scale, remapCallback, &data); 735 - 736 - //luaL_unref(lua, LUA_REGISTRYINDEX, data.reg); 737 - sq_release(vm, &data.reg); 738 - 739 - return 0; 740 - } 741 - } 742 - } 743 - } 744 - } 745 - } 746 - } 747 - 748 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 749 - 750 - tic_api_map((tic_mem*)getSquirrelMachine(vm), x, y, w, h, sx, sy, colors, count, scale, NULL, NULL); 751 - 752 - return 0; 753 - } 754 - 755 - static SQInteger squirrel_music(HSQUIRRELVM vm) 756 - { 757 - SQInteger top = sq_gettop(vm); 758 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 759 - 760 - if(top == 1) tic_api_music(tic, -1, 0, 0, false, false); 761 - else if(top >= 2) 762 - { 763 - tic_api_music(tic, -1, 0, 0, false, false); 764 - 765 - s32 track = getSquirrelNumber(vm, 2); 766 - s32 frame = -1; 767 - s32 row = -1; 768 - bool loop = true; 769 - bool sustain = false; 770 - 771 - if(top >= 3) 772 - { 773 - frame = getSquirrelNumber(vm, 3); 774 - 775 - if(top >= 4) 776 - { 777 - row = getSquirrelNumber(vm, 4); 778 - 779 - if(top >= 5) 780 - { 781 - SQBool b = SQFalse; 782 - sq_getbool(vm, 5, &b); 783 - loop = (b != SQFalse); 784 - if(top >= 6) 785 - { 786 - SQBool b = SQFalse; 787 - sq_getbool(vm, 6, &b); 788 - sustain = (b != SQFalse); 789 - } 790 - } 791 - } 792 - } 793 - 794 - tic_api_music(tic, track, frame, row, loop, sustain); 795 - } 796 - else return sq_throwerror(vm, "invalid params, use music(track)\n"); 797 - 798 - return 0; 799 - } 800 - 801 - static SQInteger squirrel_sfx(HSQUIRRELVM vm) 802 - { 803 - SQInteger top = sq_gettop(vm); 804 - 805 - if(top >= 2) 806 - { 807 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 808 - 809 - s32 note = -1; 810 - s32 octave = -1; 811 - s32 duration = -1; 812 - s32 channel = 0; 813 - s32 volume = MAX_VOLUME; 814 - s32 speed = SFX_DEF_SPEED; 815 - 816 - s32 index = getSquirrelNumber(vm, 2); 817 - 818 - if(index < SFX_COUNT) 819 - { 820 - if (index >= 0) 821 - { 822 - tic_sample* effect = tic->ram.sfx.samples.data + index; 823 - 824 - note = effect->note; 825 - octave = effect->octave; 826 - speed = effect->speed; 827 - } 828 - 829 - if(top >= 3) 830 - { 831 - if(sq_gettype(vm, 3) & (OT_INTEGER|OT_FLOAT)) 832 - { 833 - s32 id = getSquirrelNumber(vm, 3); 834 - note = id % NOTES; 835 - octave = id / NOTES; 836 - } 837 - else if(sq_gettype(vm, 3) == OT_STRING) 838 - { 839 - const SQChar* str; 840 - sq_getstring(vm, 3, &str); 841 - const char* noteStr = (const char*)str; 842 - 843 - if(!tic_tool_parse_note(noteStr, &note, &octave)) 844 - { 845 - return sq_throwerror(vm, "invalid note, should be like C#4\n"); 846 - } 847 - } 848 - 849 - if(top >= 4) 850 - { 851 - duration = getSquirrelNumber(vm, 4); 852 - 853 - if(top >= 5) 854 - { 855 - channel = getSquirrelNumber(vm, 5); 856 - 857 - if(top >= 6) 858 - { 859 - volume = getSquirrelNumber(vm, 6); 860 - 861 - if(top >= 7) 862 - { 863 - speed = getSquirrelNumber(vm, 7); 864 - } 865 - } 866 - } 867 - } 868 - } 869 - 870 - if (channel >= 0 && channel < TIC_SOUND_CHANNELS) 871 - { 872 - tic_api_sfx(tic, index, note, octave, duration, channel, volume & 0xf, speed); 873 - } 874 - else return sq_throwerror(vm, "unknown channel\n"); 875 - } 876 - else return sq_throwerror(vm, "unknown sfx index\n"); 877 - } 878 - else return sq_throwerror(vm, "invalid sfx params\n"); 879 - 880 - return 0; 881 - } 882 - 883 - static SQInteger squirrel_sync(HSQUIRRELVM vm) 884 - { 885 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 886 - 887 - bool toCart = false; 888 - u32 mask = 0; 889 - s32 bank = 0; 890 - 891 - if(sq_gettop(vm) >= 2) 892 - { 893 - mask = getSquirrelNumber(vm, 2); 894 - 895 - if(sq_gettop(vm) >= 3) 896 - { 897 - bank = getSquirrelNumber(vm, 3); 898 - 899 - if(sq_gettop(vm) >= 4) 900 - { 901 - SQBool b = SQFalse; 902 - sq_getbool(vm, 4, &b); 903 - toCart = (b != SQFalse); 904 - } 905 - } 906 - } 907 - 908 - if(bank >= 0 && bank < TIC_BANKS) 909 - tic_api_sync(tic, mask, bank, toCart); 910 - else 911 - return sq_throwerror(vm, "sync() error, invalid bank"); 912 - 913 - return 0; 914 - } 915 - 916 - static SQInteger squirrel_reset(HSQUIRRELVM vm) 917 - { 918 - tic_machine* machine = getSquirrelMachine(vm); 919 - 920 - machine->state.initialized = false; 921 - 922 - return 0; 923 - } 924 - 925 - static SQInteger squirrel_key(HSQUIRRELVM vm) 926 - { 927 - tic_machine* machine = getSquirrelMachine(vm); 928 - tic_mem* tic = &machine->memory; 929 - 930 - SQInteger top = sq_gettop(vm); 931 - 932 - if (top == 1) 933 - { 934 - sq_pushbool(vm, tic_api_key(tic, tic_key_unknown) ? SQTrue : SQFalse); 935 - } 936 - else if (top == 2) 937 - { 938 - tic_key key = getSquirrelNumber(vm, 2); 939 - 940 - if(key < tic_key_escape) 941 - sq_pushbool(vm, tic_api_key(tic, key) ? SQTrue : SQFalse); 942 - else 943 - { 944 - return sq_throwerror(vm, "unknown keyboard code\n"); 945 - } 946 - } 947 - else 948 - { 949 - return sq_throwerror(vm, "invalid params, key [code]\n"); 950 - } 951 - 952 - return 1; 953 - } 954 - 955 - static SQInteger squirrel_keyp(HSQUIRRELVM vm) 956 - { 957 - tic_machine* machine = getSquirrelMachine(vm); 958 - tic_mem* tic = &machine->memory; 959 - 960 - SQInteger top = sq_gettop(vm); 961 - 962 - if (top == 1) 963 - { 964 - sq_pushbool(vm, tic_api_keyp(tic, tic_key_unknown, -1, -1) ? SQTrue : SQFalse); 965 - } 966 - else 967 - { 968 - tic_key key = getSquirrelNumber(vm, 2); 969 - 970 - if(key >= tic_key_escape) 971 - { 972 - return sq_throwerror(vm, "unknown keyboard code\n"); 973 - } 974 - else 975 - { 976 - if(top == 2) 977 - { 978 - sq_pushbool(vm, tic_api_keyp(tic, key, -1, -1) ? SQTrue : SQFalse); 979 - } 980 - else if(top == 4) 981 - { 982 - u32 hold = getSquirrelNumber(vm, 3); 983 - u32 period = getSquirrelNumber(vm, 4); 984 - 985 - sq_pushbool(vm, tic_api_keyp(tic, key, hold, period) ? SQTrue : SQFalse); 986 - } 987 - else 988 - { 989 - return sq_throwerror(vm, "invalid params, keyp [ code [ hold period ] ]\n"); 990 - } 991 - } 992 - } 993 - 994 - return 1; 995 - } 996 - 997 - static SQInteger squirrel_memcpy(HSQUIRRELVM vm) 998 - { 999 - SQInteger top = sq_gettop(vm); 1000 - 1001 - if(top == 4) 1002 - { 1003 - s32 dest = getSquirrelNumber(vm, 2); 1004 - s32 src = getSquirrelNumber(vm, 3); 1005 - s32 size = getSquirrelNumber(vm, 4); 1006 - 1007 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1008 - tic_api_memcpy(tic, dest, src, size); 1009 - return 0; 1010 - } 1011 - 1012 - return sq_throwerror(vm, "invalid params, memcpy(dest,src,size)\n"); 1013 - } 1014 - 1015 - static SQInteger squirrel_memset(HSQUIRRELVM vm) 1016 - { 1017 - SQInteger top = sq_gettop(vm); 1018 - 1019 - if(top == 4) 1020 - { 1021 - s32 dest = getSquirrelNumber(vm, 2); 1022 - u8 value = getSquirrelNumber(vm, 3); 1023 - s32 size = getSquirrelNumber(vm, 4); 1024 - 1025 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1026 - tic_api_memset(tic, dest, value, size); 1027 - return 0; 1028 - } 1029 - 1030 - return sq_throwerror(vm, "invalid params, memset(dest,val,size)\n"); 1031 - } 1032 - 1033 - // NB we leave the string on the stack so that the char* pointer remains valid. 1034 - static const char* printString(HSQUIRRELVM vm, s32 index) 1035 - { 1036 - const SQChar* text = ""; 1037 - if (SQ_SUCCEEDED(sq_tostring(vm, index))) 1038 - { 1039 - sq_getstring(vm, -1, &text); 1040 - } 1041 - 1042 - return (const char*)text; 1043 - } 1044 - 1045 - static SQInteger squirrel_font(HSQUIRRELVM vm) 1046 - { 1047 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1048 - SQInteger top = sq_gettop(vm); 1049 - 1050 - if(top >= 2) 1051 - { 1052 - const char* text = printString(vm, 2); 1053 - s32 x = 0; 1054 - s32 y = 0; 1055 - s32 width = TIC_SPRITESIZE; 1056 - s32 height = TIC_SPRITESIZE; 1057 - u8 chromakey = 0; 1058 - bool fixed = false; 1059 - bool alt = false; 1060 - s32 scale = 1; 1061 - 1062 - if(top >= 4) 1063 - { 1064 - x = getSquirrelNumber(vm, 3); 1065 - y = getSquirrelNumber(vm, 4); 1066 - 1067 - if(top >= 5) 1068 - { 1069 - chromakey = getSquirrelNumber(vm, 5); 1070 - 1071 - if(top >= 7) 1072 - { 1073 - width = getSquirrelNumber(vm, 6); 1074 - height = getSquirrelNumber(vm, 7); 1075 - 1076 - if(top >= 8) 1077 - { 1078 - SQBool b = SQFalse; 1079 - sq_getbool(vm, 8, &b); 1080 - fixed = (b != SQFalse); 1081 - 1082 - if(top >= 9) 1083 - { 1084 - scale = getSquirrelNumber(vm, 9); 1085 - 1086 - if (top >= 10) 1087 - { 1088 - SQBool b = SQFalse; 1089 - sq_getbool(vm, 10, &b); 1090 - alt = (b != SQFalse); 1091 - } 1092 - 1093 - } 1094 - } 1095 - } 1096 - } 1097 - } 1098 - 1099 - if(scale == 0) 1100 - { 1101 - sq_pushinteger(vm, 0); 1102 - return 1; 1103 - } 1104 - 1105 - s32 size = tic_api_font(tic, text, x, y, chromakey, width, height, fixed, scale, alt); 1106 - 1107 - sq_pushinteger(vm, size); 1108 - return 1; 1109 - } 1110 - 1111 - return 0; 1112 - } 1113 - 1114 - static SQInteger squirrel_print(HSQUIRRELVM vm) 1115 - { 1116 - SQInteger top = sq_gettop(vm); 1117 - 1118 - if(top >= 2) 1119 - { 1120 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1121 - 1122 - s32 x = 0; 1123 - s32 y = 0; 1124 - s32 color = TIC_PALETTE_SIZE-1; 1125 - bool fixed = false; 1126 - bool alt = false; 1127 - s32 scale = 1; 1128 - 1129 - const char* text = printString(vm, 2); 1130 - 1131 - if(top >= 4) 1132 - { 1133 - x = getSquirrelNumber(vm, 3); 1134 - y = getSquirrelNumber(vm, 4); 1135 - 1136 - if(top >= 5) 1137 - { 1138 - color = getSquirrelNumber(vm, 5) % TIC_PALETTE_SIZE; 1139 - 1140 - if(top >= 6) 1141 - { 1142 - SQBool b = SQFalse; 1143 - sq_getbool(vm, 5, &b); 1144 - fixed = (b != SQFalse); 1145 - 1146 - if(top >= 7) 1147 - { 1148 - scale = getSquirrelNumber(vm, 7); 1149 - 1150 - if (top >= 8) 1151 - { 1152 - SQBool b = SQFalse; 1153 - sq_getbool(vm, 8, &b); 1154 - alt = (b != SQFalse); 1155 - } 1156 - } 1157 - } 1158 - } 1159 - } 1160 - 1161 - if(scale == 0) 1162 - { 1163 - sq_pushinteger(vm, 0); 1164 - return 1; 1165 - } 1166 - 1167 - s32 size = tic_api_print(tic, text ? text : "nil", x, y, color, fixed, scale, alt); 1168 - 1169 - sq_pushinteger(vm, size); 1170 - 1171 - return 1; 1172 - } 1173 - 1174 - return 0; 1175 - } 1176 - 1177 - static SQInteger squirrel_trace(HSQUIRRELVM vm) 1178 - { 1179 - SQInteger top = sq_gettop(vm); 1180 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1181 - 1182 - if(top >= 2) 1183 - { 1184 - const char* text = printString(vm, 2); 1185 - u8 color = tic_color_12; 1186 - 1187 - if(top >= 3) 1188 - { 1189 - color = getSquirrelNumber(vm, 3); 1190 - } 1191 - 1192 - tic_api_trace(tic, text, color); 1193 - } 1194 - 1195 - return 0; 1196 - } 1197 - 1198 - static SQInteger squirrel_pmem(HSQUIRRELVM vm) 1199 - { 1200 - SQInteger top = sq_gettop(vm); 1201 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1202 - 1203 - if(top >= 2) 1204 - { 1205 - u32 index = getSquirrelNumber(vm, 2); 1206 - 1207 - if(index < TIC_PERSISTENT_SIZE) 1208 - { 1209 - u32 val = tic_api_pmem(tic, index, 0, false); 1210 - 1211 - if(top >= 3) 1212 - { 1213 - SQInteger i = 0; 1214 - sq_getinteger(vm, 3, &i); 1215 - tic_api_pmem(tic, index, (u32)i, true); 1216 - } 1217 - 1218 - sq_pushinteger(vm, val); 1219 - 1220 - return 1; 1221 - } 1222 - return sq_throwerror(vm, "invalid persistent tic index\n"); 1223 - } 1224 - else return sq_throwerror(vm, "invalid params, pmem(index [val]) -> val\n"); 1225 - 1226 - return 0; 1227 - } 1228 - 1229 - static SQInteger squirrel_time(HSQUIRRELVM vm) 1230 - { 1231 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1232 - 1233 - sq_pushfloat(vm, (SQFloat)(tic_api_time(tic))); 1234 - 1235 - return 1; 1236 - } 1237 - 1238 - static SQInteger squirrel_tstamp(HSQUIRRELVM vm) 1239 - { 1240 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1241 - 1242 - sq_pushinteger(vm, (SQFloat)(tic_api_tstamp(tic))); 1243 - 1244 - return 1; 1245 - } 1246 - 1247 - static SQInteger squirrel_exit(HSQUIRRELVM vm) 1248 - { 1249 - tic_api_exit((tic_mem*)getSquirrelMachine(vm)); 1250 - 1251 - return 0; 1252 - } 1253 - 1254 - static SQInteger squirrel_mouse(HSQUIRRELVM vm) 1255 - { 1256 - tic_machine* machine = getSquirrelMachine(vm); 1257 - 1258 - const tic80_mouse* mouse = &machine->memory.ram.input.mouse; 1259 - 1260 - sq_newarray(vm, 7); 1261 - sq_pushinteger(vm, mouse->x); 1262 - sq_arrayappend(vm, -2); 1263 - sq_pushinteger(vm, mouse->y); 1264 - sq_arrayappend(vm, -2); 1265 - sq_pushbool(vm, mouse->left ? SQTrue : SQFalse); 1266 - sq_arrayappend(vm, -2); 1267 - sq_pushbool(vm, mouse->middle ? SQTrue : SQFalse); 1268 - sq_arrayappend(vm, -2); 1269 - sq_pushbool(vm, mouse->right ? SQTrue : SQFalse); 1270 - sq_arrayappend(vm, -2); 1271 - sq_pushinteger(vm, mouse->scrollx); 1272 - sq_arrayappend(vm, -2); 1273 - sq_pushinteger(vm, mouse->scrolly); 1274 - sq_arrayappend(vm, -2); 1275 - 1276 - return 1; 1277 - } 1278 - 1279 - static SQInteger squirrel_fget(HSQUIRRELVM vm) 1280 - { 1281 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1282 - 1283 - SQInteger top = sq_gettop(vm); 1284 - 1285 - if(top >= 2) 1286 - { 1287 - u32 index = getSquirrelNumber(vm, 2); 1288 - 1289 - if(top >= 3) 1290 - { 1291 - u32 flag = getSquirrelNumber(vm, 3); 1292 - sq_pushbool(vm, tic_api_fget(tic, index, flag)); 1293 - return 1; 1294 - } 1295 - } 1296 - 1297 - sq_throwerror(vm, "invalid params, fget(index, flag) -> val\n"); 1298 - 1299 - return 0; 1300 - } 1301 - 1302 - static SQInteger squirrel_fset(HSQUIRRELVM vm) 1303 - { 1304 - tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1305 - 1306 - SQInteger top = sq_gettop(vm); 1307 - 1308 - if(top >= 2) 1309 - { 1310 - u32 index = getSquirrelNumber(vm, 2); 1311 - 1312 - if(top >= 3) 1313 - { 1314 - u32 flag = getSquirrelNumber(vm, 3); 1315 - 1316 - if(top >= 4) 1317 - { 1318 - SQBool value = SQFalse; 1319 - sq_getbool(vm, 4, &value); 1320 - 1321 - tic_api_fset(tic, index, flag, value); 1322 - return 0; 1323 - } 1324 - } 1325 - } 1326 - 1327 - sq_throwerror(vm, "invalid params, fset(index, flag, value)\n"); 1328 - 1329 - return 0; 1330 - } 1331 - 1332 - static SQInteger squirrel_dofile(HSQUIRRELVM vm) 1333 - { 1334 - return sq_throwerror(vm, "unknown method: \"dofile\"\n"); 1335 - } 1336 - 1337 - static SQInteger squirrel_loadfile(HSQUIRRELVM vm) 1338 - { 1339 - return sq_throwerror(vm, "unknown method: \"loadfile\"\n"); 1340 - } 1341 - 1342 - static void squirrel_open_builtins(HSQUIRRELVM vm) 1343 - { 1344 - sq_pushroottable(vm); 1345 - sqstd_register_mathlib(vm); 1346 - sqstd_register_stringlib(vm); 1347 - sqstd_register_bloblib(vm); 1348 - sq_poptop(vm); 1349 - } 1350 - 1351 - static void checkForceExit(HSQUIRRELVM vm, SQInteger type, const SQChar* sourceName, SQInteger line, const SQChar* functionName) 1352 - { 1353 - tic_machine* machine = getSquirrelMachine(vm); 1354 - tic_tick_data* tick = machine->data; 1355 - 1356 - if(tick && tick->forceExit && tick->forceExit(tick->data)) 1357 - sq_throwerror(vm, "script execution was interrupted"); 1358 - } 1359 - 1360 - static void initAPI(tic_machine* machine) 1361 - { 1362 - HSQUIRRELVM vm = machine->squirrel; 1363 - 1364 - sq_setcompilererrorhandler(vm, squirrel_compilerError); 1365 - 1366 - sq_pushregistrytable(vm); 1367 - sq_pushstring(vm, TicMachine, -1); 1368 - sq_pushuserpointer(machine->squirrel, machine); 1369 - sq_newslot(vm, -3, SQTrue); 1370 - sq_poptop(vm); 1371 - 1372 - #if USE_FOREIGN_POINTER 1373 - sq_setforeignptr(vm, machine); 1374 - #endif 1375 - 1376 - #define API_FUNC_DEF(name, ...) {squirrel_ ## name, #name}, 1377 - static const struct{SQFUNCTION func; const char* name;} ApiItems[] = {TIC_API_LIST(API_FUNC_DEF)}; 1378 - #undef API_FUNC_DEF 1379 - 1380 - for (s32 i = 0; i < COUNT_OF(ApiItems); i++) 1381 - registerSquirrelFunction(machine, ApiItems[i].func, ApiItems[i].name); 1382 - 1383 - registerSquirrelFunction(machine, squirrel_dofile, "dofile"); 1384 - registerSquirrelFunction(machine, squirrel_loadfile, "loadfile"); 1385 - 1386 - #if CHECK_FORCE_EXIT 1387 - sq_setnativedebughook(vm, checkForceExit); 1388 - #endif 1389 - sq_enabledebuginfo(vm, SQTrue); 1390 - 1391 - } 1392 - 1393 - static void closeSquirrel(tic_mem* tic) 1394 - { 1395 - tic_machine* machine = (tic_machine*)tic; 1396 - 1397 - if(machine->squirrel) 1398 - { 1399 - sq_close(machine->squirrel); 1400 - machine->squirrel = NULL; 1401 - } 1402 - } 1403 - 1404 - static bool initSquirrel(tic_mem* tic, const char* code) 1405 - { 1406 - tic_machine* machine = (tic_machine*)tic; 1407 - 1408 - closeSquirrel(tic); 1409 - 1410 - HSQUIRRELVM vm = machine->squirrel = sq_open(100); 1411 - squirrel_open_builtins(vm); 1412 - 1413 - sq_newclosure(vm, squirrel_errorHandler, 0); 1414 - sq_seterrorhandler(vm); 1415 - 1416 - initAPI(machine); 1417 - 1418 - { 1419 - HSQUIRRELVM vm = machine->squirrel; 1420 - 1421 - sq_settop(vm, 0); 1422 - 1423 - if((SQ_FAILED(sq_compilebuffer(vm, code, strlen(code), "squirrel", SQTrue))) || 1424 - (sq_pushroottable(vm), false) || 1425 - (SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue)))) 1426 - { 1427 - sq_getlasterror(vm); 1428 - sq_tostring(vm, -1); 1429 - const SQChar* errorString = "unknown error"; 1430 - sq_getstring(vm, -1, &errorString); 1431 - 1432 - if (machine->data) 1433 - machine->data->error(machine->data->data, errorString); 1434 - 1435 - sq_pop(vm, 2); // error and error string 1436 - 1437 - return false; 1438 - } 1439 - } 1440 - 1441 - return true; 1442 - } 1443 - 1444 - static void callSquirrelTick(tic_mem* tic) 1445 - { 1446 - tic_machine* machine = (tic_machine*)tic; 1447 - 1448 - HSQUIRRELVM vm = machine->squirrel; 1449 - 1450 - if(vm) 1451 - { 1452 - sq_pushroottable(vm); 1453 - sq_pushstring(vm, TIC_FN, -1); 1454 - 1455 - if (SQ_SUCCEEDED(sq_get(vm, -2))) 1456 - { 1457 - sq_pushroottable(vm); 1458 - if(SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue))) 1459 - { 1460 - sq_getlasterror(vm); 1461 - sq_tostring(vm, -1); 1462 - const SQChar* errorString = "unknown error"; 1463 - sq_getstring(vm, -1, &errorString); 1464 - 1465 - if (machine->data) 1466 - machine->data->error(machine->data->data, errorString); 1467 - sq_pop(vm, 3); // remove string, error and root table. 1468 - } 1469 - } 1470 - else 1471 - { 1472 - sq_pop(vm, 1); 1473 - if (machine->data) 1474 - machine->data->error(machine->data->data, "'function TIC()...' isn't found :("); 1475 - } 1476 - } 1477 - } 1478 - 1479 - static void callSquirrelScanlineName(tic_mem* tic, s32 row, void* data, const char* name) 1480 - { 1481 - tic_machine* machine = (tic_machine*)tic; 1482 - HSQUIRRELVM vm = machine->squirrel; 1483 - 1484 - if (vm) 1485 - { 1486 - sq_pushroottable(vm); 1487 - sq_pushstring(vm, name, -1); 1488 - if (SQ_SUCCEEDED(sq_get(vm, -2))) 1489 - { 1490 - sq_pushroottable(vm); 1491 - sq_pushinteger(vm, row); 1492 - 1493 - if(SQ_FAILED(sq_call(vm, 2, SQFalse, SQTrue))) 1494 - { 1495 - sq_getlasterror(vm); 1496 - sq_tostring(vm, -1); 1497 - 1498 - const SQChar* errorString = "unknown error"; 1499 - sq_getstring(vm, -1, &errorString); 1500 - if (machine->data) 1501 - machine->data->error(machine->data->data, errorString); 1502 - sq_pop(vm, 3); // error string, error and root table 1503 - } 1504 - } 1505 - else sq_poptop(vm); 1506 - } 1507 - } 1508 - 1509 - static void callSquirrelScanline(tic_mem* tic, s32 row, void* data) 1510 - { 1511 - callSquirrelScanlineName(tic, row, data, SCN_FN); 1512 - 1513 - // try to call old scanline 1514 - callSquirrelScanlineName(tic, row, data, "scanline"); 1515 - } 1516 - 1517 - static void callSquirrelOverline(tic_mem* tic, void* data) 1518 - { 1519 - tic_machine* machine = (tic_machine*)tic; 1520 - HSQUIRRELVM vm = machine->squirrel; 1521 - 1522 - if (vm) 1523 - { 1524 - const char* OvrFunc = OVR_FN; 1525 - 1526 - sq_pushroottable(vm); 1527 - sq_pushstring(vm, OvrFunc, -1); 1528 - 1529 - if(SQ_SUCCEEDED(sq_get(vm, -2))) 1530 - { 1531 - sq_pushroottable(vm); 1532 - if(SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue))) 1533 - { 1534 - sq_getlasterror(vm); 1535 - sq_tostring(vm, -1); 1536 - const SQChar* errorString = "unknown error"; 1537 - sq_getstring(vm, -1, &errorString); 1538 - if (machine->data) 1539 - machine->data->error(machine->data->data, errorString); 1540 - sq_pop(vm, 3); 1541 - } 1542 - } 1543 - else sq_poptop(vm); 1544 - } 1545 - 1546 - } 1547 - 1548 - static const char* const SquirrelKeywords [] = 1549 - { 1550 - "base", "break", "case", "catch", "class", "clone", 1551 - "continue", "const", "default", "delete", "else", "enum", 1552 - "extends", "for", "foreach", "function", "if", "in", 1553 - "local", "null", "resume", "return", "switch", "this", 1554 - "throw", "try", "typeof", "while", "yield", "constructor", 1555 - "instanceof", "true", "false", "static", "__LINE__", "__FILE__" 1556 - }; 1557 - 1558 - static inline bool isalnum_(char c) {return isalnum(c) || c == '_';} 1559 - 1560 - static const tic_outline_item* getSquirrelOutline(const char* code, s32* size) 1561 - { 1562 - enum{Size = sizeof(tic_outline_item)}; 1563 - 1564 - *size = 0; 1565 - 1566 - static tic_outline_item* items = NULL; 1567 - 1568 - if(items) 1569 - { 1570 - free(items); 1571 - items = NULL; 1572 - } 1573 - 1574 - const char* ptr = code; 1575 - 1576 - while(true) 1577 - { 1578 - static const char FuncString[] = "function "; 1579 - 1580 - ptr = strstr(ptr, FuncString); 1581 - 1582 - if(ptr) 1583 - { 1584 - ptr += sizeof FuncString - 1; 1585 - 1586 - const char* start = ptr; 1587 - const char* end = start; 1588 - 1589 - while(*ptr) 1590 - { 1591 - char c = *ptr; 1592 - 1593 - if(isalnum_(c) || c == ':'); 1594 - else if(c == '(') 1595 - { 1596 - end = ptr; 1597 - break; 1598 - } 1599 - else break; 1600 - 1601 - ptr++; 1602 - } 1603 - 1604 - if(end > start) 1605 - { 1606 - items = realloc(items, (*size + 1) * Size); 1607 - 1608 - items[*size].pos = start; 1609 - items[*size].size = (s32)(end - start); 1610 - 1611 - (*size)++; 1612 - } 1613 - } 1614 - else break; 1615 - } 1616 - 1617 - return items; 1618 - } 1619 - 1620 - void evalSquirrel(tic_mem* tic, const char* code) { 1621 - tic_machine* machine = (tic_machine*)tic; 1622 - HSQUIRRELVM vm = machine->squirrel; 1623 - 1624 - // make sure that the Squirrel interpreter is initialized. 1625 - if (vm == NULL) 1626 - { 1627 - if (!initSquirrel(tic, "")) 1628 - return; 1629 - vm = machine->squirrel; 1630 - } 1631 - 1632 - sq_settop(vm, 0); 1633 - 1634 - if((SQ_FAILED(sq_compilebuffer(vm, code, strlen(code), "squirrel", SQTrue))) || 1635 - (sq_pushroottable(vm), false) || 1636 - (SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue)))) 1637 - { 1638 - sq_getlasterror(vm); 1639 - sq_tostring(vm, -1); 1640 - const SQChar* errorString = "unknown error"; 1641 - sq_getstring(vm, -1, &errorString); 1642 - if (machine->data) 1643 - machine->data->error(machine->data->data, errorString); 1644 - } 1645 - 1646 - sq_settop(vm, 0); 1647 - } 1648 - 1649 - static const tic_script_config SquirrelSyntaxConfig = 1650 - { 1651 - .init = initSquirrel, 1652 - .close = closeSquirrel, 1653 - .tick = callSquirrelTick, 1654 - .scanline = callSquirrelScanline, 1655 - .overline = callSquirrelOverline, 1656 - 1657 - .getOutline = getSquirrelOutline, 1658 - .eval = evalSquirrel, 1659 - 1660 - .blockCommentStart = "/*", 1661 - .blockCommentEnd = "*/", 1662 - .blockCommentStart2 = NULL, 1663 - .blockCommentEnd2 = NULL, 1664 - .singleComment = "//", 1665 - .blockStringStart = "@\"", 1666 - .blockStringEnd = "\"", 1667 - 1668 - .keywords = SquirrelKeywords, 1669 - .keywordsCount = COUNT_OF(SquirrelKeywords), 1670 - }; 1671 - 1672 - const tic_script_config* getSquirrelScriptConfig() 1673 - { 1674 - return &SquirrelSyntaxConfig; 1675 - } 1676 - 1677 - #endif /* defined(TIC_BUILD_WITH_SQUIRREL) */ 1 + // MIT License 2 + 3 + // Copyright (c) 2017 Vadim Grigoruk @nesbox // grigoruk@gmail.com 4 + 5 + // Permission is hereby granted, free of charge, to any person obtaining a copy 6 + // of this software and associated documentation files (the "Software"), to deal 7 + // in the Software without restriction, including without limitation the rights 8 + // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 + // copies of the Software, and to permit persons to whom the Software is 10 + // furnished to do so, subject to the following conditions: 11 + 12 + // The above copyright notice and this permission notice shall be included in all 13 + // copies or substantial portions of the Software. 14 + 15 + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 + // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 + // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 + // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 + // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 + // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 + // SOFTWARE. 22 + 23 + #include "core/machine.h" 24 + 25 + #if defined(TIC_BUILD_WITH_SQUIRREL) 26 + 27 + //#define USE_FOREIGN_POINTER 28 + //#define CHECK_FORCE_EXIT 29 + 30 + #include <stdlib.h> 31 + #include <stdio.h> 32 + #include <string.h> 33 + #include <squirrel.h> 34 + #include <sqstdmath.h> 35 + #include <sqstdstring.h> 36 + #include <sqstdblob.h> 37 + #include <ctype.h> 38 + 39 + static const char TicMachine[] = "_TIC80"; 40 + 41 + 42 + // !TODO: get rid of this wrap 43 + static s32 getSquirrelNumber(HSQUIRRELVM vm, s32 index) 44 + { 45 + SQInteger i; 46 + if (SQ_SUCCEEDED(sq_getinteger(vm, index, &i))) 47 + return (s32)i; 48 + 49 + SQFloat f; 50 + if (SQ_SUCCEEDED(sq_getfloat(vm, index, &f))) 51 + return (s32)f; 52 + 53 + return 0; 54 + } 55 + 56 + static void registerSquirrelFunction(tic_machine* machine, SQFUNCTION func, const char *name) 57 + { 58 + sq_pushroottable(machine->squirrel); 59 + sq_pushstring(machine->squirrel, name, -1); 60 + sq_newclosure(machine->squirrel, func, 0); 61 + sq_newslot(machine->squirrel, -3, SQTrue); 62 + sq_poptop(machine->squirrel); // remove root table. 63 + } 64 + 65 + static tic_machine* getSquirrelMachine(HSQUIRRELVM vm) 66 + { 67 + #if USE_FOREIGN_POINTER 68 + return (tic_machine*)sq_getforeignpointer(vm); 69 + #else 70 + sq_pushregistrytable(vm); 71 + sq_pushstring(vm, TicMachine, -1); 72 + if (SQ_FAILED(sq_get(vm, -2))) 73 + { 74 + fprintf(stderr, "FATAL ERROR: TicMachine not found!\n"); 75 + abort(); 76 + } 77 + SQUserPointer ptr; 78 + if (SQ_FAILED(sq_getuserpointer(vm, -1, &ptr))) 79 + { 80 + fprintf(stderr, "FATAL ERROR: Cannot get user pointer for TicMachine!\n"); 81 + abort(); 82 + } 83 + tic_machine* machine = (tic_machine*)ptr; 84 + sq_pop(vm, 2); // user pointer and registry table. 85 + return machine; 86 + #endif 87 + } 88 + 89 + void squirrel_compilerError(HSQUIRRELVM vm, const SQChar* desc, const SQChar* source, 90 + SQInteger line, SQInteger column) 91 + { 92 + tic_machine* machine = getSquirrelMachine(vm); 93 + char buffer[1024]; 94 + snprintf(buffer, 1023, "%.40s line %.6d column %.6d: %s\n", source, (int)line, (int)column, desc); 95 + 96 + if (machine->data) 97 + machine->data->error(machine->data->data, buffer); 98 + } 99 + 100 + static SQInteger squirrel_errorHandler(HSQUIRRELVM vm) 101 + { 102 + tic_machine* machine = getSquirrelMachine(vm); 103 + 104 + SQStackInfos si; 105 + SQInteger level = 0; 106 + while (SQ_SUCCEEDED(sq_stackinfos(vm, level, &si))) 107 + { 108 + char buffer[100]; 109 + snprintf(buffer, 99, "%.40s %.40s %.6d\n", si.funcname, si.source, (int)si.line); 110 + 111 + if (machine->data) 112 + machine->data->error(machine->data->data, buffer); 113 + ++level; 114 + } 115 + 116 + return 0; 117 + } 118 + 119 + 120 + static SQInteger squirrel_peek(HSQUIRRELVM vm) 121 + { 122 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 123 + 124 + // check number of args 125 + if (sq_gettop(vm) != 2) 126 + return sq_throwerror(vm, "invalid parameters, peek(address)"); 127 + s32 address = getSquirrelNumber(vm, 2); 128 + 129 + sq_pushinteger(vm, tic_api_peek(tic, address)); 130 + return 1; 131 + } 132 + 133 + static SQInteger squirrel_poke(HSQUIRRELVM vm) 134 + { 135 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 136 + 137 + if (sq_gettop(vm) != 3) 138 + return sq_throwerror( vm, "invalid parameters, poke(address,value)" ); 139 + 140 + s32 address = getSquirrelNumber(vm, 2); 141 + u8 value = getSquirrelNumber(vm, 3); 142 + 143 + tic_api_poke(tic, address, value); 144 + 145 + return 0; 146 + } 147 + 148 + static SQInteger squirrel_peek4(HSQUIRRELVM vm) 149 + { 150 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 151 + 152 + // check number of args 153 + if (sq_gettop(vm) != 2) 154 + return sq_throwerror(vm, "invalid parameters, peek4(address)"); 155 + s32 address = getSquirrelNumber(vm, 2); 156 + 157 + sq_pushinteger(vm, tic_api_peek4(tic, address)); 158 + return 1; 159 + } 160 + 161 + static SQInteger squirrel_poke4(HSQUIRRELVM vm) 162 + { 163 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 164 + 165 + if (sq_gettop(vm) != 3) 166 + return sq_throwerror( vm, "invalid parameters, poke4(address,value)" ); 167 + 168 + s32 address = getSquirrelNumber(vm, 2); 169 + u8 value = getSquirrelNumber(vm, 3); 170 + 171 + tic_api_poke4(tic, address, value); 172 + 173 + return 0; 174 + } 175 + 176 + static SQInteger squirrel_cls(HSQUIRRELVM vm) 177 + { 178 + SQInteger top = sq_gettop(vm); 179 + 180 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 181 + 182 + tic_api_cls(tic, top == 2 ? getSquirrelNumber(vm, 2) : 0); 183 + 184 + return 0; 185 + } 186 + 187 + static SQInteger squirrel_pix(HSQUIRRELVM vm) 188 + { 189 + SQInteger top = sq_gettop(vm); 190 + 191 + if(top >= 3) 192 + { 193 + s32 x = getSquirrelNumber(vm, 2); 194 + s32 y = getSquirrelNumber(vm, 3); 195 + 196 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 197 + 198 + if(top >= 4) 199 + { 200 + s32 color = getSquirrelNumber(vm, 4); 201 + tic_api_pix(tic, x, y, color, false); 202 + } 203 + else 204 + { 205 + sq_pushinteger(vm, tic_api_pix(tic, x, y, 0, true)); 206 + return 1; 207 + } 208 + 209 + } 210 + else return sq_throwerror(vm, "invalid parameters, pix(x y [color])\n"); 211 + 212 + return 0; 213 + } 214 + 215 + 216 + 217 + static SQInteger squirrel_line(HSQUIRRELVM vm) 218 + { 219 + SQInteger top = sq_gettop(vm); 220 + 221 + if(top == 6) 222 + { 223 + s32 x0 = getSquirrelNumber(vm, 2); 224 + s32 y0 = getSquirrelNumber(vm, 3); 225 + s32 x1 = getSquirrelNumber(vm, 4); 226 + s32 y1 = getSquirrelNumber(vm, 5); 227 + s32 color = getSquirrelNumber(vm, 6); 228 + 229 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 230 + 231 + tic_api_line(tic, x0, y0, x1, y1, color); 232 + } 233 + else return sq_throwerror(vm, "invalid parameters, line(x0,y0,x1,y1,color)\n"); 234 + 235 + return 0; 236 + } 237 + 238 + static SQInteger squirrel_rect(HSQUIRRELVM vm) 239 + { 240 + SQInteger top = sq_gettop(vm); 241 + 242 + if(top == 6) 243 + { 244 + s32 x = getSquirrelNumber(vm, 2); 245 + s32 y = getSquirrelNumber(vm, 3); 246 + s32 w = getSquirrelNumber(vm, 4); 247 + s32 h = getSquirrelNumber(vm, 5); 248 + s32 color = getSquirrelNumber(vm, 6); 249 + 250 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 251 + 252 + tic_api_rect(tic, x, y, w, h, color); 253 + } 254 + else return sq_throwerror(vm, "invalid parameters, rect(x,y,w,h,color)\n"); 255 + 256 + return 0; 257 + } 258 + 259 + static SQInteger squirrel_rectb(HSQUIRRELVM vm) 260 + { 261 + SQInteger top = sq_gettop(vm); 262 + 263 + if(top == 6) 264 + { 265 + s32 x = getSquirrelNumber(vm, 2); 266 + s32 y = getSquirrelNumber(vm, 3); 267 + s32 w = getSquirrelNumber(vm, 4); 268 + s32 h = getSquirrelNumber(vm, 5); 269 + s32 color = getSquirrelNumber(vm, 6); 270 + 271 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 272 + 273 + tic_api_rectb(tic, x, y, w, h, color); 274 + } 275 + else return sq_throwerror(vm, "invalid parameters, rectb(x,y,w,h,color)\n"); 276 + 277 + return 0; 278 + } 279 + 280 + static SQInteger squirrel_circ(HSQUIRRELVM vm) 281 + { 282 + SQInteger top = sq_gettop(vm); 283 + 284 + if(top == 5) 285 + { 286 + s32 radius = getSquirrelNumber(vm, 4); 287 + if(radius < 0) return 0; 288 + 289 + s32 x = getSquirrelNumber(vm, 2); 290 + s32 y = getSquirrelNumber(vm, 3); 291 + s32 color = getSquirrelNumber(vm, 5); 292 + 293 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 294 + 295 + tic_api_circ(tic, x, y, radius, color); 296 + } 297 + else return sq_throwerror(vm, "invalid parameters, circ(x,y,radius,color)\n"); 298 + 299 + return 0; 300 + } 301 + 302 + static SQInteger squirrel_circb(HSQUIRRELVM vm) 303 + { 304 + SQInteger top = sq_gettop(vm); 305 + 306 + if(top == 5) 307 + { 308 + s32 radius = getSquirrelNumber(vm, 4); 309 + if(radius < 0) return 0; 310 + 311 + s32 x = getSquirrelNumber(vm, 2); 312 + s32 y = getSquirrelNumber(vm, 3); 313 + s32 color = getSquirrelNumber(vm, 5); 314 + 315 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 316 + 317 + tic_api_circb(tic, x, y, radius, color); 318 + } 319 + else return sq_throwerror(vm, "invalid parameters, circb(x,y,radius,color)\n"); 320 + 321 + return 0; 322 + } 323 + 324 + static SQInteger squirrel_tri(HSQUIRRELVM vm) 325 + { 326 + SQInteger top = sq_gettop(vm); 327 + 328 + if(top == 8) 329 + { 330 + s32 pt[6]; 331 + 332 + for(s32 i = 0; i < COUNT_OF(pt); i++) 333 + pt[i] = getSquirrelNumber(vm, i+2); 334 + 335 + s32 color = getSquirrelNumber(vm, 8); 336 + 337 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 338 + 339 + tic_api_tri(tic, pt[0], pt[1], pt[2], pt[3], pt[4], pt[5], color); 340 + } 341 + else return sq_throwerror(vm, "invalid parameters, tri(x1,y1,x2,y2,x3,y3,color)\n"); 342 + 343 + return 0; 344 + } 345 + 346 + static SQInteger squirrel_textri(HSQUIRRELVM vm) 347 + { 348 + SQInteger top = sq_gettop(vm); 349 + 350 + if (top >= 13) 351 + { 352 + float pt[12]; 353 + 354 + for (s32 i = 0; i < COUNT_OF(pt); i++) 355 + { 356 + SQFloat f = 0.0; 357 + sq_getfloat(vm, i + 2, &f); 358 + pt[i] = (float)f; 359 + } 360 + 361 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 362 + static u8 colors[TIC_PALETTE_SIZE]; 363 + s32 count = 0; 364 + bool use_map = false; 365 + 366 + // check for use map 367 + if (top >= 14) 368 + { 369 + SQBool b = SQFalse; 370 + sq_getbool(vm, 14, &b); 371 + use_map = (b != SQFalse); 372 + } 373 + // check for chroma 374 + if(OT_ARRAY == sq_gettype(vm, 15)) 375 + { 376 + for(s32 i = 0; i < TIC_PALETTE_SIZE; i++) 377 + { 378 + sq_pushinteger(vm, (SQInteger)i); 379 + sq_rawget(vm, 15); 380 + if(sq_gettype(vm, -1) & (OT_FLOAT|OT_INTEGER)) 381 + { 382 + colors[i-1] = getSquirrelNumber(vm, -1); 383 + count++; 384 + sq_poptop(vm); 385 + } 386 + else 387 + { 388 + sq_poptop(vm); 389 + break; 390 + } 391 + } 392 + } 393 + else 394 + { 395 + colors[0] = getSquirrelNumber(vm, 15); 396 + count = 1; 397 + } 398 + 399 + tic_api_textri(tic, pt[0], pt[1], // xy 1 400 + pt[2], pt[3], // xy 2 401 + pt[4], pt[5], // xy 3 402 + pt[6], pt[7], // uv 1 403 + pt[8], pt[9], // uv 2 404 + pt[10], pt[11], // uv 3 405 + use_map, // use map 406 + colors, count); // chroma 407 + } 408 + else return sq_throwerror(vm, "invalid parameters, textri(x1,y1,x2,y2,x3,y3,u1,v1,u2,v2,u3,v3,[use_map=false],[chroma=off])\n"); 409 + return 0; 410 + } 411 + 412 + 413 + static SQInteger squirrel_clip(HSQUIRRELVM vm) 414 + { 415 + SQInteger top = sq_gettop(vm); 416 + 417 + if(top == 1) 418 + { 419 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 420 + 421 + tic_api_clip(tic, 0, 0, TIC80_WIDTH, TIC80_HEIGHT); 422 + } 423 + else if(top == 5) 424 + { 425 + s32 x = getSquirrelNumber(vm, 2); 426 + s32 y = getSquirrelNumber(vm, 3); 427 + s32 w = getSquirrelNumber(vm, 4); 428 + s32 h = getSquirrelNumber(vm, 5); 429 + 430 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 431 + 432 + tic_api_clip((tic_mem*)getSquirrelMachine(vm), x, y, w, h); 433 + } 434 + else return sq_throwerror(vm, "invalid parameters, use clip(x,y,w,h) or clip()\n"); 435 + 436 + return 0; 437 + } 438 + 439 + static SQInteger squirrel_btnp(HSQUIRRELVM vm) 440 + { 441 + tic_machine* machine = getSquirrelMachine(vm); 442 + tic_mem* tic = (tic_mem*)machine; 443 + 444 + SQInteger top = sq_gettop(vm); 445 + 446 + if (top == 1) 447 + { 448 + sq_pushinteger(vm, tic_api_btnp(tic, -1, -1, -1)); 449 + } 450 + else if(top == 2) 451 + { 452 + s32 index = getSquirrelNumber(vm, 2) & 0x1f; 453 + 454 + sq_pushbool(vm, (tic_api_btnp(tic, index, -1, -1) ? SQTrue : SQFalse)); 455 + } 456 + else if (top == 4) 457 + { 458 + s32 index = getSquirrelNumber(vm, 2) & 0x1f; 459 + u32 hold = getSquirrelNumber(vm, 3); 460 + u32 period = getSquirrelNumber(vm, 4); 461 + 462 + sq_pushbool(vm, (tic_api_btnp(tic, index, hold, period) ? SQTrue : SQFalse)); 463 + } 464 + else 465 + { 466 + return sq_throwerror(vm, "invalid params, btnp [ id [ hold period ] ]\n"); 467 + } 468 + 469 + return 1; 470 + } 471 + 472 + static SQInteger squirrel_btn(HSQUIRRELVM vm) 473 + { 474 + tic_machine* machine = getSquirrelMachine(vm); 475 + 476 + SQInteger top = sq_gettop(vm); 477 + 478 + if (top == 1) 479 + { 480 + sq_pushinteger(vm, machine->memory.ram.input.gamepads.data); 481 + } 482 + else if (top == 2) 483 + { 484 + u32 index = getSquirrelNumber(vm, 2) & 0x1f; 485 + bool pressed = (machine->memory.ram.input.gamepads.data & (1 << index)) != 0; 486 + sq_pushbool(vm, pressed ? SQTrue : SQFalse); 487 + } 488 + else 489 + { 490 + return sq_throwerror(vm, "invalid params, btn [ id ]\n"); 491 + } 492 + 493 + return 1; 494 + } 495 + 496 + static SQInteger squirrel_spr(HSQUIRRELVM vm) 497 + { 498 + SQInteger top = sq_gettop(vm); 499 + 500 + s32 index = 0; 501 + s32 x = 0; 502 + s32 y = 0; 503 + s32 w = 1; 504 + s32 h = 1; 505 + s32 scale = 1; 506 + tic_flip flip = tic_no_flip; 507 + tic_rotate rotate = tic_no_rotate; 508 + static u8 colors[TIC_PALETTE_SIZE]; 509 + s32 count = 0; 510 + 511 + if(top >= 2) 512 + { 513 + index = getSquirrelNumber(vm, 2); 514 + 515 + if(top >= 4) 516 + { 517 + x = getSquirrelNumber(vm, 3); 518 + y = getSquirrelNumber(vm, 4); 519 + 520 + if(top >= 5) 521 + { 522 + if(OT_ARRAY == sq_gettype(vm, 5)) 523 + { 524 + for(s32 i = 0; i < TIC_PALETTE_SIZE; i++) 525 + { 526 + sq_pushinteger(vm, (SQInteger)i); 527 + sq_rawget(vm, 5); 528 + if(sq_gettype(vm, -1) & (OT_FLOAT|OT_INTEGER)) 529 + { 530 + colors[i-1] = getSquirrelNumber(vm, -1); 531 + count++; 532 + sq_poptop(vm); 533 + } 534 + else 535 + { 536 + sq_poptop(vm); 537 + break; 538 + } 539 + } 540 + } 541 + else 542 + { 543 + colors[0] = getSquirrelNumber(vm, 5); 544 + count = 1; 545 + } 546 + 547 + if(top >= 6) 548 + { 549 + scale = getSquirrelNumber(vm, 6); 550 + 551 + if(top >= 7) 552 + { 553 + flip = getSquirrelNumber(vm, 7); 554 + 555 + if(top >= 8) 556 + { 557 + rotate = getSquirrelNumber(vm, 8); 558 + 559 + if(top >= 10) 560 + { 561 + w = getSquirrelNumber(vm, 9); 562 + h = getSquirrelNumber(vm, 10); 563 + } 564 + } 565 + } 566 + } 567 + } 568 + } 569 + } 570 + 571 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 572 + 573 + tic_api_spr(tic, index, x, y, w, h, colors, count, scale, flip, rotate); 574 + 575 + return 0; 576 + } 577 + 578 + static SQInteger squirrel_mget(HSQUIRRELVM vm) 579 + { 580 + SQInteger top = sq_gettop(vm); 581 + 582 + if(top == 3) 583 + { 584 + s32 x = getSquirrelNumber(vm, 2); 585 + s32 y = getSquirrelNumber(vm, 3); 586 + 587 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 588 + 589 + u8 value = tic_api_mget(tic, x, y); 590 + sq_pushinteger(vm, value); 591 + return 1; 592 + } 593 + else return sq_throwerror(vm, "invalid params, mget(x,y)\n"); 594 + 595 + return 0; 596 + } 597 + 598 + static SQInteger squirrel_mset(HSQUIRRELVM vm) 599 + { 600 + SQInteger top = sq_gettop(vm); 601 + 602 + if(top == 4) 603 + { 604 + s32 x = getSquirrelNumber(vm, 2); 605 + s32 y = getSquirrelNumber(vm, 3); 606 + u8 val = getSquirrelNumber(vm, 4); 607 + 608 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 609 + 610 + tic_api_mset(tic, x, y, val); 611 + } 612 + else return sq_throwerror(vm, "invalid params, mget(x,y)\n"); 613 + 614 + return 0; 615 + } 616 + 617 + typedef struct 618 + { 619 + HSQUIRRELVM vm; 620 + HSQOBJECT reg; 621 + } RemapData; 622 + 623 + static void remapCallback(void* data, s32 x, s32 y, RemapResult* result) 624 + { 625 + RemapData* remap = (RemapData*)data; 626 + HSQUIRRELVM vm = remap->vm; 627 + 628 + SQInteger top = sq_gettop(vm); 629 + 630 + sq_pushobject(vm, remap->reg); 631 + sq_pushroottable(vm); 632 + sq_pushinteger(vm, result->index); 633 + sq_pushinteger(vm, x); 634 + sq_pushinteger(vm, y); 635 + //lua_pcall(lua, 3, 3, 0); 636 + 637 + if (SQ_SUCCEEDED(sq_call(vm, 4, SQTrue, SQTrue))) 638 + { 639 + sq_pushinteger(vm, 0); 640 + if (SQ_SUCCEEDED(sq_get(vm, -2))) 641 + { 642 + result->index = getSquirrelNumber(vm, -1); 643 + sq_poptop(vm); 644 + sq_pushinteger(vm, 1); 645 + if (SQ_SUCCEEDED(sq_get(vm, -2))) 646 + { 647 + result->flip = getSquirrelNumber(vm, -1); 648 + sq_poptop(vm); 649 + sq_pushinteger(vm, 2); 650 + if (SQ_SUCCEEDED(sq_get(vm, -2))) 651 + { 652 + result->rotate = getSquirrelNumber(vm, -1); 653 + sq_poptop(vm); 654 + } 655 + } 656 + } 657 + } 658 + 659 + sq_settop(vm, top); 660 + } 661 + 662 + static SQInteger squirrel_map(HSQUIRRELVM vm) 663 + { 664 + s32 x = 0; 665 + s32 y = 0; 666 + s32 w = TIC_MAP_SCREEN_WIDTH; 667 + s32 h = TIC_MAP_SCREEN_HEIGHT; 668 + s32 sx = 0; 669 + s32 sy = 0; 670 + s32 scale = 1; 671 + static u8 colors[TIC_PALETTE_SIZE]; 672 + s32 count = 0; 673 + 674 + SQInteger top = sq_gettop(vm); 675 + 676 + if(top >= 3) 677 + { 678 + x = getSquirrelNumber(vm, 2); 679 + y = getSquirrelNumber(vm, 3); 680 + 681 + if(top >= 5) 682 + { 683 + w = getSquirrelNumber(vm, 4); 684 + h = getSquirrelNumber(vm, 5); 685 + 686 + if(top >= 7) 687 + { 688 + sx = getSquirrelNumber(vm, 6); 689 + sy = getSquirrelNumber(vm, 7); 690 + 691 + if(top >= 8) 692 + { 693 + if(OT_ARRAY == sq_gettype(vm, 8)) 694 + { 695 + for(s32 i = 0; i < TIC_PALETTE_SIZE; i++) 696 + { 697 + sq_pushinteger(vm, (SQInteger)i); 698 + sq_rawget(vm, 8); 699 + if(sq_gettype(vm, -1) & (OT_FLOAT|OT_INTEGER)) 700 + { 701 + colors[i-1] = getSquirrelNumber(vm, -1); 702 + count++; 703 + sq_poptop(vm); 704 + } 705 + else 706 + { 707 + sq_poptop(vm); 708 + break; 709 + } 710 + } 711 + } 712 + else 713 + { 714 + colors[0] = getSquirrelNumber(vm, 8); 715 + count = 1; 716 + } 717 + 718 + if(top >= 9) 719 + { 720 + scale = getSquirrelNumber(vm, 9); 721 + 722 + if(top >= 10) 723 + { 724 + SQObjectType type = sq_gettype(vm, 10); 725 + if (type & (OT_CLOSURE|OT_NATIVECLOSURE|OT_INSTANCE)) 726 + { 727 + RemapData data = {vm}; 728 + sq_resetobject(&data.reg); 729 + sq_getstackobj(vm, 10, &data.reg); 730 + sq_addref(vm, &data.reg); 731 + 732 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 733 + 734 + tic_api_map(tic, x, y, w, h, sx, sy, colors, count, scale, remapCallback, &data); 735 + 736 + //luaL_unref(lua, LUA_REGISTRYINDEX, data.reg); 737 + sq_release(vm, &data.reg); 738 + 739 + return 0; 740 + } 741 + } 742 + } 743 + } 744 + } 745 + } 746 + } 747 + 748 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 749 + 750 + tic_api_map((tic_mem*)getSquirrelMachine(vm), x, y, w, h, sx, sy, colors, count, scale, NULL, NULL); 751 + 752 + return 0; 753 + } 754 + 755 + static SQInteger squirrel_music(HSQUIRRELVM vm) 756 + { 757 + SQInteger top = sq_gettop(vm); 758 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 759 + 760 + if(top == 1) tic_api_music(tic, -1, 0, 0, false, false); 761 + else if(top >= 2) 762 + { 763 + tic_api_music(tic, -1, 0, 0, false, false); 764 + 765 + s32 track = getSquirrelNumber(vm, 2); 766 + s32 frame = -1; 767 + s32 row = -1; 768 + bool loop = true; 769 + bool sustain = false; 770 + 771 + if(top >= 3) 772 + { 773 + frame = getSquirrelNumber(vm, 3); 774 + 775 + if(top >= 4) 776 + { 777 + row = getSquirrelNumber(vm, 4); 778 + 779 + if(top >= 5) 780 + { 781 + SQBool b = SQFalse; 782 + sq_getbool(vm, 5, &b); 783 + loop = (b != SQFalse); 784 + if(top >= 6) 785 + { 786 + SQBool b = SQFalse; 787 + sq_getbool(vm, 6, &b); 788 + sustain = (b != SQFalse); 789 + } 790 + } 791 + } 792 + } 793 + 794 + tic_api_music(tic, track, frame, row, loop, sustain); 795 + } 796 + else return sq_throwerror(vm, "invalid params, use music(track)\n"); 797 + 798 + return 0; 799 + } 800 + 801 + static SQInteger squirrel_sfx(HSQUIRRELVM vm) 802 + { 803 + SQInteger top = sq_gettop(vm); 804 + 805 + if(top >= 2) 806 + { 807 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 808 + 809 + s32 note = -1; 810 + s32 octave = -1; 811 + s32 duration = -1; 812 + s32 channel = 0; 813 + s32 volume = MAX_VOLUME; 814 + s32 speed = SFX_DEF_SPEED; 815 + 816 + s32 index = getSquirrelNumber(vm, 2); 817 + 818 + if(index < SFX_COUNT) 819 + { 820 + if (index >= 0) 821 + { 822 + tic_sample* effect = tic->ram.sfx.samples.data + index; 823 + 824 + note = effect->note; 825 + octave = effect->octave; 826 + speed = effect->speed; 827 + } 828 + 829 + if(top >= 3) 830 + { 831 + if(sq_gettype(vm, 3) & (OT_INTEGER|OT_FLOAT)) 832 + { 833 + s32 id = getSquirrelNumber(vm, 3); 834 + note = id % NOTES; 835 + octave = id / NOTES; 836 + } 837 + else if(sq_gettype(vm, 3) == OT_STRING) 838 + { 839 + const SQChar* str; 840 + sq_getstring(vm, 3, &str); 841 + const char* noteStr = (const char*)str; 842 + 843 + if(!tic_tool_parse_note(noteStr, &note, &octave)) 844 + { 845 + return sq_throwerror(vm, "invalid note, should be like C#4\n"); 846 + } 847 + } 848 + 849 + if(top >= 4) 850 + { 851 + duration = getSquirrelNumber(vm, 4); 852 + 853 + if(top >= 5) 854 + { 855 + channel = getSquirrelNumber(vm, 5); 856 + 857 + if(top >= 6) 858 + { 859 + volume = getSquirrelNumber(vm, 6); 860 + 861 + if(top >= 7) 862 + { 863 + speed = getSquirrelNumber(vm, 7); 864 + } 865 + } 866 + } 867 + } 868 + } 869 + 870 + if (channel >= 0 && channel < TIC_SOUND_CHANNELS) 871 + { 872 + tic_api_sfx(tic, index, note, octave, duration, channel, volume & 0xf, speed); 873 + } 874 + else return sq_throwerror(vm, "unknown channel\n"); 875 + } 876 + else return sq_throwerror(vm, "unknown sfx index\n"); 877 + } 878 + else return sq_throwerror(vm, "invalid sfx params\n"); 879 + 880 + return 0; 881 + } 882 + 883 + static SQInteger squirrel_sync(HSQUIRRELVM vm) 884 + { 885 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 886 + 887 + bool toCart = false; 888 + u32 mask = 0; 889 + s32 bank = 0; 890 + 891 + if(sq_gettop(vm) >= 2) 892 + { 893 + mask = getSquirrelNumber(vm, 2); 894 + 895 + if(sq_gettop(vm) >= 3) 896 + { 897 + bank = getSquirrelNumber(vm, 3); 898 + 899 + if(sq_gettop(vm) >= 4) 900 + { 901 + SQBool b = SQFalse; 902 + sq_getbool(vm, 4, &b); 903 + toCart = (b != SQFalse); 904 + } 905 + } 906 + } 907 + 908 + if(bank >= 0 && bank < TIC_BANKS) 909 + tic_api_sync(tic, mask, bank, toCart); 910 + else 911 + return sq_throwerror(vm, "sync() error, invalid bank"); 912 + 913 + return 0; 914 + } 915 + 916 + static SQInteger squirrel_reset(HSQUIRRELVM vm) 917 + { 918 + tic_machine* machine = getSquirrelMachine(vm); 919 + 920 + machine->state.initialized = false; 921 + 922 + return 0; 923 + } 924 + 925 + static SQInteger squirrel_key(HSQUIRRELVM vm) 926 + { 927 + tic_machine* machine = getSquirrelMachine(vm); 928 + tic_mem* tic = &machine->memory; 929 + 930 + SQInteger top = sq_gettop(vm); 931 + 932 + if (top == 1) 933 + { 934 + sq_pushbool(vm, tic_api_key(tic, tic_key_unknown) ? SQTrue : SQFalse); 935 + } 936 + else if (top == 2) 937 + { 938 + tic_key key = getSquirrelNumber(vm, 2); 939 + 940 + if(key < tic_key_escape) 941 + sq_pushbool(vm, tic_api_key(tic, key) ? SQTrue : SQFalse); 942 + else 943 + { 944 + return sq_throwerror(vm, "unknown keyboard code\n"); 945 + } 946 + } 947 + else 948 + { 949 + return sq_throwerror(vm, "invalid params, key [code]\n"); 950 + } 951 + 952 + return 1; 953 + } 954 + 955 + static SQInteger squirrel_keyp(HSQUIRRELVM vm) 956 + { 957 + tic_machine* machine = getSquirrelMachine(vm); 958 + tic_mem* tic = &machine->memory; 959 + 960 + SQInteger top = sq_gettop(vm); 961 + 962 + if (top == 1) 963 + { 964 + sq_pushbool(vm, tic_api_keyp(tic, tic_key_unknown, -1, -1) ? SQTrue : SQFalse); 965 + } 966 + else 967 + { 968 + tic_key key = getSquirrelNumber(vm, 2); 969 + 970 + if(key >= tic_key_escape) 971 + { 972 + return sq_throwerror(vm, "unknown keyboard code\n"); 973 + } 974 + else 975 + { 976 + if(top == 2) 977 + { 978 + sq_pushbool(vm, tic_api_keyp(tic, key, -1, -1) ? SQTrue : SQFalse); 979 + } 980 + else if(top == 4) 981 + { 982 + u32 hold = getSquirrelNumber(vm, 3); 983 + u32 period = getSquirrelNumber(vm, 4); 984 + 985 + sq_pushbool(vm, tic_api_keyp(tic, key, hold, period) ? SQTrue : SQFalse); 986 + } 987 + else 988 + { 989 + return sq_throwerror(vm, "invalid params, keyp [ code [ hold period ] ]\n"); 990 + } 991 + } 992 + } 993 + 994 + return 1; 995 + } 996 + 997 + static SQInteger squirrel_memcpy(HSQUIRRELVM vm) 998 + { 999 + SQInteger top = sq_gettop(vm); 1000 + 1001 + if(top == 4) 1002 + { 1003 + s32 dest = getSquirrelNumber(vm, 2); 1004 + s32 src = getSquirrelNumber(vm, 3); 1005 + s32 size = getSquirrelNumber(vm, 4); 1006 + 1007 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1008 + tic_api_memcpy(tic, dest, src, size); 1009 + return 0; 1010 + } 1011 + 1012 + return sq_throwerror(vm, "invalid params, memcpy(dest,src,size)\n"); 1013 + } 1014 + 1015 + static SQInteger squirrel_memset(HSQUIRRELVM vm) 1016 + { 1017 + SQInteger top = sq_gettop(vm); 1018 + 1019 + if(top == 4) 1020 + { 1021 + s32 dest = getSquirrelNumber(vm, 2); 1022 + u8 value = getSquirrelNumber(vm, 3); 1023 + s32 size = getSquirrelNumber(vm, 4); 1024 + 1025 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1026 + tic_api_memset(tic, dest, value, size); 1027 + return 0; 1028 + } 1029 + 1030 + return sq_throwerror(vm, "invalid params, memset(dest,val,size)\n"); 1031 + } 1032 + 1033 + // NB we leave the string on the stack so that the char* pointer remains valid. 1034 + static const char* printString(HSQUIRRELVM vm, s32 index) 1035 + { 1036 + const SQChar* text = ""; 1037 + if (SQ_SUCCEEDED(sq_tostring(vm, index))) 1038 + { 1039 + sq_getstring(vm, -1, &text); 1040 + } 1041 + 1042 + return (const char*)text; 1043 + } 1044 + 1045 + static SQInteger squirrel_font(HSQUIRRELVM vm) 1046 + { 1047 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1048 + SQInteger top = sq_gettop(vm); 1049 + 1050 + if(top >= 2) 1051 + { 1052 + const char* text = printString(vm, 2); 1053 + s32 x = 0; 1054 + s32 y = 0; 1055 + s32 width = TIC_SPRITESIZE; 1056 + s32 height = TIC_SPRITESIZE; 1057 + u8 chromakey = 0; 1058 + bool fixed = false; 1059 + bool alt = false; 1060 + s32 scale = 1; 1061 + 1062 + if(top >= 4) 1063 + { 1064 + x = getSquirrelNumber(vm, 3); 1065 + y = getSquirrelNumber(vm, 4); 1066 + 1067 + if(top >= 5) 1068 + { 1069 + chromakey = getSquirrelNumber(vm, 5); 1070 + 1071 + if(top >= 7) 1072 + { 1073 + width = getSquirrelNumber(vm, 6); 1074 + height = getSquirrelNumber(vm, 7); 1075 + 1076 + if(top >= 8) 1077 + { 1078 + SQBool b = SQFalse; 1079 + sq_getbool(vm, 8, &b); 1080 + fixed = (b != SQFalse); 1081 + 1082 + if(top >= 9) 1083 + { 1084 + scale = getSquirrelNumber(vm, 9); 1085 + 1086 + if (top >= 10) 1087 + { 1088 + SQBool b = SQFalse; 1089 + sq_getbool(vm, 10, &b); 1090 + alt = (b != SQFalse); 1091 + } 1092 + 1093 + } 1094 + } 1095 + } 1096 + } 1097 + } 1098 + 1099 + if(scale == 0) 1100 + { 1101 + sq_pushinteger(vm, 0); 1102 + return 1; 1103 + } 1104 + 1105 + s32 size = tic_api_font(tic, text, x, y, chromakey, width, height, fixed, scale, alt); 1106 + 1107 + sq_pushinteger(vm, size); 1108 + return 1; 1109 + } 1110 + 1111 + return 0; 1112 + } 1113 + 1114 + static SQInteger squirrel_print(HSQUIRRELVM vm) 1115 + { 1116 + SQInteger top = sq_gettop(vm); 1117 + 1118 + if(top >= 2) 1119 + { 1120 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1121 + 1122 + s32 x = 0; 1123 + s32 y = 0; 1124 + s32 color = TIC_PALETTE_SIZE-1; 1125 + bool fixed = false; 1126 + bool alt = false; 1127 + s32 scale = 1; 1128 + 1129 + const char* text = printString(vm, 2); 1130 + 1131 + if(top >= 4) 1132 + { 1133 + x = getSquirrelNumber(vm, 3); 1134 + y = getSquirrelNumber(vm, 4); 1135 + 1136 + if(top >= 5) 1137 + { 1138 + color = getSquirrelNumber(vm, 5) % TIC_PALETTE_SIZE; 1139 + 1140 + if(top >= 6) 1141 + { 1142 + SQBool b = SQFalse; 1143 + sq_getbool(vm, 5, &b); 1144 + fixed = (b != SQFalse); 1145 + 1146 + if(top >= 7) 1147 + { 1148 + scale = getSquirrelNumber(vm, 7); 1149 + 1150 + if (top >= 8) 1151 + { 1152 + SQBool b = SQFalse; 1153 + sq_getbool(vm, 8, &b); 1154 + alt = (b != SQFalse); 1155 + } 1156 + } 1157 + } 1158 + } 1159 + } 1160 + 1161 + if(scale == 0) 1162 + { 1163 + sq_pushinteger(vm, 0); 1164 + return 1; 1165 + } 1166 + 1167 + s32 size = tic_api_print(tic, text ? text : "nil", x, y, color, fixed, scale, alt); 1168 + 1169 + sq_pushinteger(vm, size); 1170 + 1171 + return 1; 1172 + } 1173 + 1174 + return 0; 1175 + } 1176 + 1177 + static SQInteger squirrel_trace(HSQUIRRELVM vm) 1178 + { 1179 + SQInteger top = sq_gettop(vm); 1180 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1181 + 1182 + if(top >= 2) 1183 + { 1184 + const char* text = printString(vm, 2); 1185 + u8 color = tic_color_12; 1186 + 1187 + if(top >= 3) 1188 + { 1189 + color = getSquirrelNumber(vm, 3); 1190 + } 1191 + 1192 + tic_api_trace(tic, text, color); 1193 + } 1194 + 1195 + return 0; 1196 + } 1197 + 1198 + static SQInteger squirrel_pmem(HSQUIRRELVM vm) 1199 + { 1200 + SQInteger top = sq_gettop(vm); 1201 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1202 + 1203 + if(top >= 2) 1204 + { 1205 + u32 index = getSquirrelNumber(vm, 2); 1206 + 1207 + if(index < TIC_PERSISTENT_SIZE) 1208 + { 1209 + u32 val = tic_api_pmem(tic, index, 0, false); 1210 + 1211 + if(top >= 3) 1212 + { 1213 + SQInteger i = 0; 1214 + sq_getinteger(vm, 3, &i); 1215 + tic_api_pmem(tic, index, (u32)i, true); 1216 + } 1217 + 1218 + sq_pushinteger(vm, val); 1219 + 1220 + return 1; 1221 + } 1222 + return sq_throwerror(vm, "invalid persistent tic index\n"); 1223 + } 1224 + else return sq_throwerror(vm, "invalid params, pmem(index [val]) -> val\n"); 1225 + 1226 + return 0; 1227 + } 1228 + 1229 + static SQInteger squirrel_time(HSQUIRRELVM vm) 1230 + { 1231 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1232 + 1233 + sq_pushfloat(vm, (SQFloat)(tic_api_time(tic))); 1234 + 1235 + return 1; 1236 + } 1237 + 1238 + static SQInteger squirrel_tstamp(HSQUIRRELVM vm) 1239 + { 1240 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1241 + 1242 + sq_pushinteger(vm, (SQFloat)(tic_api_tstamp(tic))); 1243 + 1244 + return 1; 1245 + } 1246 + 1247 + static SQInteger squirrel_exit(HSQUIRRELVM vm) 1248 + { 1249 + tic_api_exit((tic_mem*)getSquirrelMachine(vm)); 1250 + 1251 + return 0; 1252 + } 1253 + 1254 + static SQInteger squirrel_mouse(HSQUIRRELVM vm) 1255 + { 1256 + tic_machine* machine = getSquirrelMachine(vm); 1257 + 1258 + const tic80_mouse* mouse = &machine->memory.ram.input.mouse; 1259 + 1260 + sq_newarray(vm, 7); 1261 + sq_pushinteger(vm, mouse->x); 1262 + sq_arrayappend(vm, -2); 1263 + sq_pushinteger(vm, mouse->y); 1264 + sq_arrayappend(vm, -2); 1265 + sq_pushbool(vm, mouse->left ? SQTrue : SQFalse); 1266 + sq_arrayappend(vm, -2); 1267 + sq_pushbool(vm, mouse->middle ? SQTrue : SQFalse); 1268 + sq_arrayappend(vm, -2); 1269 + sq_pushbool(vm, mouse->right ? SQTrue : SQFalse); 1270 + sq_arrayappend(vm, -2); 1271 + sq_pushinteger(vm, mouse->scrollx); 1272 + sq_arrayappend(vm, -2); 1273 + sq_pushinteger(vm, mouse->scrolly); 1274 + sq_arrayappend(vm, -2); 1275 + 1276 + return 1; 1277 + } 1278 + 1279 + static SQInteger squirrel_fget(HSQUIRRELVM vm) 1280 + { 1281 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1282 + 1283 + SQInteger top = sq_gettop(vm); 1284 + 1285 + if(top >= 2) 1286 + { 1287 + u32 index = getSquirrelNumber(vm, 2); 1288 + 1289 + if(top >= 3) 1290 + { 1291 + u32 flag = getSquirrelNumber(vm, 3); 1292 + sq_pushbool(vm, tic_api_fget(tic, index, flag)); 1293 + return 1; 1294 + } 1295 + } 1296 + 1297 + sq_throwerror(vm, "invalid params, fget(index, flag) -> val\n"); 1298 + 1299 + return 0; 1300 + } 1301 + 1302 + static SQInteger squirrel_fset(HSQUIRRELVM vm) 1303 + { 1304 + tic_mem* tic = (tic_mem*)getSquirrelMachine(vm); 1305 + 1306 + SQInteger top = sq_gettop(vm); 1307 + 1308 + if(top >= 2) 1309 + { 1310 + u32 index = getSquirrelNumber(vm, 2); 1311 + 1312 + if(top >= 3) 1313 + { 1314 + u32 flag = getSquirrelNumber(vm, 3); 1315 + 1316 + if(top >= 4) 1317 + { 1318 + SQBool value = SQFalse; 1319 + sq_getbool(vm, 4, &value); 1320 + 1321 + tic_api_fset(tic, index, flag, value); 1322 + return 0; 1323 + } 1324 + } 1325 + } 1326 + 1327 + sq_throwerror(vm, "invalid params, fset(index, flag, value)\n"); 1328 + 1329 + return 0; 1330 + } 1331 + 1332 + static SQInteger squirrel_dofile(HSQUIRRELVM vm) 1333 + { 1334 + return sq_throwerror(vm, "unknown method: \"dofile\"\n"); 1335 + } 1336 + 1337 + static SQInteger squirrel_loadfile(HSQUIRRELVM vm) 1338 + { 1339 + return sq_throwerror(vm, "unknown method: \"loadfile\"\n"); 1340 + } 1341 + 1342 + static void squirrel_open_builtins(HSQUIRRELVM vm) 1343 + { 1344 + sq_pushroottable(vm); 1345 + sqstd_register_mathlib(vm); 1346 + sqstd_register_stringlib(vm); 1347 + sqstd_register_bloblib(vm); 1348 + sq_poptop(vm); 1349 + } 1350 + 1351 + static void checkForceExit(HSQUIRRELVM vm, SQInteger type, const SQChar* sourceName, SQInteger line, const SQChar* functionName) 1352 + { 1353 + tic_machine* machine = getSquirrelMachine(vm); 1354 + tic_tick_data* tick = machine->data; 1355 + 1356 + if(tick && tick->forceExit && tick->forceExit(tick->data)) 1357 + sq_throwerror(vm, "script execution was interrupted"); 1358 + } 1359 + 1360 + static void initAPI(tic_machine* machine) 1361 + { 1362 + HSQUIRRELVM vm = machine->squirrel; 1363 + 1364 + sq_setcompilererrorhandler(vm, squirrel_compilerError); 1365 + 1366 + sq_pushregistrytable(vm); 1367 + sq_pushstring(vm, TicMachine, -1); 1368 + sq_pushuserpointer(machine->squirrel, machine); 1369 + sq_newslot(vm, -3, SQTrue); 1370 + sq_poptop(vm); 1371 + 1372 + #if USE_FOREIGN_POINTER 1373 + sq_setforeignptr(vm, machine); 1374 + #endif 1375 + 1376 + #define API_FUNC_DEF(name, ...) {squirrel_ ## name, #name}, 1377 + static const struct{SQFUNCTION func; const char* name;} ApiItems[] = {TIC_API_LIST(API_FUNC_DEF)}; 1378 + #undef API_FUNC_DEF 1379 + 1380 + for (s32 i = 0; i < COUNT_OF(ApiItems); i++) 1381 + registerSquirrelFunction(machine, ApiItems[i].func, ApiItems[i].name); 1382 + 1383 + registerSquirrelFunction(machine, squirrel_dofile, "dofile"); 1384 + registerSquirrelFunction(machine, squirrel_loadfile, "loadfile"); 1385 + 1386 + #if CHECK_FORCE_EXIT 1387 + sq_setnativedebughook(vm, checkForceExit); 1388 + #endif 1389 + sq_enabledebuginfo(vm, SQTrue); 1390 + 1391 + } 1392 + 1393 + static void closeSquirrel(tic_mem* tic) 1394 + { 1395 + tic_machine* machine = (tic_machine*)tic; 1396 + 1397 + if(machine->squirrel) 1398 + { 1399 + sq_close(machine->squirrel); 1400 + machine->squirrel = NULL; 1401 + } 1402 + } 1403 + 1404 + static bool initSquirrel(tic_mem* tic, const char* code) 1405 + { 1406 + tic_machine* machine = (tic_machine*)tic; 1407 + 1408 + closeSquirrel(tic); 1409 + 1410 + HSQUIRRELVM vm = machine->squirrel = sq_open(100); 1411 + squirrel_open_builtins(vm); 1412 + 1413 + sq_newclosure(vm, squirrel_errorHandler, 0); 1414 + sq_seterrorhandler(vm); 1415 + 1416 + initAPI(machine); 1417 + 1418 + { 1419 + HSQUIRRELVM vm = machine->squirrel; 1420 + 1421 + sq_settop(vm, 0); 1422 + 1423 + if((SQ_FAILED(sq_compilebuffer(vm, code, strlen(code), "squirrel", SQTrue))) || 1424 + (sq_pushroottable(vm), false) || 1425 + (SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue)))) 1426 + { 1427 + sq_getlasterror(vm); 1428 + sq_tostring(vm, -1); 1429 + const SQChar* errorString = "unknown error"; 1430 + sq_getstring(vm, -1, &errorString); 1431 + 1432 + if (machine->data) 1433 + machine->data->error(machine->data->data, errorString); 1434 + 1435 + sq_pop(vm, 2); // error and error string 1436 + 1437 + return false; 1438 + } 1439 + } 1440 + 1441 + return true; 1442 + } 1443 + 1444 + static void callSquirrelTick(tic_mem* tic) 1445 + { 1446 + tic_machine* machine = (tic_machine*)tic; 1447 + 1448 + HSQUIRRELVM vm = machine->squirrel; 1449 + 1450 + if(vm) 1451 + { 1452 + sq_pushroottable(vm); 1453 + sq_pushstring(vm, TIC_FN, -1); 1454 + 1455 + if (SQ_SUCCEEDED(sq_get(vm, -2))) 1456 + { 1457 + sq_pushroottable(vm); 1458 + if(SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue))) 1459 + { 1460 + sq_getlasterror(vm); 1461 + sq_tostring(vm, -1); 1462 + const SQChar* errorString = "unknown error"; 1463 + sq_getstring(vm, -1, &errorString); 1464 + 1465 + if (machine->data) 1466 + machine->data->error(machine->data->data, errorString); 1467 + sq_pop(vm, 3); // remove string, error and root table. 1468 + } 1469 + } 1470 + else 1471 + { 1472 + sq_pop(vm, 1); 1473 + if (machine->data) 1474 + machine->data->error(machine->data->data, "'function TIC()...' isn't found :("); 1475 + } 1476 + } 1477 + } 1478 + 1479 + static void callSquirrelScanlineName(tic_mem* tic, s32 row, void* data, const char* name) 1480 + { 1481 + tic_machine* machine = (tic_machine*)tic; 1482 + HSQUIRRELVM vm = machine->squirrel; 1483 + 1484 + if (vm) 1485 + { 1486 + sq_pushroottable(vm); 1487 + sq_pushstring(vm, name, -1); 1488 + if (SQ_SUCCEEDED(sq_get(vm, -2))) 1489 + { 1490 + sq_pushroottable(vm); 1491 + sq_pushinteger(vm, row); 1492 + 1493 + if(SQ_FAILED(sq_call(vm, 2, SQFalse, SQTrue))) 1494 + { 1495 + sq_getlasterror(vm); 1496 + sq_tostring(vm, -1); 1497 + 1498 + const SQChar* errorString = "unknown error"; 1499 + sq_getstring(vm, -1, &errorString); 1500 + if (machine->data) 1501 + machine->data->error(machine->data->data, errorString); 1502 + sq_pop(vm, 3); // error string, error and root table 1503 + } 1504 + } 1505 + else sq_poptop(vm); 1506 + } 1507 + } 1508 + 1509 + static void callSquirrelScanline(tic_mem* tic, s32 row, void* data) 1510 + { 1511 + callSquirrelScanlineName(tic, row, data, SCN_FN); 1512 + 1513 + // try to call old scanline 1514 + callSquirrelScanlineName(tic, row, data, "scanline"); 1515 + } 1516 + 1517 + static void callSquirrelOverline(tic_mem* tic, void* data) 1518 + { 1519 + tic_machine* machine = (tic_machine*)tic; 1520 + HSQUIRRELVM vm = machine->squirrel; 1521 + 1522 + if (vm) 1523 + { 1524 + const char* OvrFunc = OVR_FN; 1525 + 1526 + sq_pushroottable(vm); 1527 + sq_pushstring(vm, OvrFunc, -1); 1528 + 1529 + if(SQ_SUCCEEDED(sq_get(vm, -2))) 1530 + { 1531 + sq_pushroottable(vm); 1532 + if(SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue))) 1533 + { 1534 + sq_getlasterror(vm); 1535 + sq_tostring(vm, -1); 1536 + const SQChar* errorString = "unknown error"; 1537 + sq_getstring(vm, -1, &errorString); 1538 + if (machine->data) 1539 + machine->data->error(machine->data->data, errorString); 1540 + sq_pop(vm, 3); 1541 + } 1542 + } 1543 + else sq_poptop(vm); 1544 + } 1545 + 1546 + } 1547 + 1548 + static const char* const SquirrelKeywords [] = 1549 + { 1550 + "base", "break", "case", "catch", "class", "clone", 1551 + "continue", "const", "default", "delete", "else", "enum", 1552 + "extends", "for", "foreach", "function", "if", "in", 1553 + "local", "null", "resume", "return", "switch", "this", 1554 + "throw", "try", "typeof", "while", "yield", "constructor", 1555 + "instanceof", "true", "false", "static", "__LINE__", "__FILE__" 1556 + }; 1557 + 1558 + static inline bool isalnum_(char c) {return isalnum(c) || c == '_';} 1559 + 1560 + static const tic_outline_item* getSquirrelOutline(const char* code, s32* size) 1561 + { 1562 + enum{Size = sizeof(tic_outline_item)}; 1563 + 1564 + *size = 0; 1565 + 1566 + static tic_outline_item* items = NULL; 1567 + 1568 + if(items) 1569 + { 1570 + free(items); 1571 + items = NULL; 1572 + } 1573 + 1574 + const char* ptr = code; 1575 + 1576 + while(true) 1577 + { 1578 + static const char FuncString[] = "function "; 1579 + 1580 + ptr = strstr(ptr, FuncString); 1581 + 1582 + if(ptr) 1583 + { 1584 + ptr += sizeof FuncString - 1; 1585 + 1586 + const char* start = ptr; 1587 + const char* end = start; 1588 + 1589 + while(*ptr) 1590 + { 1591 + char c = *ptr; 1592 + 1593 + if(isalnum_(c) || c == ':'); 1594 + else if(c == '(') 1595 + { 1596 + end = ptr; 1597 + break; 1598 + } 1599 + else break; 1600 + 1601 + ptr++; 1602 + } 1603 + 1604 + if(end > start) 1605 + { 1606 + items = realloc(items, (*size + 1) * Size); 1607 + 1608 + items[*size].pos = start; 1609 + items[*size].size = (s32)(end - start); 1610 + 1611 + (*size)++; 1612 + } 1613 + } 1614 + else break; 1615 + } 1616 + 1617 + return items; 1618 + } 1619 + 1620 + void evalSquirrel(tic_mem* tic, const char* code) { 1621 + tic_machine* machine = (tic_machine*)tic; 1622 + HSQUIRRELVM vm = machine->squirrel; 1623 + 1624 + // make sure that the Squirrel interpreter is initialized. 1625 + if (vm == NULL) 1626 + { 1627 + if (!initSquirrel(tic, "")) 1628 + return; 1629 + vm = machine->squirrel; 1630 + } 1631 + 1632 + sq_settop(vm, 0); 1633 + 1634 + if((SQ_FAILED(sq_compilebuffer(vm, code, strlen(code), "squirrel", SQTrue))) || 1635 + (sq_pushroottable(vm), false) || 1636 + (SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue)))) 1637 + { 1638 + sq_getlasterror(vm); 1639 + sq_tostring(vm, -1); 1640 + const SQChar* errorString = "unknown error"; 1641 + sq_getstring(vm, -1, &errorString); 1642 + if (machine->data) 1643 + machine->data->error(machine->data->data, errorString); 1644 + } 1645 + 1646 + sq_settop(vm, 0); 1647 + } 1648 + 1649 + static const tic_script_config SquirrelSyntaxConfig = 1650 + { 1651 + .init = initSquirrel, 1652 + .close = closeSquirrel, 1653 + .tick = callSquirrelTick, 1654 + .scanline = callSquirrelScanline, 1655 + .overline = callSquirrelOverline, 1656 + 1657 + .getOutline = getSquirrelOutline, 1658 + .eval = evalSquirrel, 1659 + 1660 + .blockCommentStart = "/*", 1661 + .blockCommentEnd = "*/", 1662 + .blockCommentStart2 = NULL, 1663 + .blockCommentEnd2 = NULL, 1664 + .singleComment = "//", 1665 + .blockStringStart = "@\"", 1666 + .blockStringEnd = "\"", 1667 + 1668 + .keywords = SquirrelKeywords, 1669 + .keywordsCount = COUNT_OF(SquirrelKeywords), 1670 + }; 1671 + 1672 + const tic_script_config* getSquirrelScriptConfig() 1673 + { 1674 + return &SquirrelSyntaxConfig; 1675 + } 1676 + 1677 + #endif /* defined(TIC_BUILD_WITH_SQUIRREL) */
src/start.c src/studio/start.c
src/start.h src/studio/start.h
+2 -2
src/studio.c src/studio/studio.c
··· 30 30 #include "world.h" 31 31 #include "sfx.h" 32 32 #include "music.h" 33 - #include "history.h" 33 + #include "ext/history.h" 34 34 #include "config.h" 35 35 #include "code.h" 36 36 #include "dialog.h" 37 37 #include "menu.h" 38 38 #include "surf.h" 39 - #include "project.h" 39 + #include "studio/project.h" 40 40 41 41 #include "fs.h" 42 42
+2 -2
src/studio.h src/studio/studio.h
··· 28 28 #include <stdlib.h> 29 29 #include <stddef.h> 30 30 31 - #include "tic.h" 32 - #include "ticapi.h" 31 + #include "core/tic.h" 32 + #include "api.h" 33 33 #include "defines.h" 34 34 #include "tools.h" 35 35 #include "ext/file_dialog.h"
+1 -1
src/surf.c src/studio/surf.c
··· 23 23 #include "surf.h" 24 24 #include "fs.h" 25 25 #include "console.h" 26 - #include "project.h" 26 + #include "studio/project.h" 27 27 28 28 #include "ext/gif.h" 29 29
src/surf.h src/studio/surf.h
+1 -1
src/system.h
··· 1 1 #pragma once 2 2 3 - #include "ticapi.h" 3 + #include "api.h" 4 4 #include "ext/file_dialog.h" 5 5 #include "version.h" 6 6
+2 -2
src/system/libretro/tic80_libretro.c
··· 4 4 #include <stdarg.h> 5 5 #include <string.h> 6 6 #include <math.h> 7 - #include <tic.h> 7 + #include "core/tic.h" 8 8 #include "libretro-common/include/libretro.h" 9 9 #include "libretro_core_options.h" 10 - #include "../../ticapi.h" 10 + #include "api.h" 11 11 12 12 /** 13 13 * system.h is used for:
+2 -2
src/system/n3ds/keyboard.h
··· 22 22 23 23 #pragma once 24 24 25 - #include "tic.h" 26 - #include "ticapi.h" 25 + #include "core/tic.h" 26 + #include "api.h" 27 27 28 28 #include <3ds.h> 29 29 #include <citro3d.h>
+2 -2
src/system/n3ds/net_httpc.h
··· 22 22 23 23 #pragma once 24 24 25 - #include "tic.h" 26 - #include "ticapi.h" 25 + #include "core/tic.h" 26 + #include "api.h" 27 27 28 28 #include <3ds.h> 29 29
+1 -1
src/system/sdlgpu.c
··· 22 22 23 23 #include "system.h" 24 24 #include "tools.h" 25 - #include "net.h" 25 + #include "ext/net.h" 26 26 27 27 #include <stdlib.h> 28 28 #include <stdio.h>
+2 -2
src/tic.c src/core/tic.c
··· 32 32 #include <3ds.h> 33 33 #endif 34 34 35 - #include "ticapi.h" 35 + #include "api.h" 36 36 #include "tools.h" 37 37 #include "tilesheet.h" 38 38 #include "machine.h" 39 39 #include "ext/gif.h" 40 - #include "cart.h" 40 + #include "core/cart.h" 41 41 42 42 #define CLOCKRATE (255<<13) 43 43 #define ENVELOPE_FREQ_SCALE 2
src/tic.h src/core/tic.h
+2 -2
src/tic80.c src/core/tic80.c
··· 24 24 #include <string.h> 25 25 26 26 #include <tic80.h> 27 - #include "ticapi.h" 27 + #include "api.h" 28 28 #include "tools.h" 29 - #include "cart.h" 29 + #include "core/cart.h" 30 30 31 31 #include "ext/gif.h" 32 32
+1 -1
src/ticapi.h src/api.h
··· 22 22 23 23 #pragma once 24 24 25 - #include "tic.h" 25 + #include "core/tic.h" 26 26 27 27 typedef struct { u8 index; tic_flip flip; tic_rotate rotate; } RemapResult; 28 28 typedef void(*RemapFunc)(void*, s32 x, s32 y, RemapResult* result);
src/tilesheet.c src/core/tilesheet.c
src/tilesheet.h src/core/tilesheet.h
+1 -1
src/tools.h
··· 22 22 23 23 #pragma once 24 24 25 - #include "tic.h" 25 + #include "core/tic.h" 26 26 #include "ext/gif.h" 27 27 #include <stddef.h> 28 28
src/world.c src/studio/world.c
src/world.h src/studio/world.h
+1 -1
src/wrenapi.c src/api/wren.c
··· 20 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 21 // SOFTWARE. 22 22 23 - #include "machine.h" 23 + #include "core/machine.h" 24 24 25 25 #if defined(TIC_BUILD_WITH_WREN) 26 26
+1 -1
tic80.sublime-project
··· 3 3 [ 4 4 { 5 5 "name": "build", 6 - "shell_cmd": "cd ${project_path}/build && cmake -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel .. && ninja", 6 + "shell_cmd": "cd ${project_path}/build && cmake -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel ${project_path} && ninja", 7 7 "file_regex": "/([^/:]+):(\\d+):(\\d+): ", 8 8 "variants": [ 9 9 {