this repo has no description
0
fork

Configure Feed

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

#2257: deploy scripts as shared libs

nesbox 3dfc2ed6 765b0927

+1935 -2091
+95 -264
.github/workflows/build.yml
··· 2 2 3 3 on: [push, pull_request] 4 4 5 - env: 6 - BUILD_TYPE: MinSizeRel 7 - 8 5 jobs: 9 6 # === Windows XP === 10 7 winxp: 11 8 runs-on: windows-2019 12 9 13 10 steps: 14 - - uses: actions/checkout@v3 11 + - uses: actions/checkout@v4 15 12 with: 16 13 submodules: recursive 17 14 fetch-depth: 0 ··· 25 22 run: | 26 23 COPY /Y build\janet\janetconf.h vendor\janet\src\conf\janetconf.h 27 24 cd build 28 - cmake -G "Visual Studio 16 2019" -A Win32 -T v141_xp -DCMAKE_BUILD_TYPE=%BUILD_TYPE% .. 29 - cmake --build . --config %BUILD_TYPE% --parallel 25 + cmake -G "Visual Studio 16 2019" -A Win32 -T v141_xp -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_WITH_ALL=ON .. 26 + cmake --build . --config MinSizeRel --parallel 30 27 31 28 - name: Deploy 32 - uses: actions/upload-artifact@v3 29 + uses: actions/upload-artifact@v4 33 30 with: 34 31 name: "tic80-winxp" 35 - path: build/bin/tic80.exe 32 + path: | 33 + build/bin/tic80.exe 34 + build/bin/*.dll 36 35 37 - # === Windows XP PRO === 38 - winxp-pro: 39 - runs-on: windows-2019 40 - 41 - steps: 42 - - uses: actions/checkout@v3 43 - with: 44 - submodules: recursive 45 - fetch-depth: 0 46 - 47 - - uses: ruby/setup-ruby@v1 48 - with: 49 - ruby-version: 2.6 50 - 51 - - name: Build 36 + - name: Build Pro 52 37 shell: cmd 53 38 run: | 54 39 COPY /Y build\janet\janetconf.h vendor\janet\src\conf\janetconf.h 55 40 cd build 56 - cmake -G "Visual Studio 16 2019" -A Win32 -T v141_xp -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DBUILD_PRO=On .. 57 - cmake --build . --config %BUILD_TYPE% --parallel 41 + cmake -G "Visual Studio 16 2019" -A Win32 -T v141_xp -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_PRO=On -DBUILD_WITH_ALL=ON .. 42 + cmake --build . --config MinSizeRel --parallel 58 43 59 44 # === Windows === 60 45 windows: 61 46 runs-on: windows-2019 62 47 63 48 steps: 64 - - uses: actions/checkout@v3 49 + - uses: actions/checkout@v4 65 50 with: 66 51 submodules: recursive 67 52 fetch-depth: 0 ··· 74 59 shell: cmd 75 60 run: | 76 61 cd build 77 - cmake -G "Visual Studio 16 2019" -DBUILD_SDLGPU=On -DCMAKE_BUILD_TYPE=%BUILD_TYPE% .. 78 - cmake --build . --config %BUILD_TYPE% --parallel 62 + cmake -G "Visual Studio 16 2019" -DBUILD_SDLGPU=On -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_WITH_ALL=ON .. 63 + cmake --build . --config MinSizeRel --parallel 79 64 80 65 - name: Deploy 81 - uses: actions/upload-artifact@v3 66 + uses: actions/upload-artifact@v4 82 67 with: 83 68 name: "tic80-windows" 84 - path: build/bin/tic80.exe 85 - 86 - # === Windows PRO === 87 - windows-pro: 88 - runs-on: windows-2019 69 + path: | 70 + build/bin/tic80.exe 71 + build/bin/*.dll 89 72 90 - steps: 91 - - uses: actions/checkout@v3 92 - with: 93 - submodules: recursive 94 - fetch-depth: 0 95 - 96 - - uses: ruby/setup-ruby@v1 97 - with: 98 - ruby-version: 2.6 99 - 100 - - name: Build 73 + - name: Build Pro 101 74 shell: cmd 102 75 run: | 103 76 cd build 104 - cmake -G "Visual Studio 16 2019" -DBUILD_SDLGPU=On -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DBUILD_PRO=On .. 105 - cmake --build . --config %BUILD_TYPE% --parallel 106 - 107 - # === Windows Sokol === 108 - windows-sokol: 109 - runs-on: windows-2019 110 - 111 - steps: 112 - - uses: actions/checkout@v3 113 - with: 114 - submodules: recursive 115 - fetch-depth: 0 116 - 117 - - uses: ruby/setup-ruby@v1 118 - with: 119 - ruby-version: 2.6 120 - 121 - - name: Build 122 - shell: cmd 123 - run: | 124 - cd build 125 - cmake -G "Visual Studio 16 2019" -DBUILD_SDL=Off -DBUILD_SOKOL=On -DCMAKE_BUILD_TYPE=%BUILD_TYPE% .. 126 - cmake --build . --config %BUILD_TYPE% --parallel 127 - cp bin/tic80-sokol.exe bin/tic80.exe 128 - 129 - - name: Deploy 130 - uses: actions/upload-artifact@v3 131 - with: 132 - name: "tic80-windows-sokol" 133 - path: build/bin/tic80.exe 77 + cmake -G "Visual Studio 16 2019" -DBUILD_SDLGPU=On -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_PRO=On -DBUILD_WITH_ALL=ON .. 78 + cmake --build . --config MinSizeRel --parallel 134 79 135 80 # === Windows MinGW-64 === 136 81 windows-mingw: 137 - runs-on: windows-2019 82 + runs-on: windows-latest 83 + defaults: 84 + run: 85 + shell: msys2 {0} 138 86 139 87 steps: 140 - # https://github.com/actions/runner-images/issues/2642#issuecomment-774988591 141 - - name: configure Pagefile 142 - uses: al-cheb/configure-pagefile-action@v1.2 88 + - name: Setup Mingw 89 + uses: msys2/setup-msys2@v2 143 90 with: 144 - minimum-size: 16GB 145 - maximum-size: 16GB 146 - disk-root: "C:" 147 - 91 + msystem: UCRT64 92 + update: true 93 + install: >- 94 + base-devel 95 + git 96 + gcc 97 + 148 98 - uses: ruby/setup-ruby@v1 149 99 with: 150 100 ruby-version: 2.6 151 101 152 - - uses: actions/checkout@v3 102 + - uses: actions/checkout@v4 153 103 with: 154 104 submodules: recursive 155 105 fetch-depth: 0 ··· 158 108 shell: bash 159 109 run: | 160 110 cd build 161 - cmake -G "MSYS Makefiles" -DCMAKE_C_COMPILER=C:/msys64/mingw64/bin/gcc.exe -DCMAKE_CXX_COMPILER=C:/msys64/mingw64/bin/c++.exe -DBUILD_SDLGPU=On -DCMAKE_BUILD_TYPE=%BUILD_TYPE% .. 162 - cmake --build . --config %BUILD_TYPE% --parallel 163 - 164 - - name: Deploy 165 - uses: actions/upload-artifact@v3 166 - with: 167 - name: "tic80-mingw" 168 - path: build/bin/tic80.exe 111 + cmake -G "MSYS Makefiles" -DBUILD_SDLGPU=On -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_WITH_ALL=ON -DBUILD_WITH_JANET=OFF .. 112 + cmake --build . --config MinSizeRel --parallel 169 113 170 - # === Ubuntu PRO === 171 - linux-pro: 114 + # === Ubuntu === 115 + linux: 172 116 runs-on: ubuntu-20.04 173 117 174 118 steps: 175 - - uses: actions/checkout@v3 119 + - uses: actions/checkout@v4 176 120 with: 177 121 submodules: recursive 178 122 fetch-depth: 0 ··· 189 133 - name: Build 190 134 run: | 191 135 cd build 192 - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_SDLGPU=On -DBUILD_PRO=On .. 193 - cmake --build . --config $BUILD_TYPE --parallel 194 - cpack 195 - 196 - # === Ubuntu === 197 - linux: 198 - runs-on: ubuntu-20.04 136 + cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SDLGPU=On -DBUILD_WITH_ALL=ON .. 137 + cmake --build . --config MinSizeRel --parallel 199 138 200 - steps: 201 - - uses: actions/checkout@v3 139 + - name: Deploy 140 + uses: actions/upload-artifact@v4 202 141 with: 203 - submodules: recursive 204 - fetch-depth: 0 142 + name: "tic80-linux" 143 + path: | 144 + build/bin/tic80 145 + build/bin/*.so 205 146 206 - - uses: ruby/setup-ruby@v1 207 - with: 208 - ruby-version: 2.6 209 - 210 - - name: Install 211 - run: | 212 - sudo apt-get update 213 - sudo apt-get install libglu1-mesa-dev libasound2-dev libpulse-dev libaudio-dev libsamplerate0-dev libcurl4-openssl-dev -y 214 - 215 - - name: Build 147 + - name: Build Pro 216 148 run: | 217 149 cd build 218 - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_SDLGPU=On .. 219 - cmake --build . --config $BUILD_TYPE --parallel 220 - cpack 221 - 222 - - name: Deploy DEB 223 - uses: actions/upload-artifact@v3 224 - with: 225 - name: "tic80-linux-deb" 226 - path: build/tic80.deb 227 - 228 - - name: Deploy ZIP 229 - uses: actions/upload-artifact@v3 230 - with: 231 - name: "tic80-linux" 232 - path: build/bin/tic80 150 + cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SDLGPU=On -DBUILD_PRO=On -DBUILD_WITH_ALL=ON .. 151 + cmake --build . --config MinSizeRel --parallel 233 152 234 153 # === Raspberry PI === 235 154 rpi: ··· 250 169 - name: Build 251 170 run: | 252 171 cd build 253 - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE=rpi/toolchain.cmake .. 254 - cmake --build . --config $BUILD_TYPE --parallel 255 - cpack 256 - 257 - - name: Deploy DEB 258 - uses: actions/upload-artifact@v3 259 - with: 260 - name: "tic80-rpi-deb" 261 - path: build/tic80.deb 172 + cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_TOOLCHAIN_FILE=rpi/toolchain.cmake -DBUILD_WITH_ALL=ON .. 173 + cmake --build . --config MinSizeRel --parallel 262 174 263 175 - name: Deploy 264 176 uses: actions/upload-artifact@v3 265 177 with: 266 178 name: "tic80-rpi" 267 - path: build/bin/tic80 179 + path: | 180 + build/bin/tic80 181 + build/bin/*.so 268 182 269 - # === Raspberry PI PRO === 270 - rpi-pro: 271 - runs-on: ubuntu-latest 272 - container: nesbox/rpi-tic80:latest 273 - 274 - steps: 275 - - uses: actions/checkout@v3 276 - with: 277 - submodules: recursive 278 - fetch-depth: 0 279 - 280 - - name: Install Host toolchain 281 - run: | 282 - apt-get update 283 - apt-get install --assume-yes build-essential ruby-full gcc-8-arm-linux-gnueabihf g++-8-arm-linux-gnueabihf 284 - 285 - - name: Build 183 + - name: Build Pro 286 184 run: | 287 185 cd build 288 - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_PRO=On -DCMAKE_TOOLCHAIN_FILE=rpi/toolchain.cmake .. 289 - cmake --build . --config $BUILD_TYPE --parallel 290 - cpack 186 + cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_PRO=On -DCMAKE_TOOLCHAIN_FILE=rpi/toolchain.cmake .. 187 + cmake --build . --config MinSizeRel --parallel 291 188 292 - # === Raspberry PI 1-3 Bare Metal === 189 + # === Raspberry PI 1-4 Bare Metal === 293 190 rpi-baremetal: 294 191 runs-on: ubuntu-latest 295 192 container: nesbox/baremetalpi-tic80:latest ··· 325 222 run: | 326 223 git apply build/baremetalpi/circle.patch 327 224 cd build 328 - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE=baremetalpi/toolchain.cmake .. 225 + cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_TOOLCHAIN_FILE=baremetalpi/toolchain.cmake -DBUILD_WITH_ALL=ON .. 329 226 make tic80studio -j$(nproc) 330 227 cd baremetalpi 331 228 make -j$(nproc) ··· 385 282 run: | 386 283 git apply build/baremetalpi/circle.patch 387 284 cd build 388 - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE=baremetalpi/toolchain.cmake .. 285 + cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_TOOLCHAIN_FILE=baremetalpi/toolchain.cmake -DBUILD_WITH_ALL=ON .. 389 286 make tic80studio -j$(nproc) 390 287 cd baremetalpi 391 288 make -j$(nproc) ··· 431 328 - name: Build 432 329 run: | 433 330 cd build 434 - cmake -DCMAKE_TOOLCHAIN_FILE=$DEVKITPRO/3ds.cmake -DN3DS=TRUE -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. 331 + cmake -DCMAKE_TOOLCHAIN_FILE=$DEVKITPRO/3ds.cmake -DN3DS=TRUE -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_WITH_ALL=ON .. 435 332 make -j$(nproc) 436 333 437 334 - name: Deploy ··· 445 342 runs-on: macos-12 446 343 447 344 steps: 448 - - uses: actions/checkout@v3 345 + - uses: actions/checkout@v4 449 346 with: 450 347 submodules: recursive 451 348 fetch-depth: 0 ··· 456 353 - name: Build 457 354 run: | 458 355 cd build 459 - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_SDLGPU=On .. 460 - cmake --build . --config $BUILD_TYPE --parallel 461 - cpack 462 - cp *.dmg tic80.dmg 463 - 464 - - name: Deploy DMG 465 - uses: actions/upload-artifact@v3 466 - with: 467 - name: "tic80-macos-dmg" 468 - path: build/tic80.dmg 356 + cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SDLGPU=On -DBUILD_WITH_ALL=ON .. 357 + cmake --build . --config MinSizeRel --parallel 469 358 470 359 - name: Deploy 471 - uses: actions/upload-artifact@v3 360 + uses: actions/upload-artifact@v4 472 361 with: 473 362 name: "tic80-macos" 474 - path: build/bin/tic80 363 + path: | 364 + build/bin/tic80 365 + build/bin/*.dylib 475 366 476 - # === MacOS 12 PRO === 477 - macos-pro: 478 - runs-on: macos-12 479 - 480 - steps: 481 - - uses: actions/checkout@v3 482 - with: 483 - submodules: recursive 484 - fetch-depth: 0 485 - 486 - - name: Install 487 - run: brew uninstall --ignore-dependencies libidn2 488 - 489 - - name: Build 367 + - name: Build Pro 490 368 run: | 491 369 cd build 492 - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_SDLGPU=On -DBUILD_PRO=On .. 493 - cmake --build . --config $BUILD_TYPE --parallel 494 - cpack 495 - cp *.dmg tic80.dmg 370 + cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SDLGPU=On -DBUILD_PRO=On -DBUILD_WITH_ALL=ON .. 371 + cmake --build . --config MinSizeRel --parallel 496 372 497 - # === MacOS 14 / arm64 === 373 + # === MacOS 14 / arm64 === 498 374 macos-arm64: 499 375 runs-on: macos-14 500 376 501 377 steps: 502 - - uses: actions/checkout@v3 378 + - uses: actions/checkout@v4 503 379 with: 504 380 submodules: recursive 505 381 fetch-depth: 0 ··· 510 386 - name: Build 511 387 run: | 512 388 cd build 513 - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_SDLGPU=On .. 514 - cmake --build . --config $BUILD_TYPE --parallel 515 - cpack 516 - cp *.dmg tic80.dmg 517 - 518 - - name: Deploy DMG 519 - uses: actions/upload-artifact@v3 520 - with: 521 - name: "tic80-macos-arm64-dmg" 522 - path: build/tic80.dmg 389 + cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SDLGPU=On -DBUILD_WITH_ALL=ON .. 390 + cmake --build . --config MinSizeRel --parallel 523 391 524 392 - name: Deploy 525 - uses: actions/upload-artifact@v3 393 + uses: actions/upload-artifact@v4 526 394 with: 527 395 name: "tic80-macos-arm64" 528 - path: build/bin/tic80 396 + path: | 397 + build/bin/tic80 398 + build/bin/*.dylib 529 399 530 - # === MacOS 14 / arm64 PRO === 531 - macos-arm64-pro: 532 - runs-on: macos-14 533 - 534 - steps: 535 - - uses: actions/checkout@v3 536 - with: 537 - submodules: recursive 538 - fetch-depth: 0 539 - 540 - - name: Install 541 - run: brew uninstall --ignore-dependencies libidn2 542 - 543 - - name: Build 400 + - name: Build Pro 544 401 run: | 545 402 cd build 546 - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_SDLGPU=On -DBUILD_PRO=On .. 547 - cmake --build . --config $BUILD_TYPE --parallel 548 - cpack 549 - cp *.dmg tic80.dmg 403 + cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SDLGPU=On -DBUILD_PRO=On -DBUILD_WITH_ALL=ON .. 404 + cmake --build . --config MinSizeRel --parallel 550 405 551 406 # === Android === 552 407 android: 553 408 runs-on: ubuntu-latest 554 409 555 410 steps: 556 - - uses: actions/checkout@v3 411 + - uses: actions/checkout@v4 557 412 with: 558 413 submodules: recursive 559 414 fetch-depth: 0 ··· 566 421 local-cache: true 567 422 568 423 - name: set up JDK 11 569 - uses: actions/setup-java@v3 424 + uses: actions/setup-java@v4 570 425 with: 571 426 java-version: '11' 572 427 distribution: 'temurin' ··· 583 438 ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} 584 439 585 440 - name: Deploy 586 - uses: actions/upload-artifact@v3 441 + uses: actions/upload-artifact@v4 587 442 with: 588 443 name: "tic80-android" 589 444 path: build/android/tic80.apk ··· 593 448 runs-on: ubuntu-latest 594 449 595 450 steps: 596 - - uses: mymindstorm/setup-emsdk@v11 451 + - uses: mymindstorm/setup-emsdk@v14 597 452 598 - - uses: actions/checkout@v3 453 + - uses: actions/checkout@v4 599 454 with: 600 455 submodules: recursive 601 456 fetch-depth: 0 ··· 607 462 - name: Build 608 463 run: | 609 464 cd build 610 - emcmake cmake -DBUILD_SDLGPU=On -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. 611 - cmake --build . --config $BUILD_TYPE --parallel 612 - mkdir bin/html bin/html-export 613 - cp html/export.html bin/html-export/index.html 614 - cp bin/tic80*.js bin/html-export/ 615 - cp bin/tic80*.wasm bin/html-export/ 616 - cp html/index.html bin/html/index.html 617 - cp html/export.html bin/html/export.html 618 - cp bin/tic80.js bin/html/tic80.js 619 - cp bin/tic80.wasm bin/html/tic80.wasm 620 - cp bin/tic80.js webapp/tic80.js 621 - cp bin/tic80.wasm webapp/tic80.wasm 465 + emcmake cmake -DBUILD_SDLGPU=On -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_WITH_ALL=ON .. 466 + cmake --build . --config MinSizeRel --parallel 467 + cp html/index.html bin/index.html 622 468 623 469 - name: Deploy 624 - uses: actions/upload-artifact@v3 470 + uses: actions/upload-artifact@v4 625 471 with: 626 472 name: "tic80-html" 627 473 path: | 628 - build/bin/html/tic80.js 629 - build/bin/html/tic80.wasm 630 - build/bin/html/index.html 631 - build/bin/html/export.html 632 - 633 - - name: Deploy WebApp 634 - uses: actions/upload-artifact@v3 635 - with: 636 - name: "tic80-webapp" 637 - path: | 638 - build/webapp/index.html 639 - build/webapp/serviceworker.js 640 - build/webapp/tic80-180.png 641 - build/webapp/tic80-192.png 642 - build/webapp/tic80-512.png 643 - build/webapp/tic80.webmanifest 644 - build/webapp/tic80.js 645 - build/webapp/tic80.wasm 474 + build/bin/tic80.js 475 + build/bin/tic80.wasm 476 + build/bin/index.html
+10 -8
CMakeLists.txt
··· 14 14 15 15 configure_file("${PROJECT_SOURCE_DIR}/version.h.in" "${CMAKE_CURRENT_BINARY_DIR}/version.h") 16 16 17 - if(ANDROID OR EMSCRIPTEN OR N3DS OR RPI) 18 - set(BUILD_LIBRETRO_DEFAULT OFF) 19 - set(BUILD_PLAYER_DEFAULT OFF) 20 - set(BUILD_TOOLS OFF) 17 + if(ANDROID OR EMSCRIPTEN OR N3DS OR BAREMETALPI) 18 + set(BUILD_STATIC_DEFAULT ON) 21 19 else() 22 - set(BUILD_LIBRETRO_DEFAULT ON) 23 - set(BUILD_PLAYER_DEFAULT ON) 24 - set(BUILD_TOOLS ON) 20 + set(BUILD_STATIC_DEFAULT OFF) 25 21 endif() 26 22 23 + set(BUILD_PLAYER_DEFAULT OFF) 24 + set(BUILD_LIBRETRO_DEFAULT OFF) 27 25 set(BUILD_TOUCH_INPUT_DEFAULT ${ANDROID}) 26 + set(BUILD_TOOLS OFF) 27 + set(BUILD_WITH_ALL_DEFAULT OFF) 28 28 29 - option(BUILD_STATIC "Static runtime" ON) 29 + option(BUILD_STATIC "Static runtime" ${BUILD_STATIC_DEFAULT}) 30 + option(BUILD_WITH_ALL "Build all supported scripts" ${BUILD_WITH_ALL_DEFAULT}) 30 31 option(BUILD_SDL "SDL Enabled" ON) 31 32 option(BUILD_SDLGPU "SDL GPU Enabled" OFF) 32 33 option(BUILD_SOKOL "Sokol Enabled" OFF) ··· 66 67 message("BUILD_STATIC: ${BUILD_STATIC}") 67 68 message("BUILD_SDLGPU: ${BUILD_SDLGPU}") 68 69 message("BUILD_TOUCH_INPUT: ${BUILD_TOUCH_INPUT}") 70 + message("BUILD_WITH_ALL: ${BUILD_WITH_ALL}") 69 71 70 72 if (N3DS) 71 73 set(BUILD_SDL OFF)
+1 -1
build/android/app/build.gradle
··· 25 25 arguments "APP_PLATFORM=android-31" 26 26 } 27 27 cmake { 28 - arguments "-DBUILD_WITH_MRUBY=Off", "-DBUILD_PRO=Off", "-DCMAKE_BUILD_TYPE=MinSizeRel" 28 + arguments "-DBUILD_WITH_MRUBY=OFF", "-DBUILD_PRO=Off", "-DCMAKE_BUILD_TYPE=MinSizeRel", "-DBUILD_WITH_ALL=ON" 29 29 } 30 30 } 31 31 }
+1
build/baremetalpi/Makefile
··· 27 27 $(TIC80LIB)/libtic80core.a \ 28 28 $(TIC80LIB)/libgiflib.a \ 29 29 $(TIC80LIB)/liblpeg.a \ 30 + $(TIC80LIB)/libluaapi.a \ 30 31 $(TIC80LIB)/liblua.a \ 31 32 $(TIC80LIB)/libmoon.a \ 32 33 $(TIC80LIB)/libfennel.a \
+1 -1
cmake/core.cmake
··· 108 108 endif() 109 109 110 110 if(LINUX) 111 - target_link_libraries(tic80core PRIVATE m) 111 + target_link_libraries(tic80core PRIVATE m dl) 112 112 endif()
+4 -1
cmake/fennel.cmake
··· 2 2 # Fennel 3 3 ################################ 4 4 5 + option(BUILD_WITH_FENNEL "Fennel Enabled" ${BUILD_WITH_ALL}) 6 + message("BUILD_WITH_FENNEL: ${BUILD_WITH_FENNEL}") 7 + 5 8 if(BUILD_WITH_FENNEL) 6 9 7 10 add_library(fennel ${TIC_RUNTIME} ${CMAKE_SOURCE_DIR}/src/api/fennel.c) ··· 10 13 set_target_properties(fennel PROPERTIES PREFIX "") 11 14 endif() 12 15 13 - target_link_libraries(fennel PRIVATE lua runtime) 16 + target_link_libraries(fennel PRIVATE runtime luaapi) 14 17 target_include_directories(fennel 15 18 PRIVATE 16 19 ${THIRDPARTY_DIR}/fennel
+1 -3
cmake/janet.cmake
··· 2 2 # Janet 3 3 ################################ 4 4 5 - set(BUILD_WITH_JANET_DEFAULT TRUE) 6 - 7 - option(BUILD_WITH_JANET "Janet Enabled" ${BUILD_WITH_JANET_DEFAULT}) 5 + option(BUILD_WITH_JANET "Janet Enabled" ${BUILD_WITH_ALL}) 8 6 message("BUILD_WITH_JANET: ${BUILD_WITH_JANET}") 9 7 10 8 if(BUILD_WITH_JANET)
+17 -21
cmake/lua.cmake
··· 2 2 # LUA 3 3 ################################ 4 4 5 - set(BUILD_WITH_LUA_DEFAULT TRUE) 6 - set(BUILD_WITH_MOON_DEFAULT TRUE) 7 - set(BUILD_WITH_FENNEL_DEFAULT TRUE) 8 - 9 - option(BUILD_WITH_LUA "Lua Enabled" ${BUILD_WITH_LUA_DEFAULT}) 5 + option(BUILD_WITH_LUA "Lua Enabled" ON) 10 6 message("BUILD_WITH_LUA: ${BUILD_WITH_LUA}") 11 - 12 - option(BUILD_WITH_MOON "Moon Enabled" ${BUILD_WITH_MOON_DEFAULT}) 13 - message("BUILD_WITH_MOON: ${BUILD_WITH_MOON}") 14 - 15 - option(BUILD_WITH_FENNEL "Fennel Enabled" ${BUILD_WITH_FENNEL_DEFAULT}) 16 - message("BUILD_WITH_FENNEL: ${BUILD_WITH_FENNEL}") 17 - 18 - if(BUILD_WITH_MOON OR BUILD_WITH_FENNEL) 19 - set(BUILD_WITH_LUA TRUE) 20 - endif() 21 7 22 8 if(BUILD_WITH_LUA) 23 9 ··· 58 44 ${LUA_DIR}/lbitlib.c 59 45 ) 60 46 61 - list(APPEND LUA_SRC ${CMAKE_SOURCE_DIR}/src/api/lua.c) 62 - list(APPEND LUA_SRC ${CMAKE_SOURCE_DIR}/src/api/parse_note.c) 47 + add_library(luaapi STATIC 48 + ${LUA_SRC} 49 + ${CMAKE_SOURCE_DIR}/src/api/luaapi.c 50 + ${CMAKE_SOURCE_DIR}/src/api/parse_note.c 51 + ) 63 52 64 - add_library(lua ${TIC_RUNTIME} ${LUA_SRC}) 53 + add_library(lua ${TIC_RUNTIME} ${CMAKE_SOURCE_DIR}/src/api/lua.c) 65 54 66 55 if(NOT BUILD_STATIC) 67 56 set_target_properties(lua PROPERTIES PREFIX "") 68 57 endif() 69 58 70 - target_link_libraries(lua PRIVATE runtime) 59 + target_link_libraries(lua PRIVATE runtime luaapi) 71 60 72 - target_compile_definitions(lua PRIVATE LUA_COMPAT_5_2) 61 + target_compile_definitions(luaapi PRIVATE LUA_COMPAT_5_2) 62 + 63 + target_include_directories(luaapi 64 + PUBLIC ${THIRDPARTY_DIR}/lua 65 + ${CMAKE_SOURCE_DIR}/include 66 + ${CMAKE_SOURCE_DIR}/src 67 + ) 68 + 73 69 target_include_directories(lua 74 70 PUBLIC ${THIRDPARTY_DIR}/lua 75 71 PRIVATE ··· 78 74 ) 79 75 80 76 if(N3DS) 81 - target_compile_definitions(lua PUBLIC LUA_32BITS) 77 + target_compile_definitions(luaapi PUBLIC LUA_32BITS) 82 78 endif() 83 79 84 80 target_compile_definitions(lua INTERFACE TIC_BUILD_WITH_LUA)
+4 -1
cmake/moon.cmake
··· 2 2 # MoonScript 3 3 ################################ 4 4 5 + option(BUILD_WITH_MOON "Moon Enabled" ${BUILD_WITH_ALL}) 6 + message("BUILD_WITH_MOON: ${BUILD_WITH_MOON}") 7 + 5 8 if(BUILD_WITH_MOON) 6 9 7 10 set(LPEG_DIR ${THIRDPARTY_DIR}/lpeg) ··· 22 25 set_target_properties(moon PROPERTIES PREFIX "") 23 26 endif() 24 27 25 - target_link_libraries(moon PRIVATE lpeg lua runtime) 28 + target_link_libraries(moon PRIVATE lpeg runtime luaapi) 26 29 27 30 target_include_directories(moon 28 31 PRIVATE
+4 -8
cmake/mruby.cmake
··· 2 2 # MRUBY 3 3 ################################ 4 4 5 - find_program(RUBY ruby) 6 - find_program(RAKE rake) 7 - if(NOT RAKE) 8 - set(BUILD_WITH_MRUBY_DEFAULT FALSE) 9 - else() 10 - set(BUILD_WITH_MRUBY_DEFAULT TRUE) 11 - endif() 12 - option(BUILD_WITH_MRUBY "mruby Enabled" ${BUILD_WITH_MRUBY_DEFAULT}) 5 + option(BUILD_WITH_MRUBY "mruby Enabled" ${BUILD_WITH_ALL}) 13 6 message("BUILD_WITH_MRUBY: ${BUILD_WITH_MRUBY}") 14 7 15 8 if(BUILD_WITH_MRUBY) 9 + 10 + find_program(RUBY ruby) 11 + find_program(RAKE rake) 16 12 17 13 list(APPEND RUBY_SRC ${CMAKE_SOURCE_DIR}/src/api/mruby.c) 18 14 list(APPEND RUBY_SRC ${CMAKE_SOURCE_DIR}/src/api/parse_note.c)
+1 -1
cmake/naett.cmake
··· 22 22 target_link_libraries(naett INTERFACE winhttp) 23 23 elseif(LINUX) 24 24 target_include_directories(naett PRIVATE ${CURL_INCLUDE_DIRS}) 25 - target_link_libraries(naett ${CURL_LIBRARIES}) 25 + target_link_libraries(naett ${CURL_LIBRARIES} pthread) 26 26 elseif(APPLE) 27 27 target_link_libraries(naett 28 28 "-framework Cocoa")
+1 -3
cmake/pocketpy.cmake
··· 2 2 # pocketpy (Python) 3 3 ################################ 4 4 5 - set(BUILD_WITH_PYTHON_DEFAULT TRUE) 6 - 7 - option(BUILD_WITH_PYTHON "Python Enabled" ${BUILD_WITH_PYTHON_DEFAULT}) 5 + option(BUILD_WITH_PYTHON "Python Enabled" ${BUILD_WITH_ALL}) 8 6 message("BUILD_WITH_PYTHON: ${BUILD_WITH_PYTHON}") 9 7 10 8 if(BUILD_WITH_PYTHON)
+1 -3
cmake/quickjs.cmake
··· 2 2 # QuickJS 3 3 ################################ 4 4 5 - set(BUILD_WITH_JS_DEFAULT TRUE) 6 - 7 - option(BUILD_WITH_JS "JS Enabled" ${BUILD_WITH_JS_DEFAULT}) 5 + option(BUILD_WITH_JS "JS Enabled" ${BUILD_WITH_ALL}) 8 6 message("BUILD_WITH_JS: ${BUILD_WITH_JS}") 9 7 10 8 if(BUILD_WITH_JS)
+1 -3
cmake/scheme.cmake
··· 2 2 # SCHEME (S7) 3 3 ################################ 4 4 5 - set(BUILD_WITH_SCHEME_DEFAULT TRUE) 6 - 7 - option(BUILD_WITH_SCHEME "Scheme Enabled" ${BUILD_WITH_SCHEME_DEFAULT}) 5 + option(BUILD_WITH_SCHEME "Scheme Enabled" ${BUILD_WITH_ALL}) 8 6 message("BUILD_WITH_SCHEME: ${BUILD_WITH_SCHEME}") 9 7 10 8 if(BUILD_WITH_SCHEME)
+6 -18
cmake/sdl.cmake
··· 12 12 set(SDL_STATIC_PIC ON CACHE BOOL "" FORCE) 13 13 endif() 14 14 15 + set(SDL_SHARED OFF CACHE BOOL "" FORCE) 16 + 15 17 add_subdirectory(${THIRDPARTY_DIR}/sdl2) 16 18 17 19 endif() ··· 39 41 target_link_options(player-sdl PRIVATE -static) 40 42 endif() 41 43 42 - target_link_libraries(player-sdl PRIVATE tic80core SDL2main) 43 - 44 - if(BUILD_STATIC) 45 - target_link_libraries(player-sdl PRIVATE SDL2-static) 46 - else() 47 - target_link_libraries(player-sdl PRIVATE SDL2) 48 - endif() 44 + target_link_libraries(player-sdl PRIVATE tic80core SDL2main SDL2-static) 49 45 endif() 50 46 51 47 ################################ ··· 117 113 endif() 118 114 119 115 if(NOT EMSCRIPTEN) 120 - if(BUILD_STATIC) 121 - target_link_libraries(sdlgpu SDL2-static) 122 - else() 123 - target_link_libraries(sdlgpu SDL2) 124 - endif() 116 + target_link_libraries(sdlgpu SDL2-static) 125 117 endif() 126 118 127 119 endif() ··· 190 182 else() 191 183 if(EMSCRIPTEN) 192 184 elseif(RPI) 193 - target_link_libraries(tic80 libSDL2.a bcm_host) 185 + target_link_libraries(tic80 libSDL2.a bcm_host pthread) 194 186 else() 195 - if(BUILD_STATIC) 196 - target_link_libraries(tic80 SDL2-static) 197 - else() 198 - target_link_libraries(tic80 SDL2) 199 - endif() 187 + target_link_libraries(tic80 SDL2-static) 200 188 endif() 201 189 endif() 202 190
+1 -3
cmake/squirrel.cmake
··· 2 2 # SQUIRREL 3 3 ################################ 4 4 5 - set(BUILD_WITH_SQUIRREL_DEFAULT TRUE) 6 - 7 - option(BUILD_WITH_SQUIRREL "Squirrel Enabled" ${BUILD_WITH_SQUIRREL_DEFAULT}) 5 + option(BUILD_WITH_SQUIRREL "Squirrel Enabled" ${BUILD_WITH_ALL}) 8 6 message("BUILD_WITH_SQUIRREL: ${BUILD_WITH_SQUIRREL}") 9 7 10 8 if(BUILD_WITH_SQUIRREL)
+1 -3
cmake/wasm.cmake
··· 2 2 # WASM 3 3 ################################ 4 4 5 - set(BUILD_WITH_WASM_DEFAULT TRUE) 6 - 7 - option(BUILD_WITH_WASM "Wasm Enabled" ${BUILD_WITH_WASM_DEFAULT}) 5 + option(BUILD_WITH_WASM "Wasm Enabled" ${BUILD_WITH_ALL}) 8 6 message("BUILD_WITH_WASM: ${BUILD_WITH_WASM}") 9 7 10 8 if(BUILD_WITH_WASM)
+1 -3
cmake/wren.cmake
··· 2 2 # WREN 3 3 ################################ 4 4 5 - set(BUILD_WITH_WREN_DEFAULT TRUE) 6 - 7 - option(BUILD_WITH_WREN "WREN Enabled" ${BUILD_WITH_WREN_DEFAULT}) 5 + option(BUILD_WITH_WREN "WREN Enabled" ${BUILD_WITH_ALL}) 8 6 message("BUILD_WITH_WREN: ${BUILD_WITH_WREN}") 9 7 10 8 if(BUILD_WITH_WREN)
+13 -3
include/tic80_config.h
··· 37 37 # undef __TIC_WINDOWS__ 38 38 # define __TIC_WINDOWS__ 1 39 39 # define TIC_MODULE_EXT ".dll" 40 - # if defined(_MSC_VER) && defined(_USING_V110_SDK71_) 41 - # define __TIC_WIN7__ 1 42 - # endif 40 + # if defined(_MSC_VER) && defined(_USING_V110_SDK71_) 41 + # define __TIC_WIN7__ 1 42 + # endif 43 43 #endif 44 44 45 45 #if defined(ANDROID) || defined(__ANDROID__) ··· 50 50 # undef __TIC_LINUX__ 51 51 # define __TIC_LINUX__ 1 52 52 # define TIC_MODULE_EXT ".so" 53 + #endif 54 + 55 + #if defined(TIC_RUNTIME_STATIC) 56 + # define TIC_EXPORT 57 + #else 58 + # if defined(__TIC_WINDOWS__) 59 + # define TIC_EXPORT __declspec(dllexport) 60 + # elif defined(__GNUC__) && __GNUC__ >= 4 61 + # define TIC_EXPORT __attribute__ ((visibility("default"))) 62 + # endif 53 63 #endif 54 64 55 65 #ifndef TIC80_API
+11 -11
src/api/fennel.c
··· 21 21 // SOFTWARE. 22 22 23 23 #include "core/core.h" 24 - #include "lua_api.h" 24 + #include "luaapi.h" 25 25 26 26 #include "fennel.h" 27 27 ··· 41 41 static bool initFennel(tic_mem* tic, const char* code) 42 42 { 43 43 tic_core* core = (tic_core*)tic; 44 - closeLua(tic); 44 + luaapi_close(tic); 45 45 46 46 lua_State* lua = core->currentVM = luaL_newstate(); 47 - lua_open_builtins(lua); 47 + luaapi_open(lua); 48 48 49 - initLuaAPI(core); 49 + luaapi_init(core); 50 50 51 51 { 52 52 lua_State* fennel = core->currentVM; ··· 187 187 #include "../build/assets/fenneldemo.tic.dat" 188 188 }; 189 189 190 - const tic_script EXPORT_SCRIPT(Fennel) = 190 + TIC_EXPORT const tic_script EXPORT_SCRIPT(Fennel) = 191 191 { 192 192 .id = 14, 193 193 .name = "fennel", ··· 195 195 .projectComment = ";;", 196 196 { 197 197 .init = initFennel, 198 - .close = closeLua, 199 - .tick = callLuaTick, 200 - .boot = callLuaBoot, 198 + .close = luaapi_close, 199 + .tick = luaapi_tick, 200 + .boot = luaapi_boot, 201 201 202 202 .callback = 203 203 { 204 - .scanline = callLuaScanline, 205 - .border = callLuaBorder, 206 - .menu = callLuaMenu, 204 + .scanline = luaapi_scn, 205 + .border = luaapi_bdr, 206 + .menu = luaapi_menu, 207 207 }, 208 208 }, 209 209
+1 -1
src/api/janet.c
··· 1276 1276 #include "../build/assets/janetmark.tic.dat" 1277 1277 }; 1278 1278 1279 - JANET_API const tic_script EXPORT_SCRIPT(Janet) = 1279 + TIC_EXPORT const tic_script EXPORT_SCRIPT(Janet) = 1280 1280 { 1281 1281 .id = 18, 1282 1282 .name = "janet",
+1 -1
src/api/js.c
··· 1264 1264 #include "../build/assets/jsmark.tic.dat" 1265 1265 }; 1266 1266 1267 - const tic_script EXPORT_SCRIPT(Js) = 1267 + TIC_EXPORT const tic_script EXPORT_SCRIPT(Js) = 1268 1268 { 1269 1269 .id = 12, 1270 1270 .name = "js",
+13 -1702
src/api/lua.c
··· 21 21 // SOFTWARE. 22 22 23 23 #include "core/core.h" 24 + #include "luaapi.h" 24 25 25 26 #include <stdlib.h> 26 27 #include <lua.h> ··· 28 29 #include <lualib.h> 29 30 #include <ctype.h> 30 31 31 - extern bool parse_note(const char* noteStr, s32* note, s32* octave); 32 - 33 - static inline s32 getLuaNumber(lua_State* lua, s32 index) 34 - { 35 - return (s32)lua_tonumber(lua, index); 36 - } 37 - 38 - static void registerLuaFunction(tic_core* core, lua_CFunction func, const char *name) 39 - { 40 - lua_pushlightuserdata(core->currentVM, core); 41 - lua_pushcclosure(core->currentVM, func, 1); 42 - lua_setglobal(core->currentVM, name); 43 - } 44 - 45 - static tic_core* getLuaCore(lua_State* lua) 46 - { 47 - tic_core* core = lua_touserdata(lua, lua_upvalueindex(1)); 48 - return core; 49 - } 50 - 51 - static s32 lua_peek(lua_State* lua) 52 - { 53 - s32 top = lua_gettop(lua); 54 - tic_core* core = getLuaCore(lua); 55 - tic_mem* tic = (tic_mem*)core; 56 - 57 - if(top >= 1) 58 - { 59 - s32 address = getLuaNumber(lua, 1); 60 - s32 bits = BITS_IN_BYTE; 61 - 62 - if(top == 2) 63 - bits = getLuaNumber(lua, 2); 64 - 65 - lua_pushinteger(lua, core->api.peek(tic, address, bits)); 66 - return 1; 67 - } 68 - else luaL_error(lua, "invalid parameters, peek(addr,bits)\n"); 69 - 70 - return 0; 71 - } 72 - 73 - static s32 lua_poke(lua_State* lua) 74 - { 75 - s32 top = lua_gettop(lua); 76 - tic_core* core = getLuaCore(lua); 77 - tic_mem* tic = (tic_mem*)core; 78 - 79 - if(top >= 2) 80 - { 81 - s32 address = getLuaNumber(lua, 1); 82 - u8 value = getLuaNumber(lua, 2); 83 - s32 bits = BITS_IN_BYTE; 84 - 85 - if(top == 3) 86 - bits = getLuaNumber(lua, 3); 87 - 88 - core->api.poke(tic, address, value, bits); 89 - } 90 - else luaL_error(lua, "invalid parameters, poke(addr,val,bits)\n"); 91 - 92 - return 0; 93 - } 94 - 95 - static s32 lua_peek1(lua_State* lua) 96 - { 97 - s32 top = lua_gettop(lua); 98 - tic_core* core = getLuaCore(lua); 99 - tic_mem* tic = (tic_mem*)core; 100 - 101 - if(top == 1) 102 - { 103 - s32 address = getLuaNumber(lua, 1); 104 - lua_pushinteger(lua, core->api.peek1(tic, address)); 105 - return 1; 106 - } 107 - else luaL_error(lua, "invalid parameters, peek1(addr)\n"); 108 - 109 - return 0; 110 - } 111 - 112 - static s32 lua_poke1(lua_State* lua) 113 - { 114 - s32 top = lua_gettop(lua); 115 - tic_core* core = getLuaCore(lua); 116 - tic_mem* tic = (tic_mem*)core; 117 - 118 - if(top == 2) 119 - { 120 - s32 address = getLuaNumber(lua, 1); 121 - u8 value = getLuaNumber(lua, 2); 122 - 123 - core->api.poke1(tic, address, value); 124 - } 125 - else luaL_error(lua, "invalid parameters, poke1(addr,val)\n"); 126 - 127 - return 0; 128 - } 129 - 130 - static s32 lua_peek2(lua_State* lua) 131 - { 132 - s32 top = lua_gettop(lua); 133 - tic_core* core = getLuaCore(lua); 134 - tic_mem* tic = (tic_mem*)core; 135 - 136 - if(top == 1) 137 - { 138 - s32 address = getLuaNumber(lua, 1); 139 - lua_pushinteger(lua, core->api.peek2(tic, address)); 140 - return 1; 141 - } 142 - else luaL_error(lua, "invalid parameters, peek2(addr)\n"); 143 - 144 - return 0; 145 - } 146 - 147 - static s32 lua_poke2(lua_State* lua) 148 - { 149 - s32 top = lua_gettop(lua); 150 - tic_core* core = getLuaCore(lua); 151 - tic_mem* tic = (tic_mem*)core; 152 - 153 - if(top == 2) 154 - { 155 - s32 address = getLuaNumber(lua, 1); 156 - u8 value = getLuaNumber(lua, 2); 157 - 158 - core->api.poke2(tic, address, value); 159 - } 160 - else luaL_error(lua, "invalid parameters, poke2(addr,val)\n"); 161 - 162 - return 0; 163 - } 164 - 165 - static s32 lua_peek4(lua_State* lua) 166 - { 167 - s32 top = lua_gettop(lua); 168 - tic_core* core = getLuaCore(lua); 169 - tic_mem* tic = (tic_mem*)core; 170 - 171 - if(top == 1) 172 - { 173 - s32 address = getLuaNumber(lua, 1); 174 - lua_pushinteger(lua, core->api.peek4(tic, address)); 175 - return 1; 176 - } 177 - else luaL_error(lua, "invalid parameters, peek4(addr)\n"); 178 - 179 - return 0; 180 - } 181 - 182 - static s32 lua_poke4(lua_State* lua) 183 - { 184 - s32 top = lua_gettop(lua); 185 - tic_core* core = getLuaCore(lua); 186 - tic_mem* tic = (tic_mem*)core; 187 - 188 - if(top == 2) 189 - { 190 - s32 address = getLuaNumber(lua, 1); 191 - u8 value = getLuaNumber(lua, 2); 192 - 193 - core->api.poke4(tic, address, value); 194 - } 195 - else luaL_error(lua, "invalid parameters, poke4(addr,val)\n"); 196 - 197 - return 0; 198 - } 199 - 200 - static s32 lua_cls(lua_State* lua) 201 - { 202 - s32 top = lua_gettop(lua); 203 - 204 - tic_core* core = getLuaCore(lua); 205 - tic_mem* tic = (tic_mem*)core; 206 - 207 - core->api.cls(tic, top == 1 ? getLuaNumber(lua, 1) : 0); 208 - 209 - return 0; 210 - } 211 - 212 - static s32 lua_pix(lua_State* lua) 213 - { 214 - s32 top = lua_gettop(lua); 215 - 216 - if(top >= 2) 217 - { 218 - s32 x = getLuaNumber(lua, 1); 219 - s32 y = getLuaNumber(lua, 2); 220 - 221 - tic_core* core = getLuaCore(lua); 222 - tic_mem* tic = (tic_mem*)core; 223 - 224 - if(top >= 3) 225 - { 226 - s32 color = getLuaNumber(lua, 3); 227 - core->api.pix(tic, x, y, color, false); 228 - } 229 - else 230 - { 231 - lua_pushinteger(lua, core->api.pix(tic, x, y, 0, true)); 232 - return 1; 233 - } 234 - 235 - } 236 - else luaL_error(lua, "invalid parameters, pix(x y [color])\n"); 237 - 238 - return 0; 239 - } 240 - 241 - static s32 lua_line(lua_State* lua) 242 - { 243 - s32 top = lua_gettop(lua); 244 - 245 - if(top == 5) 246 - { 247 - float x0 = lua_tonumber(lua, 1); 248 - float y0 = lua_tonumber(lua, 2); 249 - float x1 = lua_tonumber(lua, 3); 250 - float y1 = lua_tonumber(lua, 4); 251 - s32 color = getLuaNumber(lua, 5); 252 - 253 - tic_core* core = getLuaCore(lua); 254 - tic_mem* tic = (tic_mem*)core; 255 - 256 - core->api.line(tic, x0, y0, x1, y1, color); 257 - } 258 - else luaL_error(lua, "invalid parameters, line(x0,y0,x1,y1,color)\n"); 259 - 260 - return 0; 261 - } 262 - 263 - static s32 lua_rect(lua_State* lua) 264 - { 265 - s32 top = lua_gettop(lua); 266 - 267 - if(top == 5) 268 - { 269 - s32 x = getLuaNumber(lua, 1); 270 - s32 y = getLuaNumber(lua, 2); 271 - s32 w = getLuaNumber(lua, 3); 272 - s32 h = getLuaNumber(lua, 4); 273 - s32 color = getLuaNumber(lua, 5); 274 - 275 - tic_core* core = getLuaCore(lua); 276 - tic_mem* tic = (tic_mem*)core; 277 - 278 - core->api.rect(tic, x, y, w, h, color); 279 - } 280 - else luaL_error(lua, "invalid parameters, rect(x,y,w,h,color)\n"); 281 - 282 - return 0; 283 - } 284 - 285 - static s32 lua_rectb(lua_State* lua) 286 - { 287 - s32 top = lua_gettop(lua); 288 - 289 - if(top == 5) 290 - { 291 - s32 x = getLuaNumber(lua, 1); 292 - s32 y = getLuaNumber(lua, 2); 293 - s32 w = getLuaNumber(lua, 3); 294 - s32 h = getLuaNumber(lua, 4); 295 - s32 color = getLuaNumber(lua, 5); 296 - 297 - tic_core* core = getLuaCore(lua); 298 - tic_mem* tic = (tic_mem*)core; 299 - 300 - core->api.rectb(tic, x, y, w, h, color); 301 - } 302 - else luaL_error(lua, "invalid parameters, rectb(x,y,w,h,color)\n"); 303 - 304 - return 0; 305 - } 306 - 307 - static s32 lua_circ(lua_State* lua) 308 - { 309 - s32 top = lua_gettop(lua); 310 - 311 - if(top == 4) 312 - { 313 - tic_core* core = getLuaCore(lua); 314 - tic_mem* tic = (tic_mem*)core; 315 - 316 - s32 x = getLuaNumber(lua, 1); 317 - s32 y = getLuaNumber(lua, 2); 318 - s32 radius = getLuaNumber(lua, 3); 319 - s32 color = getLuaNumber(lua, 4); 320 - 321 - core->api.circ(tic, x, y, radius, color); 322 - } 323 - else luaL_error(lua, "invalid parameters, circ(x,y,radius,color)\n"); 324 - 325 - return 0; 326 - } 327 - 328 - static s32 lua_circb(lua_State* lua) 329 - { 330 - s32 top = lua_gettop(lua); 331 - 332 - if(top == 4) 333 - { 334 - tic_core* core = getLuaCore(lua); 335 - tic_mem* tic = (tic_mem*)core; 336 - 337 - s32 x = getLuaNumber(lua, 1); 338 - s32 y = getLuaNumber(lua, 2); 339 - s32 radius = getLuaNumber(lua, 3); 340 - s32 color = getLuaNumber(lua, 4); 341 - 342 - core->api.circb(tic, x, y, radius, color); 343 - } 344 - else luaL_error(lua, "invalid parameters, circb(x,y,radius,color)\n"); 345 - 346 - return 0; 347 - } 348 - 349 - static s32 lua_elli(lua_State* lua) 350 - { 351 - s32 top = lua_gettop(lua); 352 - 353 - if(top == 5) 354 - { 355 - tic_core* core = getLuaCore(lua); 356 - tic_mem* tic = (tic_mem*)core; 357 - 358 - s32 x = getLuaNumber(lua, 1); 359 - s32 y = getLuaNumber(lua, 2); 360 - s32 a = getLuaNumber(lua, 3); 361 - s32 b = getLuaNumber(lua, 4); 362 - s32 color = getLuaNumber(lua, 5); 363 - 364 - core->api.elli(tic, x, y, a, b, color); 365 - } 366 - else luaL_error(lua, "invalid parameters, elli(x,y,a,b,color)\n"); 367 - 368 - return 0; 369 - } 370 - 371 - static s32 lua_ellib(lua_State* lua) 372 - { 373 - s32 top = lua_gettop(lua); 374 - 375 - if(top == 5) 376 - { 377 - tic_core* core = getLuaCore(lua); 378 - tic_mem* tic = (tic_mem*)core; 379 - 380 - s32 x = getLuaNumber(lua, 1); 381 - s32 y = getLuaNumber(lua, 2); 382 - s32 a = getLuaNumber(lua, 3); 383 - s32 b = getLuaNumber(lua, 4); 384 - s32 color = getLuaNumber(lua, 5); 385 - 386 - core->api.ellib(tic, x, y, a, b, color); 387 - } 388 - else luaL_error(lua, "invalid parameters, ellib(x,y,a,b,color)\n"); 389 - 390 - return 0; 391 - } 392 - 393 - static s32 lua_tri(lua_State* lua) 394 - { 395 - s32 top = lua_gettop(lua); 396 - 397 - if(top == 7) 398 - { 399 - float pt[6]; 400 - 401 - for(s32 i = 0; i < COUNT_OF(pt); i++) 402 - pt[i] = lua_tonumber(lua, i+1); 403 - 404 - s32 color = getLuaNumber(lua, 7); 405 - 406 - tic_core* core = getLuaCore(lua); 407 - tic_mem* tic = (tic_mem*)core; 408 - 409 - core->api.tri(tic, pt[0], pt[1], pt[2], pt[3], pt[4], pt[5], color); 410 - } 411 - else luaL_error(lua, "invalid parameters, tri(x1,y1,x2,y2,x3,y3,color)\n"); 412 - 413 - return 0; 414 - } 415 - 416 - static s32 lua_trib(lua_State* lua) 417 - { 418 - s32 top = lua_gettop(lua); 419 - 420 - if(top == 7) 421 - { 422 - float pt[6]; 423 - 424 - for(s32 i = 0; i < COUNT_OF(pt); i++) 425 - pt[i] = lua_tonumber(lua, i+1); 426 - 427 - s32 color = getLuaNumber(lua, 7); 428 - 429 - tic_core* core = getLuaCore(lua); 430 - tic_mem* tic = (tic_mem*)core; 431 - 432 - core->api.trib(tic, pt[0], pt[1], pt[2], pt[3], pt[4], pt[5], color); 433 - } 434 - else luaL_error(lua, "invalid parameters, trib(x1,y1,x2,y2,x3,y3,color)\n"); 435 - 436 - return 0; 437 - } 438 - 439 - #if defined(BUILD_DEPRECATED) 440 - 441 - static s32 lua_textri(lua_State* lua) 442 - { 443 - s32 top = lua_gettop(lua); 444 - 445 - if (top >= 12) 446 - { 447 - float pt[12]; 448 - 449 - for (s32 i = 0; i < COUNT_OF(pt); i++) 450 - pt[i] = (float)lua_tonumber(lua, i + 1); 451 - 452 - tic_core* core = getLuaCore(lua); 453 - tic_mem* tic = (tic_mem*)core; 454 - static u8 colors[TIC_PALETTE_SIZE]; 455 - s32 count = 0; 456 - bool use_map = false; 457 - 458 - // check for use map 459 - if (top >= 13) 460 - use_map = lua_toboolean(lua, 13); 461 - 462 - // check for chroma 463 - if(top >= 14) 464 - { 465 - if(lua_istable(lua, 14)) 466 - { 467 - for(s32 i = 1; i <= TIC_PALETTE_SIZE; i++) 468 - { 469 - lua_rawgeti(lua, 14, i); 470 - if(lua_isnumber(lua, -1)) 471 - { 472 - colors[i-1] = getLuaNumber(lua, -1); 473 - count++; 474 - lua_pop(lua, 1); 475 - } 476 - else 477 - { 478 - lua_pop(lua, 1); 479 - break; 480 - } 481 - } 482 - } 483 - else 484 - { 485 - colors[0] = getLuaNumber(lua, 14); 486 - count = 1; 487 - } 488 - } 489 - 490 - core->api.textri(tic, 491 - pt[0], pt[1], // xy 1 492 - pt[2], pt[3], // xy 2 493 - pt[4], pt[5], // xy 3 494 - pt[6], pt[7], // uv 1 495 - pt[8], pt[9], // uv 2 496 - pt[10], pt[11], // uv 3 497 - use_map, // use map 498 - colors, count); // chroma 499 - } 500 - 501 - return 0; 502 - } 503 - 504 - #endif 505 - 506 - static s32 lua_ttri(lua_State* lua) 507 - { 508 - s32 top = lua_gettop(lua); 509 - 510 - if (top >= 12) 511 - { 512 - float pt[12]; 513 - 514 - for (s32 i = 0; i < COUNT_OF(pt); i++) 515 - pt[i] = (float)lua_tonumber(lua, i + 1); 516 - 517 - tic_core* core = getLuaCore(lua); 518 - tic_mem* tic = (tic_mem*)core; 519 - static u8 colors[TIC_PALETTE_SIZE]; 520 - s32 count = 0; 521 - tic_texture_src src = tic_tiles_texture; 522 - 523 - // check for texture src 524 - if (top >= 13) 525 - { 526 - src = lua_isboolean(lua, 13) 527 - ? (lua_toboolean(lua, 13) ? tic_map_texture : tic_tiles_texture) 528 - : lua_tointeger(lua, 13); 529 - } 530 - // check for chroma 531 - if(top >= 14) 532 - { 533 - if(lua_istable(lua, 14)) 534 - { 535 - for(s32 i = 1; i <= TIC_PALETTE_SIZE; i++) 536 - { 537 - lua_rawgeti(lua, 14, i); 538 - if(lua_isnumber(lua, -1)) 539 - { 540 - colors[i-1] = getLuaNumber(lua, -1); 541 - count++; 542 - lua_pop(lua, 1); 543 - } 544 - else 545 - { 546 - lua_pop(lua, 1); 547 - break; 548 - } 549 - } 550 - } 551 - else 552 - { 553 - colors[0] = getLuaNumber(lua, 14); 554 - count = 1; 555 - } 556 - } 557 - 558 - float z[3]; 559 - bool depth = false; 560 - 561 - if(top == 17) 562 - { 563 - for (s32 i = 0; i < COUNT_OF(z); i++) 564 - z[i] = (float)lua_tonumber(lua, i + 15); 565 - 566 - depth = true; 567 - } 568 - 569 - core->api.ttri(tic, pt[0], pt[1], // xy 1 570 - pt[2], pt[3], // xy 2 571 - pt[4], pt[5], // xy 3 572 - pt[6], pt[7], // uv 1 573 - pt[8], pt[9], // uv 2 574 - pt[10], pt[11], // uv 3 575 - src, // texture source 576 - colors, count, // chroma 577 - z[0], z[1], z[2], depth); // depth 578 - } 579 - else luaL_error(lua, "invalid parameters, ttri(x1,y1,x2,y2,x3,y3,u1,v1,u2,v2,u3,v3,[src=0],[chroma=off],[z1=0],[z2=0],[z3=0])\n"); 580 - return 0; 581 - } 582 - 583 - 584 - static s32 lua_clip(lua_State* lua) 585 - { 586 - s32 top = lua_gettop(lua); 587 - 588 - if(top == 0) 589 - { 590 - tic_core* core = getLuaCore(lua); 591 - tic_mem* tic = (tic_mem*)core; 592 - 593 - core->api.clip(tic, 0, 0, TIC80_WIDTH, TIC80_HEIGHT); 594 - } 595 - else if(top == 4) 596 - { 597 - s32 x = getLuaNumber(lua, 1); 598 - s32 y = getLuaNumber(lua, 2); 599 - s32 w = getLuaNumber(lua, 3); 600 - s32 h = getLuaNumber(lua, 4); 601 - 602 - tic_core* core = getLuaCore(lua); 603 - tic_mem* tic = (tic_mem*)core; 604 - 605 - core->api.clip((tic_mem*)getLuaCore(lua), x, y, w, h); 606 - } 607 - else luaL_error(lua, "invalid parameters, use clip(x,y,w,h) or clip()\n"); 608 - 609 - return 0; 610 - } 611 - 612 - static s32 lua_btnp(lua_State* lua) 613 - { 614 - tic_core* core = getLuaCore(lua); 615 - tic_mem* tic = (tic_mem*)core; 616 - 617 - s32 top = lua_gettop(lua); 618 - 619 - if (top == 0) 620 - { 621 - lua_pushinteger(lua, core->api.btnp(tic, -1, -1, -1)); 622 - } 623 - else if(top == 1) 624 - { 625 - s32 index = getLuaNumber(lua, 1) & 0x1f; 626 - 627 - lua_pushboolean(lua, core->api.btnp(tic, index, -1, -1)); 628 - } 629 - else if (top == 3) 630 - { 631 - s32 index = getLuaNumber(lua, 1) & 0x1f; 632 - u32 hold = getLuaNumber(lua, 2); 633 - u32 period = getLuaNumber(lua, 3); 634 - 635 - lua_pushboolean(lua, core->api.btnp(tic, index, hold, period)); 636 - } 637 - else 638 - { 639 - luaL_error(lua, "invalid params, btnp [ id [ hold period ] ]\n"); 640 - return 0; 641 - } 642 - 643 - return 1; 644 - } 645 - 646 - static s32 lua_btn(lua_State* lua) 647 - { 648 - tic_core* core = getLuaCore(lua); 649 - tic_mem* tic = (tic_mem*)core; 650 - 651 - s32 top = lua_gettop(lua); 652 - 653 - if (top == 0) 654 - { 655 - lua_pushinteger(lua, core->api.btn(tic, -1)); 656 - } 657 - else if (top == 1) 658 - { 659 - bool pressed = core->api.btn(tic, getLuaNumber(lua, 1) & 0x1f); 660 - lua_pushboolean(lua, pressed); 661 - } 662 - else 663 - { 664 - luaL_error(lua, "invalid params, btn [ id ]\n"); 665 - return 0; 666 - } 667 - 668 - return 1; 669 - } 670 - 671 - static s32 lua_spr(lua_State* lua) 672 - { 673 - s32 top = lua_gettop(lua); 674 - 675 - s32 index = 0; 676 - s32 x = 0; 677 - s32 y = 0; 678 - s32 w = 1; 679 - s32 h = 1; 680 - s32 scale = 1; 681 - tic_flip flip = tic_no_flip; 682 - tic_rotate rotate = tic_no_rotate; 683 - static u8 colors[TIC_PALETTE_SIZE]; 684 - s32 count = 0; 685 - 686 - if(top >= 1) 687 - { 688 - index = getLuaNumber(lua, 1); 689 - 690 - if(top >= 3) 691 - { 692 - x = getLuaNumber(lua, 2); 693 - y = getLuaNumber(lua, 3); 694 - 695 - if(top >= 4) 696 - { 697 - if(lua_istable(lua, 4)) 698 - { 699 - for(s32 i = 1; i <= TIC_PALETTE_SIZE; i++) 700 - { 701 - lua_rawgeti(lua, 4, i); 702 - if(lua_isnumber(lua, -1)) 703 - { 704 - colors[i-1] = getLuaNumber(lua, -1); 705 - count++; 706 - lua_pop(lua, 1); 707 - } 708 - else 709 - { 710 - lua_pop(lua, 1); 711 - break; 712 - } 713 - } 714 - } 715 - else 716 - { 717 - colors[0] = getLuaNumber(lua, 4); 718 - count = 1; 719 - } 720 - 721 - if(top >= 5) 722 - { 723 - scale = getLuaNumber(lua, 5); 724 - 725 - if(top >= 6) 726 - { 727 - flip = getLuaNumber(lua, 6); 728 - 729 - if(top >= 7) 730 - { 731 - rotate = getLuaNumber(lua, 7); 732 - 733 - if(top >= 9) 734 - { 735 - w = getLuaNumber(lua, 8); 736 - h = getLuaNumber(lua, 9); 737 - } 738 - } 739 - } 740 - } 741 - } 742 - } 743 - } 744 - 745 - tic_core* core = getLuaCore(lua); 746 - tic_mem* tic = (tic_mem*)core; 747 - 748 - core->api.spr(tic, index, x, y, w, h, colors, count, scale, flip, rotate); 749 - 750 - return 0; 751 - } 752 - 753 - static s32 lua_mget(lua_State* lua) 754 - { 755 - s32 top = lua_gettop(lua); 756 - 757 - if(top == 2) 758 - { 759 - s32 x = getLuaNumber(lua, 1); 760 - s32 y = getLuaNumber(lua, 2); 761 - 762 - tic_core* core = getLuaCore(lua); 763 - tic_mem* tic = (tic_mem*)core; 764 - 765 - u8 value = core->api.mget(tic, x, y); 766 - lua_pushinteger(lua, value); 767 - return 1; 768 - } 769 - else luaL_error(lua, "invalid params, mget(x,y)\n"); 770 - 771 - return 0; 772 - } 773 - 774 - static s32 lua_mset(lua_State* lua) 775 - { 776 - s32 top = lua_gettop(lua); 777 - 778 - if(top == 3) 779 - { 780 - s32 x = getLuaNumber(lua, 1); 781 - s32 y = getLuaNumber(lua, 2); 782 - u8 val = getLuaNumber(lua, 3); 783 - 784 - tic_core* core = getLuaCore(lua); 785 - tic_mem* tic = (tic_mem*)core; 786 - 787 - core->api.mset(tic, x, y, val); 788 - } 789 - else luaL_error(lua, "invalid params, mget(x,y)\n"); 790 - 791 - return 0; 792 - } 793 - 794 - typedef struct 795 - { 796 - lua_State* lua; 797 - s32 reg; 798 - } RemapData; 799 - 800 - static void remapCallback(void* data, s32 x, s32 y, RemapResult* result) 801 - { 802 - RemapData* remap = (RemapData*)data; 803 - lua_State* lua = remap->lua; 804 - 805 - lua_rawgeti(lua, LUA_REGISTRYINDEX, remap->reg); 806 - lua_pushinteger(lua, result->index); 807 - lua_pushinteger(lua, x); 808 - lua_pushinteger(lua, y); 809 - lua_pcall(lua, 3, 3, 0); 810 - 811 - result->index = getLuaNumber(lua, -3); 812 - result->flip = getLuaNumber(lua, -2); 813 - result->rotate = getLuaNumber(lua, -1); 814 - } 815 - 816 - static s32 lua_map(lua_State* lua) 817 - { 818 - s32 x = 0; 819 - s32 y = 0; 820 - s32 w = TIC_MAP_SCREEN_WIDTH; 821 - s32 h = TIC_MAP_SCREEN_HEIGHT; 822 - s32 sx = 0; 823 - s32 sy = 0; 824 - s32 scale = 1; 825 - static u8 colors[TIC_PALETTE_SIZE]; 826 - s32 count = 0; 827 - 828 - s32 top = lua_gettop(lua); 829 - 830 - if(top >= 2) 831 - { 832 - x = getLuaNumber(lua, 1); 833 - y = getLuaNumber(lua, 2); 834 - 835 - if(top >= 4) 836 - { 837 - w = getLuaNumber(lua, 3); 838 - h = getLuaNumber(lua, 4); 839 - 840 - if(top >= 6) 841 - { 842 - sx = getLuaNumber(lua, 5); 843 - sy = getLuaNumber(lua, 6); 844 - 845 - if(top >= 7) 846 - { 847 - if(lua_istable(lua, 7)) 848 - { 849 - for(s32 i = 1; i <= TIC_PALETTE_SIZE; i++) 850 - { 851 - lua_rawgeti(lua, 7, i); 852 - if(lua_isnumber(lua, -1)) 853 - { 854 - colors[i-1] = getLuaNumber(lua, -1); 855 - count++; 856 - lua_pop(lua, 1); 857 - } 858 - else 859 - { 860 - lua_pop(lua, 1); 861 - break; 862 - } 863 - } 864 - } 865 - else 866 - { 867 - colors[0] = getLuaNumber(lua, 7); 868 - count = 1; 869 - } 870 - 871 - if(top >= 8) 872 - { 873 - scale = getLuaNumber(lua, 8); 874 - 875 - if(top >= 9) 876 - { 877 - if (lua_isfunction(lua, 9)) 878 - { 879 - s32 remap = luaL_ref(lua, LUA_REGISTRYINDEX); 880 - 881 - RemapData data = {lua, remap}; 882 - 883 - tic_core* core = getLuaCore(lua); 884 - tic_mem* tic = (tic_mem*)core; 885 - 886 - core->api.map(tic, x, y, w, h, sx, sy, colors, count, scale, remapCallback, &data); 887 - 888 - luaL_unref(lua, LUA_REGISTRYINDEX, data.reg); 889 - 890 - return 0; 891 - } 892 - } 893 - } 894 - } 895 - } 896 - } 897 - } 898 - 899 - tic_core* core = getLuaCore(lua); 900 - tic_mem* tic = (tic_mem*)core; 901 - 902 - core->api.map((tic_mem*)getLuaCore(lua), x, y, w, h, sx, sy, colors, count, scale, NULL, NULL); 903 - 904 - return 0; 905 - } 906 - 907 - static s32 lua_music(lua_State* lua) 908 - { 909 - s32 top = lua_gettop(lua); 910 - tic_core* core = getLuaCore(lua); 911 - tic_mem* tic = (tic_mem*)core; 912 - 913 - if(top == 0) core->api.music(tic, -1, 0, 0, false, false, -1, -1); 914 - else if(top >= 1) 915 - { 916 - s32 track = getLuaNumber(lua, 1); 917 - 918 - if(track > MUSIC_TRACKS - 1) 919 - { 920 - luaL_error(lua, "invalid music track index"); 921 - return 0; 922 - } 923 - 924 - core->api.music(tic, -1, 0, 0, false, false, -1, -1); 925 - 926 - s32 frame = -1; 927 - s32 row = -1; 928 - bool loop = true; 929 - bool sustain = false; 930 - s32 tempo = -1; 931 - s32 speed = -1; 932 - 933 - if(top >= 2) 934 - { 935 - frame = getLuaNumber(lua, 2); 936 - 937 - if(top >= 3) 938 - { 939 - row = getLuaNumber(lua, 3); 940 - 941 - if(top >= 4) 942 - { 943 - loop = lua_toboolean(lua, 4); 944 - 945 - if (top >= 5) 946 - { 947 - sustain = lua_toboolean(lua, 5); 948 - 949 - if (top >= 6) 950 - { 951 - tempo = getLuaNumber(lua, 6); 952 - 953 - if (top >= 7) 954 - { 955 - speed = getLuaNumber(lua, 7); 956 - } 957 - } 958 - } 959 - 960 - } 961 - } 962 - } 963 - 964 - core->api.music(tic, track, frame, row, loop, sustain, tempo, speed); 965 - } 966 - else luaL_error(lua, "invalid params, use music(track)\n"); 967 - 968 - return 0; 969 - } 970 - 971 - static s32 lua_sfx(lua_State* lua) 972 - { 973 - s32 top = lua_gettop(lua); 974 - 975 - if(top >= 1) 976 - { 977 - tic_core* core = getLuaCore(lua); 978 - tic_mem* tic = (tic_mem*)core; 979 - 980 - s32 note = -1; 981 - s32 octave = -1; 982 - s32 duration = -1; 983 - s32 channel = 0; 984 - s32 volumes[TIC80_SAMPLE_CHANNELS] = {MAX_VOLUME, MAX_VOLUME}; 985 - s32 speed = SFX_DEF_SPEED; 986 - 987 - s32 index = getLuaNumber(lua, 1); 988 - 989 - if(index < SFX_COUNT) 990 - { 991 - if (index >= 0) 992 - { 993 - tic_sample* effect = tic->ram->sfx.samples.data + index; 994 - 995 - note = effect->note; 996 - octave = effect->octave; 997 - speed = effect->speed; 998 - } 999 - 1000 - if(top >= 2) 1001 - { 1002 - if(lua_isinteger(lua, 2)) 1003 - { 1004 - s32 id = getLuaNumber(lua, 2); 1005 - note = id % NOTES; 1006 - octave = id / NOTES; 1007 - } 1008 - else if(lua_isstring(lua, 2)) 1009 - { 1010 - const char* noteStr = lua_tostring(lua, 2); 1011 - 1012 - if(!parse_note(noteStr, &note, &octave)) 1013 - { 1014 - luaL_error(lua, "invalid note, should be like C#4\n"); 1015 - return 0; 1016 - } 1017 - } 1018 - 1019 - if(top >= 3) 1020 - { 1021 - duration = getLuaNumber(lua, 3); 1022 - 1023 - if(top >= 4) 1024 - { 1025 - channel = getLuaNumber(lua, 4); 1026 - 1027 - if(top >= 5) 1028 - { 1029 - if(lua_istable(lua, 5)) 1030 - { 1031 - for(s32 i = 0; i < COUNT_OF(volumes); i++) 1032 - { 1033 - volumes[i] = lua_rawgeti(lua, 5, i + 1); 1034 - lua_pop(lua, 1); 1035 - } 1036 - } 1037 - else volumes[0] = volumes[1] = getLuaNumber(lua, 5); 1038 - 1039 - if(top >= 6) 1040 - { 1041 - speed = getLuaNumber(lua, 6); 1042 - } 1043 - } 1044 - } 1045 - } 1046 - } 1047 - 1048 - if (channel >= 0 && channel < TIC_SOUND_CHANNELS) 1049 - { 1050 - core->api.sfx(tic, index, note, octave, duration, channel, volumes[0] & 0xf, volumes[1] & 0xf, speed); 1051 - } 1052 - else luaL_error(lua, "unknown channel\n"); 1053 - } 1054 - else luaL_error(lua, "unknown sfx index\n"); 1055 - } 1056 - else luaL_error(lua, "invalid sfx params\n"); 1057 - 1058 - return 0; 1059 - } 1060 - 1061 - static s32 lua_vbank(lua_State* lua) 1062 - { 1063 - tic_core* core = getLuaCore(lua); 1064 - tic_mem* tic = (tic_mem*)core; 1065 - 1066 - s32 prev = core->state.vbank.id; 1067 - 1068 - if(lua_gettop(lua) == 1) 1069 - core->api.vbank(tic, getLuaNumber(lua, 1)); 1070 - 1071 - lua_pushinteger(lua, prev); 1072 - return 1; 1073 - } 1074 - 1075 - static s32 lua_sync(lua_State* lua) 1076 - { 1077 - tic_core* core = getLuaCore(lua); 1078 - tic_mem* tic = (tic_mem*)core; 1079 - 1080 - bool toCart = false; 1081 - u32 mask = 0; 1082 - s32 bank = 0; 1083 - 1084 - if(lua_gettop(lua) >= 1) 1085 - { 1086 - mask = getLuaNumber(lua, 1); 1087 - 1088 - if(lua_gettop(lua) >= 2) 1089 - { 1090 - bank = getLuaNumber(lua, 2); 1091 - 1092 - if(lua_gettop(lua) >= 3) 1093 - { 1094 - toCart = lua_toboolean(lua, 3); 1095 - } 1096 - } 1097 - } 1098 - 1099 - if(bank >= 0 && bank < TIC_BANKS) 1100 - core->api.sync(tic, mask, bank, toCart); 1101 - else 1102 - luaL_error(lua, "sync() error, invalid bank"); 1103 - 1104 - return 0; 1105 - } 1106 - 1107 - static s32 lua_reset(lua_State* lua) 1108 - { 1109 - tic_core* core = getLuaCore(lua); 1110 - 1111 - core->state.initialized = false; 1112 - 1113 - return 0; 1114 - } 1115 - 1116 - static s32 lua_key(lua_State* lua) 1117 - { 1118 - tic_core* core = getLuaCore(lua); 1119 - tic_mem* tic = &core->memory; 1120 - 1121 - s32 top = lua_gettop(lua); 1122 - 1123 - if (top == 0) 1124 - { 1125 - lua_pushboolean(lua, core->api.key(tic, tic_key_unknown)); 1126 - } 1127 - else if (top == 1) 1128 - { 1129 - tic_key key = getLuaNumber(lua, 1); 1130 - 1131 - if(key < tic_keys_count) 1132 - lua_pushboolean(lua, core->api.key(tic, key)); 1133 - else 1134 - { 1135 - luaL_error(lua, "unknown keyboard code\n"); 1136 - return 0; 1137 - } 1138 - } 1139 - else 1140 - { 1141 - luaL_error(lua, "invalid params, key [code]\n"); 1142 - return 0; 1143 - } 1144 - 1145 - return 1; 1146 - } 1147 - 1148 - static s32 lua_keyp(lua_State* lua) 1149 - { 1150 - tic_core* core = getLuaCore(lua); 1151 - tic_mem* tic = &core->memory; 1152 - 1153 - s32 top = lua_gettop(lua); 1154 - 1155 - if (top == 0) 1156 - { 1157 - lua_pushboolean(lua, core->api.keyp(tic, tic_key_unknown, -1, -1)); 1158 - } 1159 - else 1160 - { 1161 - tic_key key = getLuaNumber(lua, 1); 1162 - 1163 - if(key >= tic_keys_count) 1164 - { 1165 - luaL_error(lua, "unknown keyboard code\n"); 1166 - } 1167 - else 1168 - { 1169 - if(top == 1) 1170 - { 1171 - lua_pushboolean(lua, core->api.keyp(tic, key, -1, -1)); 1172 - } 1173 - else if(top == 3) 1174 - { 1175 - u32 hold = getLuaNumber(lua, 2); 1176 - u32 period = getLuaNumber(lua, 3); 1177 - 1178 - lua_pushboolean(lua, core->api.keyp(tic, key, hold, period)); 1179 - } 1180 - else 1181 - { 1182 - luaL_error(lua, "invalid params, keyp [ code [ hold period ] ]\n"); 1183 - return 0; 1184 - } 1185 - } 1186 - } 1187 - 1188 - return 1; 1189 - } 1190 - 1191 - static s32 lua_memcpy(lua_State* lua) 1192 - { 1193 - s32 top = lua_gettop(lua); 1194 - 1195 - if(top == 3) 1196 - { 1197 - s32 dest = getLuaNumber(lua, 1); 1198 - s32 src = getLuaNumber(lua, 2); 1199 - s32 size = getLuaNumber(lua, 3); 1200 - 1201 - tic_core* core = getLuaCore(lua); 1202 - tic_mem* tic = (tic_mem*)core; 1203 - core->api.memcpy(tic, dest, src, size); 1204 - } 1205 - else luaL_error(lua, "invalid params, memcpy(dest,src,size)\n"); 1206 - 1207 - return 0; 1208 - } 1209 - 1210 - static s32 lua_memset(lua_State* lua) 1211 - { 1212 - s32 top = lua_gettop(lua); 1213 - 1214 - if(top == 3) 1215 - { 1216 - s32 dest = getLuaNumber(lua, 1); 1217 - u8 value = getLuaNumber(lua, 2); 1218 - s32 size = getLuaNumber(lua, 3); 1219 - 1220 - tic_core* core = getLuaCore(lua); 1221 - tic_mem* tic = (tic_mem*)core; 1222 - 1223 - core->api.memset(tic, dest, value, size); 1224 - } 1225 - else luaL_error(lua, "invalid params, memset(dest,val,size)\n"); 1226 - 1227 - return 0; 1228 - } 1229 - 1230 - static const char* printString(lua_State* lua, s32 index) 1231 - { 1232 - lua_getglobal(lua, "tostring"); 1233 - lua_pushvalue(lua, -1); 1234 - lua_pushvalue(lua, index); 1235 - lua_call(lua, 1, 1); 1236 - 1237 - const char* text = lua_tostring(lua, -1); 1238 - 1239 - lua_pop(lua, 2); 1240 - 1241 - return text; 1242 - } 1243 - 1244 - static s32 lua_font(lua_State* lua) 1245 - { 1246 - tic_core* core = getLuaCore(lua); 1247 - tic_mem* tic = (tic_mem*)core; 1248 - s32 top = lua_gettop(lua); 1249 - 1250 - if(top >= 1) 1251 - { 1252 - const char* text = printString(lua, 1); 1253 - s32 x = 0; 1254 - s32 y = 0; 1255 - s32 width = TIC_SPRITESIZE; 1256 - s32 height = TIC_SPRITESIZE; 1257 - u8 chromakey = 0; 1258 - bool fixed = false; 1259 - s32 scale = 1; 1260 - bool alt = false; 1261 - 1262 - if(top >= 3) 1263 - { 1264 - x = getLuaNumber(lua, 2); 1265 - y = getLuaNumber(lua, 3); 1266 - 1267 - if(top >= 4) 1268 - { 1269 - chromakey = getLuaNumber(lua, 4); 1270 - 1271 - if(top >= 6) 1272 - { 1273 - width = getLuaNumber(lua, 5); 1274 - height = getLuaNumber(lua, 6); 1275 - 1276 - if(top >= 7) 1277 - { 1278 - fixed = lua_toboolean(lua, 7); 1279 - 1280 - if(top >= 8) 1281 - { 1282 - scale = getLuaNumber(lua, 8); 1283 - 1284 - if(top >= 9) 1285 - { 1286 - alt = lua_toboolean(lua, 9); 1287 - } 1288 - } 1289 - } 1290 - } 1291 - } 1292 - } 1293 - 1294 - if(scale == 0) 1295 - { 1296 - lua_pushinteger(lua, 0); 1297 - return 1; 1298 - } 1299 - 1300 - s32 size = core->api.font(tic, text, x, y, &chromakey, 1, width, height, fixed, scale, alt); 1301 - 1302 - lua_pushinteger(lua, size); 1303 - 1304 - return 1; 1305 - } 1306 - 1307 - return 0; 1308 - } 1309 - 1310 - static s32 lua_print(lua_State* lua) 1311 - { 1312 - s32 top = lua_gettop(lua); 1313 - 1314 - if(top >= 1) 1315 - { 1316 - tic_core* core = getLuaCore(lua); 1317 - tic_mem* tic = (tic_mem*)core; 1318 - 1319 - s32 x = 0; 1320 - s32 y = 0; 1321 - s32 color = TIC_DEFAULT_COLOR; 1322 - bool fixed = false; 1323 - s32 scale = 1; 1324 - bool alt = false; 1325 - 1326 - const char* text = printString(lua, 1); 1327 - 1328 - if(top >= 3) 1329 - { 1330 - x = getLuaNumber(lua, 2); 1331 - y = getLuaNumber(lua, 3); 1332 - 1333 - if(top >= 4) 1334 - { 1335 - color = getLuaNumber(lua, 4) % TIC_PALETTE_SIZE; 1336 - 1337 - if(top >= 5) 1338 - { 1339 - fixed = lua_toboolean(lua, 5); 1340 - 1341 - if(top >= 6) 1342 - { 1343 - scale = getLuaNumber(lua, 6); 1344 - 1345 - if(top >= 7) 1346 - { 1347 - alt = lua_toboolean(lua, 7); 1348 - } 1349 - } 1350 - } 1351 - } 1352 - } 1353 - 1354 - if(scale == 0) 1355 - { 1356 - lua_pushinteger(lua, 0); 1357 - return 1; 1358 - } 1359 - 1360 - s32 size = core->api.print(tic, text ? text : "nil", x, y, color, fixed, scale, alt); 1361 - 1362 - lua_pushinteger(lua, size); 1363 - 1364 - return 1; 1365 - } 1366 - 1367 - return 0; 1368 - } 1369 - 1370 - static s32 lua_trace(lua_State *lua) 1371 - { 1372 - s32 top = lua_gettop(lua); 1373 - tic_core* core = getLuaCore(lua); 1374 - tic_mem* tic = (tic_mem*)core; 1375 - 1376 - if(top >= 1) 1377 - { 1378 - const char* text = printString(lua, 1); 1379 - u8 color = TIC_DEFAULT_COLOR; 1380 - 1381 - if(top >= 2) 1382 - { 1383 - color = getLuaNumber(lua, 2); 1384 - } 1385 - 1386 - core->api.trace(tic, text, color); 1387 - } 1388 - else luaL_error(lua, "invalid params, trace(text,[color])\n"); 1389 - 1390 - return 0; 1391 - } 1392 - 1393 - static s32 lua_pmem(lua_State *lua) 1394 - { 1395 - s32 top = lua_gettop(lua); 1396 - tic_core* core = getLuaCore(lua); 1397 - tic_mem* tic = &core->memory; 1398 - 1399 - if(top >= 1) 1400 - { 1401 - u32 index = getLuaNumber(lua, 1); 1402 - 1403 - if(index < TIC_PERSISTENT_SIZE) 1404 - { 1405 - u32 val = core->api.pmem(tic, index, 0, false); 1406 - 1407 - if(top >= 2) 1408 - { 1409 - core->api.pmem(tic, index, (u32)lua_tointeger(lua, 2), true); 1410 - } 1411 - 1412 - lua_pushinteger(lua, val); 1413 - 1414 - return 1; 1415 - } 1416 - 1417 - luaL_error(lua, "invalid persistent tic index\n"); 1418 - } 1419 - else luaL_error(lua, "invalid params, pmem(index [val]) -> val\n"); 1420 - 1421 - return 0; 1422 - } 1423 - 1424 - static s32 lua_time(lua_State *lua) 1425 - { 1426 - tic_core* core = getLuaCore(lua); 1427 - tic_mem* tic = (tic_mem*)core; 1428 - 1429 - lua_pushnumber(lua, core->api.time(tic)); 1430 - 1431 - return 1; 1432 - } 1433 - 1434 - static s32 lua_tstamp(lua_State *lua) 1435 - { 1436 - tic_core* core = getLuaCore(lua); 1437 - tic_mem* tic = (tic_mem*)core; 1438 - 1439 - lua_pushnumber(lua, core->api.tstamp(tic)); 1440 - 1441 - return 1; 1442 - } 1443 - 1444 - static s32 lua_exit(lua_State *lua) 1445 - { 1446 - tic_core* core = getLuaCore(lua); 1447 - tic_mem* tic = (tic_mem*)core; 1448 - 1449 - core->api.exit(tic); 1450 - 1451 - return 0; 1452 - } 1453 - 1454 - static s32 lua_mouse(lua_State *lua) 1455 - { 1456 - tic_core* core = getLuaCore(lua); 1457 - 1458 - { 1459 - tic_point pos = core->api.mouse((tic_mem*)core); 1460 - 1461 - lua_pushinteger(lua, pos.x); 1462 - lua_pushinteger(lua, pos.y); 1463 - } 1464 - 1465 - const tic80_mouse* mouse = &core->memory.ram->input.mouse; 1466 - 1467 - lua_pushboolean(lua, mouse->left); 1468 - lua_pushboolean(lua, mouse->middle); 1469 - lua_pushboolean(lua, mouse->right); 1470 - lua_pushinteger(lua, mouse->scrollx); 1471 - lua_pushinteger(lua, mouse->scrolly); 1472 - 1473 - return 7; 1474 - } 1475 - 1476 - static s32 lua_fget(lua_State* lua) 1477 - { 1478 - tic_core* core = getLuaCore(lua); 1479 - tic_mem* tic = (tic_mem*)core; 1480 - s32 top = lua_gettop(lua); 1481 - 1482 - if(top >= 1) 1483 - { 1484 - u32 index = getLuaNumber(lua, 1); 1485 - 1486 - if(top >= 2) 1487 - { 1488 - u32 flag = getLuaNumber(lua, 2); 1489 - lua_pushboolean(lua, core->api.fget(tic, index, flag)); 1490 - return 1; 1491 - } 1492 - } 1493 - 1494 - luaL_error(lua, "invalid params, fget(sprite,flag)\n"); 1495 - 1496 - return 0; 1497 - } 1498 - 1499 - static s32 lua_fset(lua_State* lua) 1500 - { 1501 - tic_core* core = getLuaCore(lua); 1502 - tic_mem* tic = (tic_mem*)core; 1503 - s32 top = lua_gettop(lua); 1504 - 1505 - if(top >= 1) 1506 - { 1507 - u32 index = getLuaNumber(lua, 1); 1508 - 1509 - if(top >= 2) 1510 - { 1511 - u32 flag = getLuaNumber(lua, 2); 1512 - 1513 - if(top >= 3) 1514 - { 1515 - bool value = lua_toboolean(lua, 3); 1516 - core->api.fset(tic, index, flag, value); 1517 - return 0; 1518 - } 1519 - } 1520 - } 1521 - 1522 - luaL_error(lua, "invalid params, fset(sprite,flag,value)\n"); 1523 - 1524 - return 0; 1525 - } 1526 - 1527 - static s32 lua_dofile(lua_State *lua) 1528 - { 1529 - luaL_error(lua, "unknown method: \"dofile\"\n"); 1530 - 1531 - return 0; 1532 - } 1533 - 1534 - static s32 lua_loadfile(lua_State *lua) 1535 - { 1536 - luaL_error(lua, "unknown method: \"loadfile\"\n"); 1537 - 1538 - return 0; 1539 - } 1540 - 1541 - void lua_open_builtins(lua_State *lua) 1542 - { 1543 - static const luaL_Reg loadedlibs[] = 1544 - { 1545 - { "_G", luaopen_base }, 1546 - { LUA_LOADLIBNAME, luaopen_package }, 1547 - { LUA_COLIBNAME, luaopen_coroutine }, 1548 - { LUA_TABLIBNAME, luaopen_table }, 1549 - { LUA_STRLIBNAME, luaopen_string }, 1550 - { LUA_MATHLIBNAME, luaopen_math }, 1551 - { LUA_DBLIBNAME, luaopen_debug }, 1552 - { NULL, NULL } 1553 - }; 1554 - 1555 - for (const luaL_Reg *lib = loadedlibs; lib->func; lib++) 1556 - { 1557 - luaL_requiref(lua, lib->name, lib->func, 1); 1558 - lua_pop(lua, 1); 1559 - } 1560 - } 1561 - 1562 - void initLuaAPI(tic_core* core) 1563 - { 1564 - static const struct{lua_CFunction func; const char* name;} ApiItems[] = 1565 - { 1566 - #define API_FUNC_DEF(name, ...) {lua_ ## name, #name}, 1567 - TIC_API_LIST(API_FUNC_DEF) 1568 - #undef API_FUNC_DEF 1569 - 1570 - #if defined(BUILD_DEPRECATED) 1571 - {lua_textri, "textri"}, 1572 - #endif 1573 - }; 1574 - 1575 - for (s32 i = 0; i < COUNT_OF(ApiItems); i++) 1576 - registerLuaFunction(core, ApiItems[i].func, ApiItems[i].name); 1577 - 1578 - registerLuaFunction(core, lua_dofile, "dofile"); 1579 - registerLuaFunction(core, lua_loadfile, "loadfile"); 1580 - } 1581 - 1582 - void closeLua(tic_mem* tic) 1583 - { 1584 - tic_core* core = (tic_core*)tic; 1585 - 1586 - if(core->currentVM) 1587 - { 1588 - lua_close(core->currentVM); 1589 - core->currentVM = NULL; 1590 - } 1591 - } 1592 - 1593 32 static bool initLua(tic_mem* tic, const char* code) 1594 33 { 1595 34 tic_core* core = (tic_core*)tic; 1596 35 1597 - closeLua(tic); 36 + luaapi_close(tic); 1598 37 1599 38 lua_State* lua = core->currentVM = luaL_newstate(); 1600 - lua_open_builtins(lua); 39 + luaapi_open(lua); 1601 40 1602 - initLuaAPI(core); 41 + luaapi_init(core); 1603 42 1604 43 { 1605 44 lua_State* lua = core->currentVM; ··· 1616 55 return true; 1617 56 } 1618 57 1619 - /* 1620 - ** Message handler which appends stract trace to exceptions. 1621 - ** This function was extractred from lua.c. 1622 - */ 1623 - static s32 msghandler (lua_State *lua) 1624 - { 1625 - const char *msg = lua_tostring(lua, 1); 1626 - if (msg == NULL) /* is error object not a string? */ 1627 - { 1628 - if (luaL_callmeta(lua, 1, "__tostring") && /* does it have a metamethod */ 1629 - lua_type(lua, -1) == LUA_TSTRING) /* that produces a string? */ 1630 - return 1; /* that is the message */ 1631 - else 1632 - msg = lua_pushfstring(lua, "(error object is a %s value)", luaL_typename(lua, 1)); 1633 - } 1634 - luaL_traceback(lua, lua, msg, 1); /* append a standard traceback */ 1635 - return 1; /* return the traceback */ 1636 - } 1637 - 1638 - /* 1639 - ** Interface to 'lua_pcall', which sets appropriate message handler function. 1640 - ** Please use this function for all top level lua functions. 1641 - ** This function was extractred from lua.c (and stripped of signal handling) 1642 - */ 1643 - static s32 docall (lua_State *lua, s32 narg, s32 nres) 1644 - { 1645 - s32 status = 0; 1646 - s32 base = lua_gettop(lua) - narg; /* function index */ 1647 - lua_pushcfunction(lua, msghandler); /* push message handler */ 1648 - lua_insert(lua, base); /* put it under function and args */ 1649 - status = lua_pcall(lua, narg, nres, base); 1650 - lua_remove(lua, base); /* remove message handler from the stack */ 1651 - return status; 1652 - } 1653 - 1654 - void callLuaTick(tic_mem* tic) 1655 - { 1656 - tic_core* core = (tic_core*)tic; 1657 - 1658 - lua_State* lua = core->currentVM; 1659 - 1660 - if(lua) 1661 - { 1662 - lua_getglobal(lua, TIC_FN); 1663 - if(lua_isfunction(lua, -1)) 1664 - { 1665 - if(docall(lua, 0, 0) != LUA_OK) 1666 - { 1667 - core->data->error(core->data->data, lua_tostring(lua, -1)); 1668 - return; 1669 - } 1670 - 1671 - #if defined(BUILD_DEPRECATED) 1672 - // call OVR() callback for backward compatibility 1673 - { 1674 - lua_getglobal(lua, OVR_FN); 1675 - if(lua_isfunction(lua, -1)) 1676 - { 1677 - OVR(core) 1678 - { 1679 - if(docall(lua, 0, 0) != LUA_OK) 1680 - core->data->error(core->data->data, lua_tostring(lua, -1)); 1681 - } 1682 - } 1683 - else lua_pop(lua, 1); 1684 - } 1685 - #endif 1686 - } 1687 - else 1688 - { 1689 - lua_pop(lua, 1); 1690 - core->data->error(core->data->data, "'function TIC()...' isn't found :("); 1691 - } 1692 - } 1693 - } 1694 - 1695 - void callLuaIntCallback(tic_mem* tic, s32 value, void* data, const char* name) 1696 - { 1697 - tic_core* core = (tic_core*)tic; 1698 - lua_State* lua = core->currentVM; 1699 - 1700 - if (lua) 1701 - { 1702 - lua_getglobal(lua, name); 1703 - if(lua_isfunction(lua, -1)) 1704 - { 1705 - lua_pushinteger(lua, value); 1706 - if(docall(lua, 1, 0) != LUA_OK) 1707 - core->data->error(core->data->data, lua_tostring(lua, -1)); 1708 - } 1709 - else lua_pop(lua, 1); 1710 - } 1711 - } 1712 - 1713 - void callLuaScanline(tic_mem* tic, s32 row, void* data) 1714 - { 1715 - callLuaIntCallback(tic, row, data, SCN_FN); 1716 - 1717 - // try to call old scanline 1718 - callLuaIntCallback(tic, row, data, "scanline"); 1719 - } 1720 - 1721 - void callLuaBorder(tic_mem* tic, s32 row, void* data) 1722 - { 1723 - callLuaIntCallback(tic, row, data, BDR_FN); 1724 - } 1725 - 1726 - void callLuaMenu(tic_mem* tic, s32 index, void* data) 1727 - { 1728 - callLuaIntCallback(tic, index, data, MENU_FN); 1729 - } 1730 - 1731 - void callLuaBoot(tic_mem* tic) 1732 - { 1733 - tic_core* core = (tic_core*)tic; 1734 - lua_State* lua = core->currentVM; 1735 - 1736 - if (lua) 1737 - { 1738 - lua_getglobal(lua, BOOT_FN); 1739 - if(lua_isfunction(lua, -1)) 1740 - { 1741 - if(docall(lua, 0, 0) != LUA_OK) 1742 - core->data->error(core->data->data, lua_tostring(lua, -1)); 1743 - } 1744 - else lua_pop(lua, 1); 1745 - } 1746 - } 1747 - 1748 58 static const char* const LuaKeywords [] = 1749 59 { 1750 60 "and", "break", "do", "else", "elseif", ··· 1816 126 return items; 1817 127 } 1818 128 1819 - static void evalLua(tic_mem* tic, const char* code) { 129 + static void evalLua(tic_mem* tic, const char* code) 130 + { 1820 131 tic_core* core = (tic_core*)tic; 1821 132 lua_State* lua = core->currentVM; 1822 133 ··· 1895 206 #include "../build/assets/car.tic.dat" 1896 207 }; 1897 208 1898 - const tic_script EXPORT_SCRIPT(Lua) = 209 + TIC_EXPORT const tic_script EXPORT_SCRIPT(Lua) = 1899 210 { 1900 211 .id = 10, 1901 212 .name = "lua", ··· 1903 214 .projectComment = "--", 1904 215 { 1905 216 .init = initLua, 1906 - .close = closeLua, 1907 - .tick = callLuaTick, 1908 - .boot = callLuaBoot, 217 + .close = luaapi_close, 218 + .tick = luaapi_tick, 219 + .boot = luaapi_boot, 1909 220 1910 221 .callback = 1911 222 { 1912 - .scanline = callLuaScanline, 1913 - .border = callLuaBorder, 1914 - .menu = callLuaMenu, 223 + .scanline = luaapi_scn, 224 + .border = luaapi_bdr, 225 + .menu = luaapi_menu, 1915 226 }, 1916 227 }, 1917 228
+8 -11
src/api/lua_api.h src/api/luaapi.h
··· 29 29 #include <lualib.h> 30 30 #include <ctype.h> 31 31 32 - extern void initLuaAPI(tic_core* core); 33 - extern void callLuaTick(tic_mem* tic); 34 - extern void callLuaBoot(tic_mem* tic); 35 - extern void callLuaScanlineName(tic_mem* tic, s32 row, void* data, const char* name); 36 - extern void callLuaScanline(tic_mem* tic, s32 row, void* data); 37 - extern void callLuaBorder(tic_mem* tic, s32 row, void* data); 38 - extern void callLuaOverline(tic_mem* tic, void* data); 39 - extern void callLuaMenu(tic_mem* tic, s32 index, void* data); 40 - extern void closeLua(tic_mem* tic); 41 - extern void callLuaTick(tic_mem* tic); 42 - extern void lua_open_builtins(lua_State *lua); 32 + void luaapi_init(tic_core* core); 33 + void luaapi_tick(tic_mem* tic); 34 + void luaapi_boot(tic_mem* tic); 35 + void luaapi_scn(tic_mem* tic, s32 row, void* data); 36 + void luaapi_bdr(tic_mem* tic, s32 row, void* data); 37 + void luaapi_menu(tic_mem* tic, s32 index, void* data); 38 + void luaapi_close(tic_mem* tic); 39 + void luaapi_open(lua_State *lua);
+1720
src/api/luaapi.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 "core/core.h" 24 + 25 + #include <stdlib.h> 26 + #include <lua.h> 27 + #include <lauxlib.h> 28 + #include <lualib.h> 29 + #include <ctype.h> 30 + 31 + extern bool parse_note(const char* noteStr, s32* note, s32* octave); 32 + 33 + static inline s32 getLuaNumber(lua_State* lua, s32 index) 34 + { 35 + return (s32)lua_tonumber(lua, index); 36 + } 37 + 38 + static void registerLuaFunction(tic_core* core, lua_CFunction func, const char *name) 39 + { 40 + lua_pushlightuserdata(core->currentVM, core); 41 + lua_pushcclosure(core->currentVM, func, 1); 42 + lua_setglobal(core->currentVM, name); 43 + } 44 + 45 + static tic_core* getLuaCore(lua_State* lua) 46 + { 47 + tic_core* core = lua_touserdata(lua, lua_upvalueindex(1)); 48 + return core; 49 + } 50 + 51 + static s32 lua_peek(lua_State* lua) 52 + { 53 + s32 top = lua_gettop(lua); 54 + tic_core* core = getLuaCore(lua); 55 + tic_mem* tic = (tic_mem*)core; 56 + 57 + if(top >= 1) 58 + { 59 + s32 address = getLuaNumber(lua, 1); 60 + s32 bits = BITS_IN_BYTE; 61 + 62 + if(top == 2) 63 + bits = getLuaNumber(lua, 2); 64 + 65 + lua_pushinteger(lua, core->api.peek(tic, address, bits)); 66 + return 1; 67 + } 68 + else luaL_error(lua, "invalid parameters, peek(addr,bits)\n"); 69 + 70 + return 0; 71 + } 72 + 73 + static s32 lua_poke(lua_State* lua) 74 + { 75 + s32 top = lua_gettop(lua); 76 + tic_core* core = getLuaCore(lua); 77 + tic_mem* tic = (tic_mem*)core; 78 + 79 + if(top >= 2) 80 + { 81 + s32 address = getLuaNumber(lua, 1); 82 + u8 value = getLuaNumber(lua, 2); 83 + s32 bits = BITS_IN_BYTE; 84 + 85 + if(top == 3) 86 + bits = getLuaNumber(lua, 3); 87 + 88 + core->api.poke(tic, address, value, bits); 89 + } 90 + else luaL_error(lua, "invalid parameters, poke(addr,val,bits)\n"); 91 + 92 + return 0; 93 + } 94 + 95 + static s32 lua_peek1(lua_State* lua) 96 + { 97 + s32 top = lua_gettop(lua); 98 + tic_core* core = getLuaCore(lua); 99 + tic_mem* tic = (tic_mem*)core; 100 + 101 + if(top == 1) 102 + { 103 + s32 address = getLuaNumber(lua, 1); 104 + lua_pushinteger(lua, core->api.peek1(tic, address)); 105 + return 1; 106 + } 107 + else luaL_error(lua, "invalid parameters, peek1(addr)\n"); 108 + 109 + return 0; 110 + } 111 + 112 + static s32 lua_poke1(lua_State* lua) 113 + { 114 + s32 top = lua_gettop(lua); 115 + tic_core* core = getLuaCore(lua); 116 + tic_mem* tic = (tic_mem*)core; 117 + 118 + if(top == 2) 119 + { 120 + s32 address = getLuaNumber(lua, 1); 121 + u8 value = getLuaNumber(lua, 2); 122 + 123 + core->api.poke1(tic, address, value); 124 + } 125 + else luaL_error(lua, "invalid parameters, poke1(addr,val)\n"); 126 + 127 + return 0; 128 + } 129 + 130 + static s32 lua_peek2(lua_State* lua) 131 + { 132 + s32 top = lua_gettop(lua); 133 + tic_core* core = getLuaCore(lua); 134 + tic_mem* tic = (tic_mem*)core; 135 + 136 + if(top == 1) 137 + { 138 + s32 address = getLuaNumber(lua, 1); 139 + lua_pushinteger(lua, core->api.peek2(tic, address)); 140 + return 1; 141 + } 142 + else luaL_error(lua, "invalid parameters, peek2(addr)\n"); 143 + 144 + return 0; 145 + } 146 + 147 + static s32 lua_poke2(lua_State* lua) 148 + { 149 + s32 top = lua_gettop(lua); 150 + tic_core* core = getLuaCore(lua); 151 + tic_mem* tic = (tic_mem*)core; 152 + 153 + if(top == 2) 154 + { 155 + s32 address = getLuaNumber(lua, 1); 156 + u8 value = getLuaNumber(lua, 2); 157 + 158 + core->api.poke2(tic, address, value); 159 + } 160 + else luaL_error(lua, "invalid parameters, poke2(addr,val)\n"); 161 + 162 + return 0; 163 + } 164 + 165 + static s32 lua_peek4(lua_State* lua) 166 + { 167 + s32 top = lua_gettop(lua); 168 + tic_core* core = getLuaCore(lua); 169 + tic_mem* tic = (tic_mem*)core; 170 + 171 + if(top == 1) 172 + { 173 + s32 address = getLuaNumber(lua, 1); 174 + lua_pushinteger(lua, core->api.peek4(tic, address)); 175 + return 1; 176 + } 177 + else luaL_error(lua, "invalid parameters, peek4(addr)\n"); 178 + 179 + return 0; 180 + } 181 + 182 + static s32 lua_poke4(lua_State* lua) 183 + { 184 + s32 top = lua_gettop(lua); 185 + tic_core* core = getLuaCore(lua); 186 + tic_mem* tic = (tic_mem*)core; 187 + 188 + if(top == 2) 189 + { 190 + s32 address = getLuaNumber(lua, 1); 191 + u8 value = getLuaNumber(lua, 2); 192 + 193 + core->api.poke4(tic, address, value); 194 + } 195 + else luaL_error(lua, "invalid parameters, poke4(addr,val)\n"); 196 + 197 + return 0; 198 + } 199 + 200 + static s32 lua_cls(lua_State* lua) 201 + { 202 + s32 top = lua_gettop(lua); 203 + 204 + tic_core* core = getLuaCore(lua); 205 + tic_mem* tic = (tic_mem*)core; 206 + 207 + core->api.cls(tic, top == 1 ? getLuaNumber(lua, 1) : 0); 208 + 209 + return 0; 210 + } 211 + 212 + static s32 lua_pix(lua_State* lua) 213 + { 214 + s32 top = lua_gettop(lua); 215 + 216 + if(top >= 2) 217 + { 218 + s32 x = getLuaNumber(lua, 1); 219 + s32 y = getLuaNumber(lua, 2); 220 + 221 + tic_core* core = getLuaCore(lua); 222 + tic_mem* tic = (tic_mem*)core; 223 + 224 + if(top >= 3) 225 + { 226 + s32 color = getLuaNumber(lua, 3); 227 + core->api.pix(tic, x, y, color, false); 228 + } 229 + else 230 + { 231 + lua_pushinteger(lua, core->api.pix(tic, x, y, 0, true)); 232 + return 1; 233 + } 234 + 235 + } 236 + else luaL_error(lua, "invalid parameters, pix(x y [color])\n"); 237 + 238 + return 0; 239 + } 240 + 241 + static s32 lua_line(lua_State* lua) 242 + { 243 + s32 top = lua_gettop(lua); 244 + 245 + if(top == 5) 246 + { 247 + float x0 = lua_tonumber(lua, 1); 248 + float y0 = lua_tonumber(lua, 2); 249 + float x1 = lua_tonumber(lua, 3); 250 + float y1 = lua_tonumber(lua, 4); 251 + s32 color = getLuaNumber(lua, 5); 252 + 253 + tic_core* core = getLuaCore(lua); 254 + tic_mem* tic = (tic_mem*)core; 255 + 256 + core->api.line(tic, x0, y0, x1, y1, color); 257 + } 258 + else luaL_error(lua, "invalid parameters, line(x0,y0,x1,y1,color)\n"); 259 + 260 + return 0; 261 + } 262 + 263 + static s32 lua_rect(lua_State* lua) 264 + { 265 + s32 top = lua_gettop(lua); 266 + 267 + if(top == 5) 268 + { 269 + s32 x = getLuaNumber(lua, 1); 270 + s32 y = getLuaNumber(lua, 2); 271 + s32 w = getLuaNumber(lua, 3); 272 + s32 h = getLuaNumber(lua, 4); 273 + s32 color = getLuaNumber(lua, 5); 274 + 275 + tic_core* core = getLuaCore(lua); 276 + tic_mem* tic = (tic_mem*)core; 277 + 278 + core->api.rect(tic, x, y, w, h, color); 279 + } 280 + else luaL_error(lua, "invalid parameters, rect(x,y,w,h,color)\n"); 281 + 282 + return 0; 283 + } 284 + 285 + static s32 lua_rectb(lua_State* lua) 286 + { 287 + s32 top = lua_gettop(lua); 288 + 289 + if(top == 5) 290 + { 291 + s32 x = getLuaNumber(lua, 1); 292 + s32 y = getLuaNumber(lua, 2); 293 + s32 w = getLuaNumber(lua, 3); 294 + s32 h = getLuaNumber(lua, 4); 295 + s32 color = getLuaNumber(lua, 5); 296 + 297 + tic_core* core = getLuaCore(lua); 298 + tic_mem* tic = (tic_mem*)core; 299 + 300 + core->api.rectb(tic, x, y, w, h, color); 301 + } 302 + else luaL_error(lua, "invalid parameters, rectb(x,y,w,h,color)\n"); 303 + 304 + return 0; 305 + } 306 + 307 + static s32 lua_circ(lua_State* lua) 308 + { 309 + s32 top = lua_gettop(lua); 310 + 311 + if(top == 4) 312 + { 313 + tic_core* core = getLuaCore(lua); 314 + tic_mem* tic = (tic_mem*)core; 315 + 316 + s32 x = getLuaNumber(lua, 1); 317 + s32 y = getLuaNumber(lua, 2); 318 + s32 radius = getLuaNumber(lua, 3); 319 + s32 color = getLuaNumber(lua, 4); 320 + 321 + core->api.circ(tic, x, y, radius, color); 322 + } 323 + else luaL_error(lua, "invalid parameters, circ(x,y,radius,color)\n"); 324 + 325 + return 0; 326 + } 327 + 328 + static s32 lua_circb(lua_State* lua) 329 + { 330 + s32 top = lua_gettop(lua); 331 + 332 + if(top == 4) 333 + { 334 + tic_core* core = getLuaCore(lua); 335 + tic_mem* tic = (tic_mem*)core; 336 + 337 + s32 x = getLuaNumber(lua, 1); 338 + s32 y = getLuaNumber(lua, 2); 339 + s32 radius = getLuaNumber(lua, 3); 340 + s32 color = getLuaNumber(lua, 4); 341 + 342 + core->api.circb(tic, x, y, radius, color); 343 + } 344 + else luaL_error(lua, "invalid parameters, circb(x,y,radius,color)\n"); 345 + 346 + return 0; 347 + } 348 + 349 + static s32 lua_elli(lua_State* lua) 350 + { 351 + s32 top = lua_gettop(lua); 352 + 353 + if(top == 5) 354 + { 355 + tic_core* core = getLuaCore(lua); 356 + tic_mem* tic = (tic_mem*)core; 357 + 358 + s32 x = getLuaNumber(lua, 1); 359 + s32 y = getLuaNumber(lua, 2); 360 + s32 a = getLuaNumber(lua, 3); 361 + s32 b = getLuaNumber(lua, 4); 362 + s32 color = getLuaNumber(lua, 5); 363 + 364 + core->api.elli(tic, x, y, a, b, color); 365 + } 366 + else luaL_error(lua, "invalid parameters, elli(x,y,a,b,color)\n"); 367 + 368 + return 0; 369 + } 370 + 371 + static s32 lua_ellib(lua_State* lua) 372 + { 373 + s32 top = lua_gettop(lua); 374 + 375 + if(top == 5) 376 + { 377 + tic_core* core = getLuaCore(lua); 378 + tic_mem* tic = (tic_mem*)core; 379 + 380 + s32 x = getLuaNumber(lua, 1); 381 + s32 y = getLuaNumber(lua, 2); 382 + s32 a = getLuaNumber(lua, 3); 383 + s32 b = getLuaNumber(lua, 4); 384 + s32 color = getLuaNumber(lua, 5); 385 + 386 + core->api.ellib(tic, x, y, a, b, color); 387 + } 388 + else luaL_error(lua, "invalid parameters, ellib(x,y,a,b,color)\n"); 389 + 390 + return 0; 391 + } 392 + 393 + static s32 lua_tri(lua_State* lua) 394 + { 395 + s32 top = lua_gettop(lua); 396 + 397 + if(top == 7) 398 + { 399 + float pt[6]; 400 + 401 + for(s32 i = 0; i < COUNT_OF(pt); i++) 402 + pt[i] = lua_tonumber(lua, i+1); 403 + 404 + s32 color = getLuaNumber(lua, 7); 405 + 406 + tic_core* core = getLuaCore(lua); 407 + tic_mem* tic = (tic_mem*)core; 408 + 409 + core->api.tri(tic, pt[0], pt[1], pt[2], pt[3], pt[4], pt[5], color); 410 + } 411 + else luaL_error(lua, "invalid parameters, tri(x1,y1,x2,y2,x3,y3,color)\n"); 412 + 413 + return 0; 414 + } 415 + 416 + static s32 lua_trib(lua_State* lua) 417 + { 418 + s32 top = lua_gettop(lua); 419 + 420 + if(top == 7) 421 + { 422 + float pt[6]; 423 + 424 + for(s32 i = 0; i < COUNT_OF(pt); i++) 425 + pt[i] = lua_tonumber(lua, i+1); 426 + 427 + s32 color = getLuaNumber(lua, 7); 428 + 429 + tic_core* core = getLuaCore(lua); 430 + tic_mem* tic = (tic_mem*)core; 431 + 432 + core->api.trib(tic, pt[0], pt[1], pt[2], pt[3], pt[4], pt[5], color); 433 + } 434 + else luaL_error(lua, "invalid parameters, trib(x1,y1,x2,y2,x3,y3,color)\n"); 435 + 436 + return 0; 437 + } 438 + 439 + #if defined(BUILD_DEPRECATED) 440 + 441 + static s32 lua_textri(lua_State* lua) 442 + { 443 + s32 top = lua_gettop(lua); 444 + 445 + if (top >= 12) 446 + { 447 + float pt[12]; 448 + 449 + for (s32 i = 0; i < COUNT_OF(pt); i++) 450 + pt[i] = (float)lua_tonumber(lua, i + 1); 451 + 452 + tic_core* core = getLuaCore(lua); 453 + tic_mem* tic = (tic_mem*)core; 454 + static u8 colors[TIC_PALETTE_SIZE]; 455 + s32 count = 0; 456 + bool use_map = false; 457 + 458 + // check for use map 459 + if (top >= 13) 460 + use_map = lua_toboolean(lua, 13); 461 + 462 + // check for chroma 463 + if(top >= 14) 464 + { 465 + if(lua_istable(lua, 14)) 466 + { 467 + for(s32 i = 1; i <= TIC_PALETTE_SIZE; i++) 468 + { 469 + lua_rawgeti(lua, 14, i); 470 + if(lua_isnumber(lua, -1)) 471 + { 472 + colors[i-1] = getLuaNumber(lua, -1); 473 + count++; 474 + lua_pop(lua, 1); 475 + } 476 + else 477 + { 478 + lua_pop(lua, 1); 479 + break; 480 + } 481 + } 482 + } 483 + else 484 + { 485 + colors[0] = getLuaNumber(lua, 14); 486 + count = 1; 487 + } 488 + } 489 + 490 + core->api.textri(tic, 491 + pt[0], pt[1], // xy 1 492 + pt[2], pt[3], // xy 2 493 + pt[4], pt[5], // xy 3 494 + pt[6], pt[7], // uv 1 495 + pt[8], pt[9], // uv 2 496 + pt[10], pt[11], // uv 3 497 + use_map, // use map 498 + colors, count); // chroma 499 + } 500 + 501 + return 0; 502 + } 503 + 504 + #endif 505 + 506 + static s32 lua_ttri(lua_State* lua) 507 + { 508 + s32 top = lua_gettop(lua); 509 + 510 + if (top >= 12) 511 + { 512 + float pt[12]; 513 + 514 + for (s32 i = 0; i < COUNT_OF(pt); i++) 515 + pt[i] = (float)lua_tonumber(lua, i + 1); 516 + 517 + tic_core* core = getLuaCore(lua); 518 + tic_mem* tic = (tic_mem*)core; 519 + static u8 colors[TIC_PALETTE_SIZE]; 520 + s32 count = 0; 521 + tic_texture_src src = tic_tiles_texture; 522 + 523 + // check for texture src 524 + if (top >= 13) 525 + { 526 + src = lua_isboolean(lua, 13) 527 + ? (lua_toboolean(lua, 13) ? tic_map_texture : tic_tiles_texture) 528 + : lua_tointeger(lua, 13); 529 + } 530 + // check for chroma 531 + if(top >= 14) 532 + { 533 + if(lua_istable(lua, 14)) 534 + { 535 + for(s32 i = 1; i <= TIC_PALETTE_SIZE; i++) 536 + { 537 + lua_rawgeti(lua, 14, i); 538 + if(lua_isnumber(lua, -1)) 539 + { 540 + colors[i-1] = getLuaNumber(lua, -1); 541 + count++; 542 + lua_pop(lua, 1); 543 + } 544 + else 545 + { 546 + lua_pop(lua, 1); 547 + break; 548 + } 549 + } 550 + } 551 + else 552 + { 553 + colors[0] = getLuaNumber(lua, 14); 554 + count = 1; 555 + } 556 + } 557 + 558 + float z[3]; 559 + bool depth = false; 560 + 561 + if(top == 17) 562 + { 563 + for (s32 i = 0; i < COUNT_OF(z); i++) 564 + z[i] = (float)lua_tonumber(lua, i + 15); 565 + 566 + depth = true; 567 + } 568 + 569 + core->api.ttri(tic, pt[0], pt[1], // xy 1 570 + pt[2], pt[3], // xy 2 571 + pt[4], pt[5], // xy 3 572 + pt[6], pt[7], // uv 1 573 + pt[8], pt[9], // uv 2 574 + pt[10], pt[11], // uv 3 575 + src, // texture source 576 + colors, count, // chroma 577 + z[0], z[1], z[2], depth); // depth 578 + } 579 + else luaL_error(lua, "invalid parameters, ttri(x1,y1,x2,y2,x3,y3,u1,v1,u2,v2,u3,v3,[src=0],[chroma=off],[z1=0],[z2=0],[z3=0])\n"); 580 + return 0; 581 + } 582 + 583 + 584 + static s32 lua_clip(lua_State* lua) 585 + { 586 + s32 top = lua_gettop(lua); 587 + 588 + if(top == 0) 589 + { 590 + tic_core* core = getLuaCore(lua); 591 + tic_mem* tic = (tic_mem*)core; 592 + 593 + core->api.clip(tic, 0, 0, TIC80_WIDTH, TIC80_HEIGHT); 594 + } 595 + else if(top == 4) 596 + { 597 + s32 x = getLuaNumber(lua, 1); 598 + s32 y = getLuaNumber(lua, 2); 599 + s32 w = getLuaNumber(lua, 3); 600 + s32 h = getLuaNumber(lua, 4); 601 + 602 + tic_core* core = getLuaCore(lua); 603 + tic_mem* tic = (tic_mem*)core; 604 + 605 + core->api.clip((tic_mem*)getLuaCore(lua), x, y, w, h); 606 + } 607 + else luaL_error(lua, "invalid parameters, use clip(x,y,w,h) or clip()\n"); 608 + 609 + return 0; 610 + } 611 + 612 + static s32 lua_btnp(lua_State* lua) 613 + { 614 + tic_core* core = getLuaCore(lua); 615 + tic_mem* tic = (tic_mem*)core; 616 + 617 + s32 top = lua_gettop(lua); 618 + 619 + if (top == 0) 620 + { 621 + lua_pushinteger(lua, core->api.btnp(tic, -1, -1, -1)); 622 + } 623 + else if(top == 1) 624 + { 625 + s32 index = getLuaNumber(lua, 1) & 0x1f; 626 + 627 + lua_pushboolean(lua, core->api.btnp(tic, index, -1, -1)); 628 + } 629 + else if (top == 3) 630 + { 631 + s32 index = getLuaNumber(lua, 1) & 0x1f; 632 + u32 hold = getLuaNumber(lua, 2); 633 + u32 period = getLuaNumber(lua, 3); 634 + 635 + lua_pushboolean(lua, core->api.btnp(tic, index, hold, period)); 636 + } 637 + else 638 + { 639 + luaL_error(lua, "invalid params, btnp [ id [ hold period ] ]\n"); 640 + return 0; 641 + } 642 + 643 + return 1; 644 + } 645 + 646 + static s32 lua_btn(lua_State* lua) 647 + { 648 + tic_core* core = getLuaCore(lua); 649 + tic_mem* tic = (tic_mem*)core; 650 + 651 + s32 top = lua_gettop(lua); 652 + 653 + if (top == 0) 654 + { 655 + lua_pushinteger(lua, core->api.btn(tic, -1)); 656 + } 657 + else if (top == 1) 658 + { 659 + bool pressed = core->api.btn(tic, getLuaNumber(lua, 1) & 0x1f); 660 + lua_pushboolean(lua, pressed); 661 + } 662 + else 663 + { 664 + luaL_error(lua, "invalid params, btn [ id ]\n"); 665 + return 0; 666 + } 667 + 668 + return 1; 669 + } 670 + 671 + static s32 lua_spr(lua_State* lua) 672 + { 673 + s32 top = lua_gettop(lua); 674 + 675 + s32 index = 0; 676 + s32 x = 0; 677 + s32 y = 0; 678 + s32 w = 1; 679 + s32 h = 1; 680 + s32 scale = 1; 681 + tic_flip flip = tic_no_flip; 682 + tic_rotate rotate = tic_no_rotate; 683 + static u8 colors[TIC_PALETTE_SIZE]; 684 + s32 count = 0; 685 + 686 + if(top >= 1) 687 + { 688 + index = getLuaNumber(lua, 1); 689 + 690 + if(top >= 3) 691 + { 692 + x = getLuaNumber(lua, 2); 693 + y = getLuaNumber(lua, 3); 694 + 695 + if(top >= 4) 696 + { 697 + if(lua_istable(lua, 4)) 698 + { 699 + for(s32 i = 1; i <= TIC_PALETTE_SIZE; i++) 700 + { 701 + lua_rawgeti(lua, 4, i); 702 + if(lua_isnumber(lua, -1)) 703 + { 704 + colors[i-1] = getLuaNumber(lua, -1); 705 + count++; 706 + lua_pop(lua, 1); 707 + } 708 + else 709 + { 710 + lua_pop(lua, 1); 711 + break; 712 + } 713 + } 714 + } 715 + else 716 + { 717 + colors[0] = getLuaNumber(lua, 4); 718 + count = 1; 719 + } 720 + 721 + if(top >= 5) 722 + { 723 + scale = getLuaNumber(lua, 5); 724 + 725 + if(top >= 6) 726 + { 727 + flip = getLuaNumber(lua, 6); 728 + 729 + if(top >= 7) 730 + { 731 + rotate = getLuaNumber(lua, 7); 732 + 733 + if(top >= 9) 734 + { 735 + w = getLuaNumber(lua, 8); 736 + h = getLuaNumber(lua, 9); 737 + } 738 + } 739 + } 740 + } 741 + } 742 + } 743 + } 744 + 745 + tic_core* core = getLuaCore(lua); 746 + tic_mem* tic = (tic_mem*)core; 747 + 748 + core->api.spr(tic, index, x, y, w, h, colors, count, scale, flip, rotate); 749 + 750 + return 0; 751 + } 752 + 753 + static s32 lua_mget(lua_State* lua) 754 + { 755 + s32 top = lua_gettop(lua); 756 + 757 + if(top == 2) 758 + { 759 + s32 x = getLuaNumber(lua, 1); 760 + s32 y = getLuaNumber(lua, 2); 761 + 762 + tic_core* core = getLuaCore(lua); 763 + tic_mem* tic = (tic_mem*)core; 764 + 765 + u8 value = core->api.mget(tic, x, y); 766 + lua_pushinteger(lua, value); 767 + return 1; 768 + } 769 + else luaL_error(lua, "invalid params, mget(x,y)\n"); 770 + 771 + return 0; 772 + } 773 + 774 + static s32 lua_mset(lua_State* lua) 775 + { 776 + s32 top = lua_gettop(lua); 777 + 778 + if(top == 3) 779 + { 780 + s32 x = getLuaNumber(lua, 1); 781 + s32 y = getLuaNumber(lua, 2); 782 + u8 val = getLuaNumber(lua, 3); 783 + 784 + tic_core* core = getLuaCore(lua); 785 + tic_mem* tic = (tic_mem*)core; 786 + 787 + core->api.mset(tic, x, y, val); 788 + } 789 + else luaL_error(lua, "invalid params, mget(x,y)\n"); 790 + 791 + return 0; 792 + } 793 + 794 + typedef struct 795 + { 796 + lua_State* lua; 797 + s32 reg; 798 + } RemapData; 799 + 800 + static void remapCallback(void* data, s32 x, s32 y, RemapResult* result) 801 + { 802 + RemapData* remap = (RemapData*)data; 803 + lua_State* lua = remap->lua; 804 + 805 + lua_rawgeti(lua, LUA_REGISTRYINDEX, remap->reg); 806 + lua_pushinteger(lua, result->index); 807 + lua_pushinteger(lua, x); 808 + lua_pushinteger(lua, y); 809 + lua_pcall(lua, 3, 3, 0); 810 + 811 + result->index = getLuaNumber(lua, -3); 812 + result->flip = getLuaNumber(lua, -2); 813 + result->rotate = getLuaNumber(lua, -1); 814 + } 815 + 816 + static s32 lua_map(lua_State* lua) 817 + { 818 + s32 x = 0; 819 + s32 y = 0; 820 + s32 w = TIC_MAP_SCREEN_WIDTH; 821 + s32 h = TIC_MAP_SCREEN_HEIGHT; 822 + s32 sx = 0; 823 + s32 sy = 0; 824 + s32 scale = 1; 825 + static u8 colors[TIC_PALETTE_SIZE]; 826 + s32 count = 0; 827 + 828 + s32 top = lua_gettop(lua); 829 + 830 + if(top >= 2) 831 + { 832 + x = getLuaNumber(lua, 1); 833 + y = getLuaNumber(lua, 2); 834 + 835 + if(top >= 4) 836 + { 837 + w = getLuaNumber(lua, 3); 838 + h = getLuaNumber(lua, 4); 839 + 840 + if(top >= 6) 841 + { 842 + sx = getLuaNumber(lua, 5); 843 + sy = getLuaNumber(lua, 6); 844 + 845 + if(top >= 7) 846 + { 847 + if(lua_istable(lua, 7)) 848 + { 849 + for(s32 i = 1; i <= TIC_PALETTE_SIZE; i++) 850 + { 851 + lua_rawgeti(lua, 7, i); 852 + if(lua_isnumber(lua, -1)) 853 + { 854 + colors[i-1] = getLuaNumber(lua, -1); 855 + count++; 856 + lua_pop(lua, 1); 857 + } 858 + else 859 + { 860 + lua_pop(lua, 1); 861 + break; 862 + } 863 + } 864 + } 865 + else 866 + { 867 + colors[0] = getLuaNumber(lua, 7); 868 + count = 1; 869 + } 870 + 871 + if(top >= 8) 872 + { 873 + scale = getLuaNumber(lua, 8); 874 + 875 + if(top >= 9) 876 + { 877 + if (lua_isfunction(lua, 9)) 878 + { 879 + s32 remap = luaL_ref(lua, LUA_REGISTRYINDEX); 880 + 881 + RemapData data = {lua, remap}; 882 + 883 + tic_core* core = getLuaCore(lua); 884 + tic_mem* tic = (tic_mem*)core; 885 + 886 + core->api.map(tic, x, y, w, h, sx, sy, colors, count, scale, remapCallback, &data); 887 + 888 + luaL_unref(lua, LUA_REGISTRYINDEX, data.reg); 889 + 890 + return 0; 891 + } 892 + } 893 + } 894 + } 895 + } 896 + } 897 + } 898 + 899 + tic_core* core = getLuaCore(lua); 900 + tic_mem* tic = (tic_mem*)core; 901 + 902 + core->api.map((tic_mem*)getLuaCore(lua), x, y, w, h, sx, sy, colors, count, scale, NULL, NULL); 903 + 904 + return 0; 905 + } 906 + 907 + static s32 lua_music(lua_State* lua) 908 + { 909 + s32 top = lua_gettop(lua); 910 + tic_core* core = getLuaCore(lua); 911 + tic_mem* tic = (tic_mem*)core; 912 + 913 + if(top == 0) core->api.music(tic, -1, 0, 0, false, false, -1, -1); 914 + else if(top >= 1) 915 + { 916 + s32 track = getLuaNumber(lua, 1); 917 + 918 + if(track > MUSIC_TRACKS - 1) 919 + { 920 + luaL_error(lua, "invalid music track index"); 921 + return 0; 922 + } 923 + 924 + core->api.music(tic, -1, 0, 0, false, false, -1, -1); 925 + 926 + s32 frame = -1; 927 + s32 row = -1; 928 + bool loop = true; 929 + bool sustain = false; 930 + s32 tempo = -1; 931 + s32 speed = -1; 932 + 933 + if(top >= 2) 934 + { 935 + frame = getLuaNumber(lua, 2); 936 + 937 + if(top >= 3) 938 + { 939 + row = getLuaNumber(lua, 3); 940 + 941 + if(top >= 4) 942 + { 943 + loop = lua_toboolean(lua, 4); 944 + 945 + if (top >= 5) 946 + { 947 + sustain = lua_toboolean(lua, 5); 948 + 949 + if (top >= 6) 950 + { 951 + tempo = getLuaNumber(lua, 6); 952 + 953 + if (top >= 7) 954 + { 955 + speed = getLuaNumber(lua, 7); 956 + } 957 + } 958 + } 959 + 960 + } 961 + } 962 + } 963 + 964 + core->api.music(tic, track, frame, row, loop, sustain, tempo, speed); 965 + } 966 + else luaL_error(lua, "invalid params, use music(track)\n"); 967 + 968 + return 0; 969 + } 970 + 971 + static s32 lua_sfx(lua_State* lua) 972 + { 973 + s32 top = lua_gettop(lua); 974 + 975 + if(top >= 1) 976 + { 977 + tic_core* core = getLuaCore(lua); 978 + tic_mem* tic = (tic_mem*)core; 979 + 980 + s32 note = -1; 981 + s32 octave = -1; 982 + s32 duration = -1; 983 + s32 channel = 0; 984 + s32 volumes[TIC80_SAMPLE_CHANNELS] = {MAX_VOLUME, MAX_VOLUME}; 985 + s32 speed = SFX_DEF_SPEED; 986 + 987 + s32 index = getLuaNumber(lua, 1); 988 + 989 + if(index < SFX_COUNT) 990 + { 991 + if (index >= 0) 992 + { 993 + tic_sample* effect = tic->ram->sfx.samples.data + index; 994 + 995 + note = effect->note; 996 + octave = effect->octave; 997 + speed = effect->speed; 998 + } 999 + 1000 + if(top >= 2) 1001 + { 1002 + if(lua_isinteger(lua, 2)) 1003 + { 1004 + s32 id = getLuaNumber(lua, 2); 1005 + note = id % NOTES; 1006 + octave = id / NOTES; 1007 + } 1008 + else if(lua_isstring(lua, 2)) 1009 + { 1010 + const char* noteStr = lua_tostring(lua, 2); 1011 + 1012 + if(!parse_note(noteStr, &note, &octave)) 1013 + { 1014 + luaL_error(lua, "invalid note, should be like C#4\n"); 1015 + return 0; 1016 + } 1017 + } 1018 + 1019 + if(top >= 3) 1020 + { 1021 + duration = getLuaNumber(lua, 3); 1022 + 1023 + if(top >= 4) 1024 + { 1025 + channel = getLuaNumber(lua, 4); 1026 + 1027 + if(top >= 5) 1028 + { 1029 + if(lua_istable(lua, 5)) 1030 + { 1031 + for(s32 i = 0; i < COUNT_OF(volumes); i++) 1032 + { 1033 + volumes[i] = lua_rawgeti(lua, 5, i + 1); 1034 + lua_pop(lua, 1); 1035 + } 1036 + } 1037 + else volumes[0] = volumes[1] = getLuaNumber(lua, 5); 1038 + 1039 + if(top >= 6) 1040 + { 1041 + speed = getLuaNumber(lua, 6); 1042 + } 1043 + } 1044 + } 1045 + } 1046 + } 1047 + 1048 + if (channel >= 0 && channel < TIC_SOUND_CHANNELS) 1049 + { 1050 + core->api.sfx(tic, index, note, octave, duration, channel, volumes[0] & 0xf, volumes[1] & 0xf, speed); 1051 + } 1052 + else luaL_error(lua, "unknown channel\n"); 1053 + } 1054 + else luaL_error(lua, "unknown sfx index\n"); 1055 + } 1056 + else luaL_error(lua, "invalid sfx params\n"); 1057 + 1058 + return 0; 1059 + } 1060 + 1061 + static s32 lua_vbank(lua_State* lua) 1062 + { 1063 + tic_core* core = getLuaCore(lua); 1064 + tic_mem* tic = (tic_mem*)core; 1065 + 1066 + s32 prev = core->state.vbank.id; 1067 + 1068 + if(lua_gettop(lua) == 1) 1069 + core->api.vbank(tic, getLuaNumber(lua, 1)); 1070 + 1071 + lua_pushinteger(lua, prev); 1072 + return 1; 1073 + } 1074 + 1075 + static s32 lua_sync(lua_State* lua) 1076 + { 1077 + tic_core* core = getLuaCore(lua); 1078 + tic_mem* tic = (tic_mem*)core; 1079 + 1080 + bool toCart = false; 1081 + u32 mask = 0; 1082 + s32 bank = 0; 1083 + 1084 + if(lua_gettop(lua) >= 1) 1085 + { 1086 + mask = getLuaNumber(lua, 1); 1087 + 1088 + if(lua_gettop(lua) >= 2) 1089 + { 1090 + bank = getLuaNumber(lua, 2); 1091 + 1092 + if(lua_gettop(lua) >= 3) 1093 + { 1094 + toCart = lua_toboolean(lua, 3); 1095 + } 1096 + } 1097 + } 1098 + 1099 + if(bank >= 0 && bank < TIC_BANKS) 1100 + core->api.sync(tic, mask, bank, toCart); 1101 + else 1102 + luaL_error(lua, "sync() error, invalid bank"); 1103 + 1104 + return 0; 1105 + } 1106 + 1107 + static s32 lua_reset(lua_State* lua) 1108 + { 1109 + tic_core* core = getLuaCore(lua); 1110 + 1111 + core->state.initialized = false; 1112 + 1113 + return 0; 1114 + } 1115 + 1116 + static s32 lua_key(lua_State* lua) 1117 + { 1118 + tic_core* core = getLuaCore(lua); 1119 + tic_mem* tic = &core->memory; 1120 + 1121 + s32 top = lua_gettop(lua); 1122 + 1123 + if (top == 0) 1124 + { 1125 + lua_pushboolean(lua, core->api.key(tic, tic_key_unknown)); 1126 + } 1127 + else if (top == 1) 1128 + { 1129 + tic_key key = getLuaNumber(lua, 1); 1130 + 1131 + if(key < tic_keys_count) 1132 + lua_pushboolean(lua, core->api.key(tic, key)); 1133 + else 1134 + { 1135 + luaL_error(lua, "unknown keyboard code\n"); 1136 + return 0; 1137 + } 1138 + } 1139 + else 1140 + { 1141 + luaL_error(lua, "invalid params, key [code]\n"); 1142 + return 0; 1143 + } 1144 + 1145 + return 1; 1146 + } 1147 + 1148 + static s32 lua_keyp(lua_State* lua) 1149 + { 1150 + tic_core* core = getLuaCore(lua); 1151 + tic_mem* tic = &core->memory; 1152 + 1153 + s32 top = lua_gettop(lua); 1154 + 1155 + if (top == 0) 1156 + { 1157 + lua_pushboolean(lua, core->api.keyp(tic, tic_key_unknown, -1, -1)); 1158 + } 1159 + else 1160 + { 1161 + tic_key key = getLuaNumber(lua, 1); 1162 + 1163 + if(key >= tic_keys_count) 1164 + { 1165 + luaL_error(lua, "unknown keyboard code\n"); 1166 + } 1167 + else 1168 + { 1169 + if(top == 1) 1170 + { 1171 + lua_pushboolean(lua, core->api.keyp(tic, key, -1, -1)); 1172 + } 1173 + else if(top == 3) 1174 + { 1175 + u32 hold = getLuaNumber(lua, 2); 1176 + u32 period = getLuaNumber(lua, 3); 1177 + 1178 + lua_pushboolean(lua, core->api.keyp(tic, key, hold, period)); 1179 + } 1180 + else 1181 + { 1182 + luaL_error(lua, "invalid params, keyp [ code [ hold period ] ]\n"); 1183 + return 0; 1184 + } 1185 + } 1186 + } 1187 + 1188 + return 1; 1189 + } 1190 + 1191 + static s32 lua_memcpy(lua_State* lua) 1192 + { 1193 + s32 top = lua_gettop(lua); 1194 + 1195 + if(top == 3) 1196 + { 1197 + s32 dest = getLuaNumber(lua, 1); 1198 + s32 src = getLuaNumber(lua, 2); 1199 + s32 size = getLuaNumber(lua, 3); 1200 + 1201 + tic_core* core = getLuaCore(lua); 1202 + tic_mem* tic = (tic_mem*)core; 1203 + core->api.memcpy(tic, dest, src, size); 1204 + } 1205 + else luaL_error(lua, "invalid params, memcpy(dest,src,size)\n"); 1206 + 1207 + return 0; 1208 + } 1209 + 1210 + static s32 lua_memset(lua_State* lua) 1211 + { 1212 + s32 top = lua_gettop(lua); 1213 + 1214 + if(top == 3) 1215 + { 1216 + s32 dest = getLuaNumber(lua, 1); 1217 + u8 value = getLuaNumber(lua, 2); 1218 + s32 size = getLuaNumber(lua, 3); 1219 + 1220 + tic_core* core = getLuaCore(lua); 1221 + tic_mem* tic = (tic_mem*)core; 1222 + 1223 + core->api.memset(tic, dest, value, size); 1224 + } 1225 + else luaL_error(lua, "invalid params, memset(dest,val,size)\n"); 1226 + 1227 + return 0; 1228 + } 1229 + 1230 + static const char* printString(lua_State* lua, s32 index) 1231 + { 1232 + lua_getglobal(lua, "tostring"); 1233 + lua_pushvalue(lua, -1); 1234 + lua_pushvalue(lua, index); 1235 + lua_call(lua, 1, 1); 1236 + 1237 + const char* text = lua_tostring(lua, -1); 1238 + 1239 + lua_pop(lua, 2); 1240 + 1241 + return text; 1242 + } 1243 + 1244 + static s32 lua_font(lua_State* lua) 1245 + { 1246 + tic_core* core = getLuaCore(lua); 1247 + tic_mem* tic = (tic_mem*)core; 1248 + s32 top = lua_gettop(lua); 1249 + 1250 + if(top >= 1) 1251 + { 1252 + const char* text = printString(lua, 1); 1253 + s32 x = 0; 1254 + s32 y = 0; 1255 + s32 width = TIC_SPRITESIZE; 1256 + s32 height = TIC_SPRITESIZE; 1257 + u8 chromakey = 0; 1258 + bool fixed = false; 1259 + s32 scale = 1; 1260 + bool alt = false; 1261 + 1262 + if(top >= 3) 1263 + { 1264 + x = getLuaNumber(lua, 2); 1265 + y = getLuaNumber(lua, 3); 1266 + 1267 + if(top >= 4) 1268 + { 1269 + chromakey = getLuaNumber(lua, 4); 1270 + 1271 + if(top >= 6) 1272 + { 1273 + width = getLuaNumber(lua, 5); 1274 + height = getLuaNumber(lua, 6); 1275 + 1276 + if(top >= 7) 1277 + { 1278 + fixed = lua_toboolean(lua, 7); 1279 + 1280 + if(top >= 8) 1281 + { 1282 + scale = getLuaNumber(lua, 8); 1283 + 1284 + if(top >= 9) 1285 + { 1286 + alt = lua_toboolean(lua, 9); 1287 + } 1288 + } 1289 + } 1290 + } 1291 + } 1292 + } 1293 + 1294 + if(scale == 0) 1295 + { 1296 + lua_pushinteger(lua, 0); 1297 + return 1; 1298 + } 1299 + 1300 + s32 size = core->api.font(tic, text, x, y, &chromakey, 1, width, height, fixed, scale, alt); 1301 + 1302 + lua_pushinteger(lua, size); 1303 + 1304 + return 1; 1305 + } 1306 + 1307 + return 0; 1308 + } 1309 + 1310 + static s32 lua_print(lua_State* lua) 1311 + { 1312 + s32 top = lua_gettop(lua); 1313 + 1314 + if(top >= 1) 1315 + { 1316 + tic_core* core = getLuaCore(lua); 1317 + tic_mem* tic = (tic_mem*)core; 1318 + 1319 + s32 x = 0; 1320 + s32 y = 0; 1321 + s32 color = TIC_DEFAULT_COLOR; 1322 + bool fixed = false; 1323 + s32 scale = 1; 1324 + bool alt = false; 1325 + 1326 + const char* text = printString(lua, 1); 1327 + 1328 + if(top >= 3) 1329 + { 1330 + x = getLuaNumber(lua, 2); 1331 + y = getLuaNumber(lua, 3); 1332 + 1333 + if(top >= 4) 1334 + { 1335 + color = getLuaNumber(lua, 4) % TIC_PALETTE_SIZE; 1336 + 1337 + if(top >= 5) 1338 + { 1339 + fixed = lua_toboolean(lua, 5); 1340 + 1341 + if(top >= 6) 1342 + { 1343 + scale = getLuaNumber(lua, 6); 1344 + 1345 + if(top >= 7) 1346 + { 1347 + alt = lua_toboolean(lua, 7); 1348 + } 1349 + } 1350 + } 1351 + } 1352 + } 1353 + 1354 + if(scale == 0) 1355 + { 1356 + lua_pushinteger(lua, 0); 1357 + return 1; 1358 + } 1359 + 1360 + s32 size = core->api.print(tic, text ? text : "nil", x, y, color, fixed, scale, alt); 1361 + 1362 + lua_pushinteger(lua, size); 1363 + 1364 + return 1; 1365 + } 1366 + 1367 + return 0; 1368 + } 1369 + 1370 + static s32 lua_trace(lua_State *lua) 1371 + { 1372 + s32 top = lua_gettop(lua); 1373 + tic_core* core = getLuaCore(lua); 1374 + tic_mem* tic = (tic_mem*)core; 1375 + 1376 + if(top >= 1) 1377 + { 1378 + const char* text = printString(lua, 1); 1379 + u8 color = TIC_DEFAULT_COLOR; 1380 + 1381 + if(top >= 2) 1382 + { 1383 + color = getLuaNumber(lua, 2); 1384 + } 1385 + 1386 + core->api.trace(tic, text, color); 1387 + } 1388 + else luaL_error(lua, "invalid params, trace(text,[color])\n"); 1389 + 1390 + return 0; 1391 + } 1392 + 1393 + static s32 lua_pmem(lua_State *lua) 1394 + { 1395 + s32 top = lua_gettop(lua); 1396 + tic_core* core = getLuaCore(lua); 1397 + tic_mem* tic = &core->memory; 1398 + 1399 + if(top >= 1) 1400 + { 1401 + u32 index = getLuaNumber(lua, 1); 1402 + 1403 + if(index < TIC_PERSISTENT_SIZE) 1404 + { 1405 + u32 val = core->api.pmem(tic, index, 0, false); 1406 + 1407 + if(top >= 2) 1408 + { 1409 + core->api.pmem(tic, index, (u32)lua_tointeger(lua, 2), true); 1410 + } 1411 + 1412 + lua_pushinteger(lua, val); 1413 + 1414 + return 1; 1415 + } 1416 + 1417 + luaL_error(lua, "invalid persistent tic index\n"); 1418 + } 1419 + else luaL_error(lua, "invalid params, pmem(index [val]) -> val\n"); 1420 + 1421 + return 0; 1422 + } 1423 + 1424 + static s32 lua_time(lua_State *lua) 1425 + { 1426 + tic_core* core = getLuaCore(lua); 1427 + tic_mem* tic = (tic_mem*)core; 1428 + 1429 + lua_pushnumber(lua, core->api.time(tic)); 1430 + 1431 + return 1; 1432 + } 1433 + 1434 + static s32 lua_tstamp(lua_State *lua) 1435 + { 1436 + tic_core* core = getLuaCore(lua); 1437 + tic_mem* tic = (tic_mem*)core; 1438 + 1439 + lua_pushnumber(lua, core->api.tstamp(tic)); 1440 + 1441 + return 1; 1442 + } 1443 + 1444 + static s32 lua_exit(lua_State *lua) 1445 + { 1446 + tic_core* core = getLuaCore(lua); 1447 + tic_mem* tic = (tic_mem*)core; 1448 + 1449 + core->api.exit(tic); 1450 + 1451 + return 0; 1452 + } 1453 + 1454 + static s32 lua_mouse(lua_State *lua) 1455 + { 1456 + tic_core* core = getLuaCore(lua); 1457 + 1458 + { 1459 + tic_point pos = core->api.mouse((tic_mem*)core); 1460 + 1461 + lua_pushinteger(lua, pos.x); 1462 + lua_pushinteger(lua, pos.y); 1463 + } 1464 + 1465 + const tic80_mouse* mouse = &core->memory.ram->input.mouse; 1466 + 1467 + lua_pushboolean(lua, mouse->left); 1468 + lua_pushboolean(lua, mouse->middle); 1469 + lua_pushboolean(lua, mouse->right); 1470 + lua_pushinteger(lua, mouse->scrollx); 1471 + lua_pushinteger(lua, mouse->scrolly); 1472 + 1473 + return 7; 1474 + } 1475 + 1476 + static s32 lua_fget(lua_State* lua) 1477 + { 1478 + tic_core* core = getLuaCore(lua); 1479 + tic_mem* tic = (tic_mem*)core; 1480 + s32 top = lua_gettop(lua); 1481 + 1482 + if(top >= 1) 1483 + { 1484 + u32 index = getLuaNumber(lua, 1); 1485 + 1486 + if(top >= 2) 1487 + { 1488 + u32 flag = getLuaNumber(lua, 2); 1489 + lua_pushboolean(lua, core->api.fget(tic, index, flag)); 1490 + return 1; 1491 + } 1492 + } 1493 + 1494 + luaL_error(lua, "invalid params, fget(sprite,flag)\n"); 1495 + 1496 + return 0; 1497 + } 1498 + 1499 + static s32 lua_fset(lua_State* lua) 1500 + { 1501 + tic_core* core = getLuaCore(lua); 1502 + tic_mem* tic = (tic_mem*)core; 1503 + s32 top = lua_gettop(lua); 1504 + 1505 + if(top >= 1) 1506 + { 1507 + u32 index = getLuaNumber(lua, 1); 1508 + 1509 + if(top >= 2) 1510 + { 1511 + u32 flag = getLuaNumber(lua, 2); 1512 + 1513 + if(top >= 3) 1514 + { 1515 + bool value = lua_toboolean(lua, 3); 1516 + core->api.fset(tic, index, flag, value); 1517 + return 0; 1518 + } 1519 + } 1520 + } 1521 + 1522 + luaL_error(lua, "invalid params, fset(sprite,flag,value)\n"); 1523 + 1524 + return 0; 1525 + } 1526 + 1527 + static s32 lua_dofile(lua_State *lua) 1528 + { 1529 + luaL_error(lua, "unknown method: \"dofile\"\n"); 1530 + 1531 + return 0; 1532 + } 1533 + 1534 + static s32 lua_loadfile(lua_State *lua) 1535 + { 1536 + luaL_error(lua, "unknown method: \"loadfile\"\n"); 1537 + 1538 + return 0; 1539 + } 1540 + 1541 + void luaapi_open(lua_State *lua) 1542 + { 1543 + static const luaL_Reg loadedlibs[] = 1544 + { 1545 + { "_G", luaopen_base }, 1546 + { LUA_LOADLIBNAME, luaopen_package }, 1547 + { LUA_COLIBNAME, luaopen_coroutine }, 1548 + { LUA_TABLIBNAME, luaopen_table }, 1549 + { LUA_STRLIBNAME, luaopen_string }, 1550 + { LUA_MATHLIBNAME, luaopen_math }, 1551 + { LUA_DBLIBNAME, luaopen_debug }, 1552 + { NULL, NULL } 1553 + }; 1554 + 1555 + for (const luaL_Reg *lib = loadedlibs; lib->func; lib++) 1556 + { 1557 + luaL_requiref(lua, lib->name, lib->func, 1); 1558 + lua_pop(lua, 1); 1559 + } 1560 + } 1561 + 1562 + void luaapi_init(tic_core* core) 1563 + { 1564 + static const struct{lua_CFunction func; const char* name;} ApiItems[] = 1565 + { 1566 + #define API_FUNC_DEF(name, ...) {lua_ ## name, #name}, 1567 + TIC_API_LIST(API_FUNC_DEF) 1568 + #undef API_FUNC_DEF 1569 + 1570 + #if defined(BUILD_DEPRECATED) 1571 + {lua_textri, "textri"}, 1572 + #endif 1573 + }; 1574 + 1575 + for (s32 i = 0; i < COUNT_OF(ApiItems); i++) 1576 + registerLuaFunction(core, ApiItems[i].func, ApiItems[i].name); 1577 + 1578 + registerLuaFunction(core, lua_dofile, "dofile"); 1579 + registerLuaFunction(core, lua_loadfile, "loadfile"); 1580 + } 1581 + 1582 + void luaapi_close(tic_mem* tic) 1583 + { 1584 + tic_core* core = (tic_core*)tic; 1585 + 1586 + if(core->currentVM) 1587 + { 1588 + lua_close(core->currentVM); 1589 + core->currentVM = NULL; 1590 + } 1591 + } 1592 + 1593 + /* 1594 + ** Message handler which appends stract trace to exceptions. 1595 + ** This function was extractred from lua.c. 1596 + */ 1597 + static s32 msghandler (lua_State *lua) 1598 + { 1599 + const char *msg = lua_tostring(lua, 1); 1600 + if (msg == NULL) /* is error object not a string? */ 1601 + { 1602 + if (luaL_callmeta(lua, 1, "__tostring") && /* does it have a metamethod */ 1603 + lua_type(lua, -1) == LUA_TSTRING) /* that produces a string? */ 1604 + return 1; /* that is the message */ 1605 + else 1606 + msg = lua_pushfstring(lua, "(error object is a %s value)", luaL_typename(lua, 1)); 1607 + } 1608 + luaL_traceback(lua, lua, msg, 1); /* append a standard traceback */ 1609 + return 1; /* return the traceback */ 1610 + } 1611 + 1612 + /* 1613 + ** Interface to 'lua_pcall', which sets appropriate message handler function. 1614 + ** Please use this function for all top level lua functions. 1615 + ** This function was extractred from lua.c (and stripped of signal handling) 1616 + */ 1617 + static s32 docall (lua_State *lua, s32 narg, s32 nres) 1618 + { 1619 + s32 status = 0; 1620 + s32 base = lua_gettop(lua) - narg; /* function index */ 1621 + lua_pushcfunction(lua, msghandler); /* push message handler */ 1622 + lua_insert(lua, base); /* put it under function and args */ 1623 + status = lua_pcall(lua, narg, nres, base); 1624 + lua_remove(lua, base); /* remove message handler from the stack */ 1625 + return status; 1626 + } 1627 + 1628 + void luaapi_tick(tic_mem* tic) 1629 + { 1630 + tic_core* core = (tic_core*)tic; 1631 + 1632 + lua_State* lua = core->currentVM; 1633 + 1634 + if(lua) 1635 + { 1636 + lua_getglobal(lua, TIC_FN); 1637 + if(lua_isfunction(lua, -1)) 1638 + { 1639 + if(docall(lua, 0, 0) != LUA_OK) 1640 + { 1641 + core->data->error(core->data->data, lua_tostring(lua, -1)); 1642 + return; 1643 + } 1644 + 1645 + #if defined(BUILD_DEPRECATED) 1646 + // call OVR() callback for backward compatibility 1647 + { 1648 + lua_getglobal(lua, OVR_FN); 1649 + if(lua_isfunction(lua, -1)) 1650 + { 1651 + OVR(core) 1652 + { 1653 + if(docall(lua, 0, 0) != LUA_OK) 1654 + core->data->error(core->data->data, lua_tostring(lua, -1)); 1655 + } 1656 + } 1657 + else lua_pop(lua, 1); 1658 + } 1659 + #endif 1660 + } 1661 + else 1662 + { 1663 + lua_pop(lua, 1); 1664 + core->data->error(core->data->data, "'function TIC()...' isn't found :("); 1665 + } 1666 + } 1667 + } 1668 + 1669 + void callLuaIntCallback(tic_mem* tic, s32 value, void* data, const char* name) 1670 + { 1671 + tic_core* core = (tic_core*)tic; 1672 + lua_State* lua = core->currentVM; 1673 + 1674 + if (lua) 1675 + { 1676 + lua_getglobal(lua, name); 1677 + if(lua_isfunction(lua, -1)) 1678 + { 1679 + lua_pushinteger(lua, value); 1680 + if(docall(lua, 1, 0) != LUA_OK) 1681 + core->data->error(core->data->data, lua_tostring(lua, -1)); 1682 + } 1683 + else lua_pop(lua, 1); 1684 + } 1685 + } 1686 + 1687 + void luaapi_scn(tic_mem* tic, s32 row, void* data) 1688 + { 1689 + callLuaIntCallback(tic, row, data, SCN_FN); 1690 + 1691 + // try to call old scanline 1692 + callLuaIntCallback(tic, row, data, "scanline"); 1693 + } 1694 + 1695 + void luaapi_bdr(tic_mem* tic, s32 row, void* data) 1696 + { 1697 + callLuaIntCallback(tic, row, data, BDR_FN); 1698 + } 1699 + 1700 + void luaapi_menu(tic_mem* tic, s32 index, void* data) 1701 + { 1702 + callLuaIntCallback(tic, index, data, MENU_FN); 1703 + } 1704 + 1705 + void luaapi_boot(tic_mem* tic) 1706 + { 1707 + tic_core* core = (tic_core*)tic; 1708 + lua_State* lua = core->currentVM; 1709 + 1710 + if (lua) 1711 + { 1712 + lua_getglobal(lua, BOOT_FN); 1713 + if(lua_isfunction(lua, -1)) 1714 + { 1715 + if(docall(lua, 0, 0) != LUA_OK) 1716 + core->data->error(core->data->data, lua_tostring(lua, -1)); 1717 + } 1718 + else lua_pop(lua, 1); 1719 + } 1720 + }
+11 -11
src/api/moonscript.c
··· 21 21 // SOFTWARE. 22 22 23 23 #include "core/core.h" 24 - #include "lua_api.h" 24 + #include "luaapi.h" 25 25 26 26 static const char _ms_loadstring[] = "_ms_loadstring"; 27 27 ··· 77 77 static bool initMoonscript(tic_mem* tic, const char* code) 78 78 { 79 79 tic_core* core = (tic_core*)tic; 80 - closeLua(tic); 80 + luaapi_close(tic); 81 81 82 82 lua_State* lua = core->currentVM = luaL_newstate(); 83 - lua_open_builtins(lua); 83 + luaapi_open(lua); 84 84 85 85 luaopen_lpeg(lua); 86 86 setloaded(lua, "lpeg"); 87 87 88 - initLuaAPI(core); 88 + luaapi_init(core); 89 89 90 90 { 91 91 lua_State* moon = lua; ··· 196 196 #include "../build/assets/moonmark.tic.dat" 197 197 }; 198 198 199 - const tic_script EXPORT_SCRIPT(Moon) = 199 + TIC_EXPORT const tic_script EXPORT_SCRIPT(Moon) = 200 200 { 201 201 .id = 13, 202 202 .name = "moon", ··· 204 204 .projectComment = "--", 205 205 { 206 206 .init = initMoonscript, 207 - .close = closeLua, 208 - .tick = callLuaTick, 209 - .boot = callLuaBoot, 207 + .close = luaapi_close, 208 + .tick = luaapi_tick, 209 + .boot = luaapi_boot, 210 210 211 211 .callback = 212 212 { 213 - .scanline = callLuaScanline, 214 - .border = callLuaBorder, 215 - .menu = callLuaMenu, 213 + .scanline = luaapi_scn, 214 + .border = luaapi_bdr, 215 + .menu = luaapi_menu, 216 216 }, 217 217 }, 218 218
+1 -1
src/api/mruby.c
··· 1226 1226 #include "../build/assets/rubymark.tic.dat" 1227 1227 }; 1228 1228 1229 - const tic_script EXPORT_SCRIPT(Ruby) = 1229 + TIC_EXPORT const tic_script EXPORT_SCRIPT(Ruby) = 1230 1230 { 1231 1231 .id = 11, 1232 1232 .name = "ruby",
+1 -1
src/api/python.c
··· 1527 1527 #include "../build/assets/pythonmark.tic.dat" 1528 1528 }; 1529 1529 1530 - PK_EXPORT const tic_script EXPORT_SCRIPT(Python) = 1530 + TIC_EXPORT const tic_script EXPORT_SCRIPT(Python) = 1531 1531 { 1532 1532 .id = 20, 1533 1533 .name = "python",
+1 -1
src/api/scheme.c
··· 1028 1028 #include "../build/assets/schememark.tic.dat" 1029 1029 }; 1030 1030 1031 - const tic_script EXPORT_SCRIPT(Scheme) = 1031 + TIC_EXPORT const tic_script EXPORT_SCRIPT(Scheme) = 1032 1032 { 1033 1033 .id = 19, 1034 1034 .name = "scheme",
+1 -1
src/api/squirrel.c
··· 1858 1858 #include "../build/assets/squirrelmark.tic.dat" 1859 1859 }; 1860 1860 1861 - const tic_script EXPORT_SCRIPT(Squirrel) = 1861 + TIC_EXPORT const tic_script EXPORT_SCRIPT(Squirrel) = 1862 1862 { 1863 1863 .id = 15, 1864 1864 .name = "squirrel",
+1 -1
src/api/wasm.c
··· 1322 1322 #include "../build/assets/wasmmark.tic.dat" 1323 1323 }; 1324 1324 1325 - const tic_script EXPORT_SCRIPT(Wasm) = 1325 + TIC_EXPORT const tic_script EXPORT_SCRIPT(Wasm) = 1326 1326 { 1327 1327 .id = 17, 1328 1328 .name = "wasm",
+1 -1
src/api/wren.c
··· 1829 1829 #include "../build/assets/wrenmark.tic.dat" 1830 1830 }; 1831 1831 1832 - const tic_script EXPORT_SCRIPT(Wren) = 1832 + TIC_EXPORT const tic_script EXPORT_SCRIPT(Wren) = 1833 1833 { 1834 1834 .id = 16, 1835 1835 .name = "wren",