From 30db4d7004a322b248362d7a95026d6dcd520e6e Mon Sep 17 00:00:00 2001 From: Lucas Scharenbroich Date: Wed, 27 Jul 2022 00:21:21 -0500 Subject: [PATCH] Get C demo functional --- demos/danmalec/.gitignore | 5 + demos/danmalec/_FileInformation.txt | 1 + demos/danmalec/build-image.bat | 17 ++++ demos/danmalec/demo_data.c | 144 +++++++++++++++++++++++++++ demos/danmalec/demo_data.h | 16 +++ demos/danmalec/gte.h | 79 +++++++++++++++ demos/danmalec/gte_user.h | 80 +++++++++++++++ demos/danmalec/main.c | 148 ++++++++++++++++++++++++++++ demos/danmalec/main.h | 6 ++ demos/danmalec/main.r | 10 ++ demos/danmalec/package.json | 21 ++++ 11 files changed, 527 insertions(+) create mode 100644 demos/danmalec/.gitignore create mode 100644 demos/danmalec/_FileInformation.txt create mode 100644 demos/danmalec/build-image.bat create mode 100644 demos/danmalec/demo_data.c create mode 100644 demos/danmalec/demo_data.h create mode 100644 demos/danmalec/gte.h create mode 100644 demos/danmalec/gte_user.h create mode 100644 demos/danmalec/main.c create mode 100644 demos/danmalec/main.h create mode 100644 demos/danmalec/main.r create mode 100644 demos/danmalec/package.json diff --git a/demos/danmalec/.gitignore b/demos/danmalec/.gitignore new file mode 100644 index 0000000..1d083a2 --- /dev/null +++ b/demos/danmalec/.gitignore @@ -0,0 +1,5 @@ +App +main +*.root +*.sym +*.a \ No newline at end of file diff --git a/demos/danmalec/_FileInformation.txt b/demos/danmalec/_FileInformation.txt new file mode 100644 index 0000000..73c1cca --- /dev/null +++ b/demos/danmalec/_FileInformation.txt @@ -0,0 +1 @@ +App=Type(B3),AuxType(0000),VersionCreate(70),MinVersion(BE),Access(E3) \ No newline at end of file diff --git a/demos/danmalec/build-image.bat b/demos/danmalec/build-image.bat new file mode 100644 index 0000000..9a60679 --- /dev/null +++ b/demos/danmalec/build-image.bat @@ -0,0 +1,17 @@ +echo off + +REM Copy all of the assets into the ProDOS image for emulator testing +REM +REM Pass the path of the Cadius tool as the first argument (%1) + +set CADIUS="%1" +set IMAGE="..\\..\\emu\\Target.2mg" +set FOLDER="/GTEDEV/DanMalec" + +REM Cadius does not overwrite files, so clear the root folder first +%CADIUS% DELETEFOLDER %IMAGE% %FOLDER% +%CADIUS% CREATEFOLDER %IMAGE% %FOLDER% + +REM Now copy files and folders as needed +%CADIUS% ADDFILE %IMAGE% %FOLDER% .\App +%CADIUS% ADDFILE %IMAGE% %FOLDER% ..\..\src\Tool160 diff --git a/demos/danmalec/demo_data.c b/demos/danmalec/demo_data.c new file mode 100644 index 0000000..8eeb17f --- /dev/null +++ b/demos/danmalec/demo_data.c @@ -0,0 +1,144 @@ +/* ******************************************************************** + + Demo Data contains data structures for demonstrating calling GTE from + ORCA/C. This contains palette and tile information. + + ********************************************************************* */ + +#include "demo_data.h" + + +Byte tiles[128 * 3] = { + // Initial special empty tile + // Normal + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + // Mask + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + // Flipped + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + // Flipped Mask + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + // Tile ID 1 + // Normal + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x33, 0x03, 0x30, + 0x00, 0x05, 0x05, 0x00, + 0x00, 0x08, 0x08, 0x00, + 0x00, 0x02, 0x02, 0x00, + 0x00, 0x07, 0x07, 0x00, + 0x00, 0x44, 0x04, 0x40, + 0x00, 0x00, 0x00, 0x00, + + // Mask + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + // Flipped + 0x00, 0x00, 0x00, 0x00, + 0x03, 0x30, 0x33, 0x00, + 0x00, 0x50, 0x50, 0x00, + 0x00, 0x80, 0x80, 0x00, + 0x00, 0x20, 0x20, 0x00, + 0x00, 0x70, 0x70, 0x00, + 0x04, 0x40, 0x44, 0x00, + 0x00, 0x00, 0x00, 0x00, + + // Flipped Mask + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + // Tile ID 2 + // Normal + 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, + 0x11, 0x00, 0x00, 0x11, + 0x11, 0x00, 0x00, 0x11, + 0x11, 0x00, 0x00, 0x11, + 0x11, 0x00, 0x00, 0x11, + 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, + + // Mask + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + // Flipped + 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, + 0x11, 0x00, 0x00, 0x11, + 0x11, 0x00, 0x00, 0x11, + 0x11, 0x00, 0x00, 0x11, + 0x11, 0x00, 0x00, 0x11, + 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, + + // Flipped Mask + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + + +// 16 Entry palette, where each entry is in the format: +// 0x0RGB +Word palette[16] = { + 0x0000, 0x0FFF, 0x0F00, 0x00F0, + 0x000F, 0x0FF0, 0x00FF, 0x0F0F, + 0x0F70, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; \ No newline at end of file diff --git a/demos/danmalec/demo_data.h b/demos/danmalec/demo_data.h new file mode 100644 index 0000000..bf76527 --- /dev/null +++ b/demos/danmalec/demo_data.h @@ -0,0 +1,16 @@ +/* ******************************************************************** + + Demo Data contains data structures for demonstrating calling GTE from + ORCA/C. This contains palette and tile information. + ********************************************************************* */ + +#ifndef _GUARD_PROJECTGTETest1_FILEdemo_data_ +#define _GUARD_PROJECTGTETest1_FILEdemo_data_ + +#include + + +extern Byte tiles[128 * 3]; +extern Word palette[16]; + +#endif /* define _GUARD_PROJECTGTETest1_FILEdemo_data_ */ \ No newline at end of file diff --git a/demos/danmalec/gte.h b/demos/danmalec/gte.h new file mode 100644 index 0000000..10c2f7b --- /dev/null +++ b/demos/danmalec/gte.h @@ -0,0 +1,79 @@ +/* ******************************************************************** + + GTE is copyright Lucas Scharenbroich and licensed under the Apache-2.0 + License. + + The following GTE function definitions are taken from the GTE Toolbox + documentation: + https://lscharen.github.io/iigs-game-engine/toolboxref.html + + And from the GTE Macros: + https://github.com/lscharen/iigs-game-engine/blob/d7be9f1be44748b0180c930b1f90b144cda661ea/macros/GTE.Macs.s + + The contents of this file are a derivite work from GTE intended to + ease the process of calling GTE / Tool 160 from ORCA/C and are believed + to be permitted under the terms of the Apache-2.0 License. + + ********************************************************************* */ + +#ifndef _GTE_HEADER_INCLUDE_ +#define _GTE_HEADER_INCLUDE_ + + +/* GTE Housekeeping Routines */ +extern pascal void GTEBootInit(void) inline(0x01A0, dispatcher); +extern pascal void GTEStartUp(Word dPageAddr, Word capFlags, Word userID) inline(0x02A0, dispatcher); +extern pascal void GTEShutDown(void) inline(0x03A0, dispatcher); +extern pascal Word GTEVersion(void) inline(0x04A0, dispatcher); +extern pascal void GTEReset(void) inline(0x05A0, dispatcher); +extern pascal Word GTEStatus(void) inline(0x06A0, dispatcher); + + +/* GTE Sprite Routines */ +extern pascal void GTECreateSpriteStamp(Word spriteDescriptor, Word vBuffAddr) inline(0x0FA0, dispatcher); +extern pascal void GTEAddSprite(Word spriteSlot, Word spriteFlags, Word vBuffAddr, Word x, Word y) inline(0x10A0, dispatcher); +extern pascal void GTEMoveSprite(Word spriteSlot, Word x, Word y) inline(0x11A0, dispatcher); +extern pascal void GTEUpdateSprite(Word spriteSlot, Word spriteFlags, Word vBuffAddr) inline(0x12A0, dispatcher); +extern pascal void GTERemoveSprite(Word spriteSlot) inline(0x13A0, dispatcher); + + +/* GTE Tile Routines */ +extern pascal void GTELoadTileSet(Pointer tileSetPtr) inline(0x0EA0, dispatcher); +extern pascal void GTEFillTileStore(Word tileID) inline(0x25A0, dispatcher); + + +/* GTE Primary Background Routines */ +extern pascal void GTESetBG0Origin(Word x, Word y) inline(0x0CA0, dispatcher); +extern pascal void GTERender(Word flags) inline(0x0DA0, dispatcher); + + +/* GTE Global State Functions */ +extern pascal void GTESetScreenMode(Word width, Word height) inline(0x0AA0, dispatcher); +extern pascal void GTESetPalette(Word palNum, Pointer palettePtr) inline(0x16A0, dispatcher); + + +/* GTE Misc. Functions */ +extern pascal Word GTEReadControl(void) inline(0x09A0, dispatcher); +extern pascal Word GTEGetSeconds(void) inline(0x14A0, dispatcher); + + +/* GTE Sprite Constants */ +#define GTE_SPRITE_HIDE 0x2000 +#define GTE_SPRITE_16X16 0x1800 +#define GTE_SPRITE_16X8 0x1000 +#define GTE_SPRITE_8X16 0x0800 +#define GTE_SPRITE_8X8 0x0000 +#define GTE_SPRITE_VFLIP 0x0400 +#define GTE_SPRITE_HFLIP 0x0200 + + +/* GTE Sprint Stamp Storage Parameters */ +#define GTE_VBUFF_STRIDE_BYTES (12 * 4) /* Each line has 4 slots of 16 pixels + 8 buffer pixels */ +#define GTE_VBUFF_TILE_ROW_BYTES (8 * GTE_VBUFF_STRIDE_BYTES) /* Each row is comprised of 8 lines */ +#define GTE_VBUFF_TILE_COL_BYTES (4) +#define GTE_VBUFF_SPRITE_STEP (GTE_VBUFF_TILE_ROW_BYTES*3) /* Allocate space for 16 rows + 8 rows of buffer */ +#define GTE_VBUFF_SPRITE_START (GTE_VBUFF_TILE_ROW_BYTES+4) /* Start at an offset so $0000 can be used as an empty value */ +#define GTE_VBUFF_SLOT_COUNT (48) /* Have space for this many stamps */ + + +#endif /* _GTE_HEADER_INCLUDE_ */ \ No newline at end of file diff --git a/demos/danmalec/gte_user.h b/demos/danmalec/gte_user.h new file mode 100644 index 0000000..ef51da0 --- /dev/null +++ b/demos/danmalec/gte_user.h @@ -0,0 +1,80 @@ +/* ******************************************************************** + + GTE is copyright Lucas Scharenbroich and licensed under the Apache-2.0 + License. + + The following GTE function definitions are taken from the GTE Toolbox + documentation: + https://lscharen.github.io/iigs-game-engine/toolboxref.html + + And from the GTE Macros: + https://github.com/lscharen/iigs-game-engine/blob/d7be9f1be44748b0180c930b1f90b144cda661ea/macros/GTE.Macs.s + + The contents of this file are a derivite work from GTE intended to + ease the process of calling GTE / Tool 160 from ORCA/C and are believed + to be permitted under the terms of the Apache-2.0 License. + + ********************************************************************* */ + +#ifndef _GTE_HEADER_INCLUDE_ +#define _GTE_HEADER_INCLUDE_ + +#define usertool 0xE10008L + +/* GTE Housekeeping Routines */ +extern pascal void GTEBootInit(void) inline(0x01A0, usertool); +extern pascal void GTEStartUp(Word dPageAddr, Word capFlags, Word userID) inline(0x02A0, usertool); +extern pascal void GTEShutDown(void) inline(0x03A0, usertool); +extern pascal Word GTEVersion(void) inline(0x04A0, usertool); +extern pascal void GTEReset(void) inline(0x05A0, usertool); +extern pascal Word GTEStatus(void) inline(0x06A0, usertool); + + +/* GTE Sprite Routines */ +extern pascal void GTECreateSpriteStamp(Word spriteDescriptor, Word vBuffAddr) inline(0x0FA0, usertool); +extern pascal void GTEAddSprite(Word spriteSlot, Word spriteFlags, Word vBuffAddr, Word x, Word y) inline(0x10A0, usertool); +extern pascal void GTEMoveSprite(Word spriteSlot, Word x, Word y) inline(0x11A0, usertool); +extern pascal void GTEUpdateSprite(Word spriteSlot, Word spriteFlags, Word vBuffAddr) inline(0x12A0, usertool); +extern pascal void GTERemoveSprite(Word spriteSlot) inline(0x13A0, usertool); + + +/* GTE Tile Routines */ +extern pascal void GTELoadTileSet(Pointer tileSetPtr) inline(0x0EA0, usertool); +extern pascal void GTEFillTileStore(Word tileID) inline(0x25A0, usertool); + + +/* GTE Primary Background Routines */ +extern pascal void GTESetBG0Origin(Word x, Word y) inline(0x0CA0, usertool); +extern pascal void GTERender(Word flags) inline(0x0DA0, usertool); + + +/* GTE Global State Functions */ +extern pascal void GTESetScreenMode(Word width, Word height) inline(0x0AA0, usertool); +extern pascal void GTESetPalette(Word palNum, Pointer palettePtr) inline(0x16A0, usertool); + + +/* GTE Misc. Functions */ +extern pascal Word GTEReadControl(void) inline(0x09A0, usertool); +extern pascal Word GTEGetSeconds(void) inline(0x14A0, usertool); + + +/* GTE Sprite Constants */ +#define GTE_SPRITE_HIDE 0x2000 +#define GTE_SPRITE_16X16 0x1800 +#define GTE_SPRITE_16X8 0x1000 +#define GTE_SPRITE_8X16 0x0800 +#define GTE_SPRITE_8X8 0x0000 +#define GTE_SPRITE_VFLIP 0x0400 +#define GTE_SPRITE_HFLIP 0x0200 + + +/* GTE Sprint Stamp Storage Parameters */ +#define GTE_VBUFF_STRIDE_BYTES (12 * 4) /* Each line has 4 slots of 16 pixels + 8 buffer pixels */ +#define GTE_VBUFF_TILE_ROW_BYTES (8 * GTE_VBUFF_STRIDE_BYTES) /* Each row is comprised of 8 lines */ +#define GTE_VBUFF_TILE_COL_BYTES (4) +#define GTE_VBUFF_SPRITE_STEP (GTE_VBUFF_TILE_ROW_BYTES*3) /* Allocate space for 16 rows + 8 rows of buffer */ +#define GTE_VBUFF_SPRITE_START (GTE_VBUFF_TILE_ROW_BYTES+4) /* Start at an offset so $0000 can be used as an empty value */ +#define GTE_VBUFF_SLOT_COUNT (48) /* Have space for this many stamps */ + + +#endif /* _GTE_HEADER_INCLUDE_ */ \ No newline at end of file diff --git a/demos/danmalec/main.c b/demos/danmalec/main.c new file mode 100644 index 0000000..1060732 --- /dev/null +++ b/demos/danmalec/main.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include +#include + +#include "main.h" +#include "gte_user.h" +#include "demo_data.h" + +#define TOOLFAIL(string) if (toolerror()) SysFailMgr(toolerror(), "\p" string "\n\r Error Code -> $"); + +typedef struct PString { + byte length; + char text[32]; +} PString; + +PString toolPath = {9, "1/Tool160" }; + +void LoadGTEToolSet(Word userId) { + InitialLoadOutputRec loadRec; + + // Load the tool from the local directory + loadRec = InitialLoad(userId, (Pointer) (&toolPath), 1); + TOOLFAIL("Unable to load Tool160 from local path"); + + // Install the tool using the system tool vector + SetTSPtr(0x8000, 160, loadRec.startAddr); + TOOLFAIL("Could not install tool"); +} + +#define SPRITE_SLOT 0 +#define SPRITE_VBUFF (GTE_VBUFF_SPRITE_START+0*GTE_VBUFF_SPRITE_STEP) + +int main (void) { + Word controlMask; + Word keyPress; + Word userId; + Handle dpHndl; + Word dpWord; + Word x = 0, y = 0; + Word px = 0, py = 0; + Word sec, lastSec = 0; + + TLStartUp(); + TOOLFAIL("Unable to start tool locator"); + + userId = MMStartUp(); + TOOLFAIL("Unable to start memory manager"); + + MTStartUp(); + TOOLFAIL("Unable to start misc tools"); + + /* If GTE is installed in System:Tools use this and switch to "gte.h" */ + /* + LoadOneTool(160, 0); + TOOLFAIL("Unable to load GTE toolset"); + */ + + /* If GTE is installed with the application, use this and "gte_user.h" */ + LoadGTEToolSet(userId); + + dpHndl = NewHandle(0x0200, userId, 0x4015, 0); + if (dpHndl == NULL) { + TOOLFAIL("Unable to allocate page 0 memory"); + } + dpWord = (Word)(*dpHndl); + if ((dpWord & 0x00FF) != 0x0000) { + TOOLFAIL("Allocated page 0 memory is not aligned"); + } + + GTEStartUp(dpWord, 0x0000, userId); + TOOLFAIL("Unable to start GTE"); + + GTESetScreenMode(160, 200); + GTELoadTileSet(tiles); + GTESetPalette(0, (Pointer)palette); + GTEFillTileStore(1); + + GTECreateSpriteStamp(GTE_SPRITE_8X8|2, SPRITE_VBUFF); + GTEAddSprite(SPRITE_SLOT, 0, SPRITE_VBUFF, px, py); + + do { + controlMask = GTEReadControl(); + keyPress = controlMask & 0x007F; + + switch (keyPress) { + case 'a': if (x > 0) { + x--; + break; + } + case 'd': if (x < 1000) { + x++; + break; + } + case 'w': if (y > 0) { + y--; + break; + } + case 's': if (y < 1000) { + y++; + break; + } + + + case 'j': if (px > 0) { + px--; + break; + } + case 'l': if (px < 154) { + px++; + break; + } + case 'i': if (py > 0) { + py--; + break; + } + case 'k': if (py < 192) { + py++; + break; + } + } + + sec = GTEGetSeconds(); + if (sec != lastSec) { + lastSec = sec; + GTEFillTileStore(1 + (lastSec & 1)); + } + + GTESetBG0Origin(x, y); + GTEMoveSprite(SPRITE_SLOT, px, py); + GTERender(0); + + } while (keyPress != 'q' && keyPress != 'Q'); + + GTEShutDown(); + + DisposeHandle(dpHndl); + + MTShutDown(); + TOOLFAIL("Unable to shutdown misc tool"); + + MMShutDown(userId); + TOOLFAIL("Unable to shutdown memory manager"); + + TLShutDown(); + TOOLFAIL("Unable to shutdown tool locator"); +} \ No newline at end of file diff --git a/demos/danmalec/main.h b/demos/danmalec/main.h new file mode 100644 index 0000000..c7346d6 --- /dev/null +++ b/demos/danmalec/main.h @@ -0,0 +1,6 @@ +#ifndef _GUARD_PROJECTGTETest1_FILEmain_ +#define _GUARD_PROJECTGTETest1_FILEmain_ + +#define rez_tools 1 + +#endif /* defined(_GUARD_PROJECTGTETest1_FILEmain_) */ diff --git a/demos/danmalec/main.r b/demos/danmalec/main.r new file mode 100644 index 0000000..28734f6 --- /dev/null +++ b/demos/danmalec/main.r @@ -0,0 +1,10 @@ +#include "types.rez" +#include "main.h" + +resource rToolStartup (rez_tools) { + mode320, + { + 3, $0302, /* Misc Tool */ + 160, $0100 /* GTE */ + } +}; \ No newline at end of file diff --git a/demos/danmalec/package.json b/demos/danmalec/package.json new file mode 100644 index 0000000..c7ae699 --- /dev/null +++ b/demos/danmalec/package.json @@ -0,0 +1,21 @@ +{ + "name": "dan-malec-c-demo", + "version": "1.0.0", + "description": "Using GTE from C", + "main": "index.js", + "config": { + "merlin32": "C:\\Programs\\IIgsXDev\\bin\\Merlin32-1.1.10.exe", + "cadius": "C:\\Programs\\IIgsXDev\\bin\\Cadius.exe", + "gsport": "C:\\Programs\\gsport\\gsport_0.31\\GSPort.exe", + "macros": "../../macros", + "crossrunner": "C:\\Programs\\Crossrunner\\Crossrunner.exe" + }, + "scripts": { + "gsport": "%npm_package_config_gsport%", + "test": "npm run build && build-image.bat %npm_package_config_cadius% && %npm_package_config_gsport%", + "build": "npm run build:tool && npm run build:sys16", + "build:sys16": "iix compile demo_data.c main.c && iix -DKeepType=S16 link main demo_data keep=App", + "build:tool": "%npm_package_config_merlin32% -V %npm_package_config_macros% ../../src/Master.s", + "debug": "%npm_package_config_crossrunner% ./App -Debug -CompatibilityLayer" + } +}