123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642 |
- /** This is a SAF interpreter of games written in programming language comun.
- Keep in mind that unless you make a precompiled version of the game, THIS IS
- A NON-STANDARD SAF PROGRAM because it reads from a file and writes errors to
- stderr (which is normally advised not to do with SAF). However once you make
- game, you can create a precompiled version that will again be a well-behaved
- SAF program.
-
- Usage: compile this like normal SAF program. Then when ran, the program
- looks for a file named "game.cmn" which is a comun source for the game to
- interpret. The file gets compiled and interpreted. In case of error in the
- program it is written to stderr.
- To make a precompiled version copy the precompiled data that's output by this
- program to some file (e.g. compiled_data.h) and include it as a library below.
- Then compiled this again.
- To learn the comun language, see its repository. SAF binding to comun is
- intuitive: the names of functions are the same as in saf.h, parameters are
- passed via stack so that they appear in the source code in the same order as
- in the function's prototype, e.g. what in C would be
- SAF_drawLine(1,2,3,4,SAF_COLOR_BLACK) in comun is
- 1 2 3 4 SAF_COLOR_BLACK SAF_drawLine. Strings are expected to be zero
- terminated but pushed in reverse order (as is standard in comun), image data
- are also expected to be pushed in reverse order, so that image width is on
- stack top, image height is one cell below etc.). Top level code is
- initialization (what in C is inside SAF_init), loop code goes to SAF_loop
- function (just as in C). */
- #define SAF_PROGRAM_NAME "comun game"
- #include "../saf.h"
- //#include "compiled_data.h" // include precompiled data here
- #if !PRECOMPILED
- #include <stdio.h>
- #endif
- #define CMN_STRING_PSEUDOHASH_SIZE 16
- #include "comun.h"
- #define GAME_FILE_NAME "game.cmn"
- #define WORKINGMEM_SIZE 2048
- #if !PRECOMPILED
- #define BYTECODEDMEM_SIZE 4096
- uint8_t bytecodeMem[BYTECODEDMEM_SIZE];
- #endif
- uint8_t workingMem[WORKINGMEM_SIZE];
- #define HELPER_STRING_SIZE 32
- char helperString[HELPER_STRING_SIZE];
- #define HELPER_IMAGE_SIZE (16 * 16)
- uint8_t helperImage[HELPER_IMAGE_SIZE];
- #define F_BUTTON_PRESSED 0x00
- #define F_BUTTON_JUST_PRESSED 0x01
- #define F_PLAY_SOUND 0x02
- #define F_SAVE 0x03
- #define F_LOAD 0x04
- #define F_FRAME 0x05
- #define F_TIME 0x06
- #define F_RANDOM 0x07
- #define F_RANDOM_SEED 0x08
- #define F_SIN 0x09
- #define F_COS 0x0a
- #define F_SQRT 0x0b
- #define F_COLOR_FROM_RGB 0x0c
- #define F_COLOR_TO_RGB 0x0d
- #define F_COLOR_TO_GRAYSCALE 0x0e
- #define F_COLOR_TO_1BIT 0x0f
- #define F_COLOR_INVERT 0x10
- #define F_DRAW_PIXEL 0x11
- #define F_DRAW_RECT 0x12
- #define F_DRAW_LINE 0x13
- #define F_DRAW_CIRCLE 0x14
- #define F_CLEAR_SCREEN 0x15
- #define F_DRAW_TEXT 0x16
- #define F_GET_FONT_CHARACTER 0x17
- #define F_DRAW_IMAGE 0x18
- #define F_DRAW_IMAGE_COMPRESSED 0x19
- #define F_DRAW_IMAGE_1BIT 0x1a
- #define F_INT_TO_STR 0x1b
- #define F_BUTTON_UP 0x1c
- #define F_BUTTON_DOWN 0x1d
- #define F_BUTTON_LEFT 0x1e
- #define F_BUTTON_RIGHT 0x1f
- #define F_BUTTON_A 0x20
- #define F_BUTTON_B 0x21
- #define F_BUTTON_C 0x22
- #define F_COLOR_BLACK 0x23
- #define F_COLOR_WHITE 0x24
- #define F_COLOR_GRAY 0x25
- #define F_COLOR_GRAY_DARK 0x26
- #define F_COLOR_RED 0x27
- #define F_COLOR_RED_DARK 0x28
- #define F_COLOR_GREEN 0x29
- #define F_COLOR_GREEN_DARK 0x2a
- #define F_COLOR_BLUE 0x2b
- #define F_COLOR_BLUE_DARK 0x2c
- #define F_COLOR_YELLOW 0x2d
- #define F_COLOR_ORANGE 0x2e
- #define F_COLOR_BROWN 0x2f
- #define F_SOUND_BEEP 0x30
- #define F_SOUND_CLICK 0x31
- #define F_SOUND_BOOM 0x32
- #define F_SOUND_BUMP 0x33
- #define F_TRANSFORM_NONE 0x34
- #define F_TRANSFORM_ROTATE_90 0x35
- #define F_TRANSFORM_ROTATE_180 0x36
- #define F_TRANSFORM_ROTATE_270 0x37
- #define F_TRANSFORM_FLIP 0x38
- #define F_TRANSFORM_SCALE_2 0x39
- #define F_TRANSFORM_SCALE_3 0x3a
- #define F_TRANSFORM_SCALE_4 0x3b
- #define F_TRANSFORM_INVERT 0x3c
- #define F_SCREEN_WIDTH 0x3d
- #define F_SCREEN_HEIGHT 0x3e
- #define F_FPS 0x3f
- #define FUNCTIONS_TOTAL 0x40
- #if !PRECOMPILED
- int8_t functions[FUNCTIONS_TOTAL];
- CMN_Compiler compiler;
- int32_t loopFunctionID;
- #endif
- CMN_Interpreter interpreter;
- uint8_t ok = 1;
- int16_t ioFunction(int16_t x)
- {
- if (x >= 0)
- putchar(x);
- return 0;
- }
- #define CV(n) CMN_interpreterGetValue(interp,n)
- #define CPOP(n) CMN_interpreterPop(interp,n)
- #define CPUSH(n) CMN_interpreterPush(interp,n)
- void loadImage(CMN_Interpreter *interp, uint8_t *image, uint16_t maxSize,
- uint8_t mode)
- {
- image[0] = CV(0);
- image[1] = CV(1);
- CPOP(2);
- uint16_t imageLen = ((uint16_t) image[0]) * ((uint16_t) image[1]);
- if (mode == 1)
- imageLen = 16 + imageLen / 2 + ((imageLen % 2) != 0);
- else if (mode == 2)
- imageLen = imageLen / 8 + ((imageLen % 8) != 0);
- if (imageLen > maxSize - 2)
- imageLen = maxSize - 2;
- for (uint16_t i = 0; i < imageLen; ++i)
- image[2 + i] = CV(i);
-
- CPOP(imageLen);
- }
-
- void functionCall(uint16_t id, CMN_Interpreter *interp)
- {
- uint8_t x, y, z, w;
- if (id >= FUNCTIONS_TOTAL || functions[id] < 0)
- {
- fputs("ERROR: call of unknown function\n",stderr);
- ok = 0;
- return;
- }
- switch (functions[id])
- {
- case F_BUTTON_PRESSED:
- x = CV(0); CPOP(1); CPUSH(SAF_buttonPressed(x)); break;
- case F_BUTTON_JUST_PRESSED:
- x = CV(0); CPOP(1); CPUSH(SAF_buttonJustPressed(x)); break;
- case F_SAVE: x = CV(0); y = CV(1); CPOP(2); SAF_save(y,x); break;
- case F_LOAD: x = CV(0); CPOP(1); CPUSH(SAF_load(x)); break;
- case F_PLAY_SOUND: SAF_playSound(CV(0)); CPOP(1); break;
- case F_FRAME: CPUSH(SAF_frame()); break;
- case F_TIME: CPUSH(SAF_time()); break;
- case F_RANDOM: CPUSH(SAF_random()); break;
- case F_RANDOM_SEED: x = CV(0); CPOP(1); SAF_randomSeed(x); break;
- case F_SIN: x = CV(0); CPOP(1); CPUSH(SAF_sin(x)); break;
- case F_COS: x = CV(0); CPOP(1); CPUSH(SAF_cos(x)); break;
- case F_SQRT: { uint32_t x32 = CV(0); CPOP(1); CPUSH(SAF_sqrt(x32)); break; }
- case F_CLEAR_SCREEN: SAF_clearScreen(CV(0)); CPOP(1); break;
- case F_DRAW_PIXEL:
- x = CV(0); y = CV(1); z = CV(2); CPOP(3); SAF_drawPixel(z,y,x); break;
- case F_DRAW_TEXT:
- {
- int8_t xs, ys;
- uint8_t l = 0;
- x = CV(0); y = CV(1);
- xs = CMN_unsignedToSignedNative(CV(2));
- ys = CMN_unsignedToSignedNative(CV(3));
- while (1)
- {
- if (l < HELPER_STRING_SIZE)
- helperString[l] = CV(l + 4);
- if (helperString[l] == 0)
- break;
- l++;
- }
- helperString[HELPER_STRING_SIZE - 1] = 0;
- CPOP(l + 5);
- SAF_drawText(helperString,ys,xs,y,x);
- break;
- }
- case F_COLOR_FROM_RGB:
- x = CV(0); y = CV(1); z = CV(2);
- CPOP(3); CPUSH(SAF_colorFromRGB(z,y,x));
- break;
- case F_COLOR_TO_RGB:
- x = CV(0); CPOP(1);
- SAF_colorToRGB(x,&y,&z,&w);
- CPUSH(w); CPUSH(z); CPUSH(y);
- break;
- case F_DRAW_RECT:
- {
- int8_t xs, ys, zs, ws;
- x = CV(0); y = CV(1);
- xs = CMN_unsignedToSignedNative(CV(2));
- ys = CMN_unsignedToSignedNative(CV(3));
- zs = CMN_unsignedToSignedNative(CV(4));
- ws = CMN_unsignedToSignedNative(CV(5));
- CPOP(6);
- SAF_drawRect(ws,zs,ys,xs,y,x);
- break;
- }
- case F_DRAW_LINE:
- case F_DRAW_CIRCLE:
- {
- int8_t xs, ys, zs, ws;
- x = CV(0);
- xs = CMN_unsignedToSignedNative(CV(1));
- ys = CMN_unsignedToSignedNative(CV(2));
- zs = CMN_unsignedToSignedNative(CV(3));
- ws = CMN_unsignedToSignedNative(CV(4));
- CPOP(5);
- if (functions[id] == F_DRAW_LINE)
- SAF_drawLine(ws,zs,ys,xs,x);
- else
- SAF_drawCircle(ws,zs,ys,xs,x);
- break;
- }
- case F_GET_FONT_CHARACTER:
- {
- uint8_t r[2];
- x = CV(0); CPOP(1);
- SAF_getFontCharacter(x,r);
- CPUSH(r[1]);
- CPUSH(r[0]);
- break;
- }
- case F_INT_TO_STR:
- {
- int v = CV(0); CPOP(1);
- const char *s = helperString;
- SAF_intToStr(v,helperString);
- while (*s != 0)
- s++;
- s--;
- CPUSH(0);
- while (s >= helperString)
- {
- CPUSH(*s);
- s--;
- }
- break;
- }
- case F_DRAW_IMAGE:
- case F_DRAW_IMAGE_COMPRESSED:
- {
- int8_t xs, ys;
- x = CV(0); y = CV(1);
- xs = CMN_unsignedToSignedNative(CV(2));
- ys = CMN_unsignedToSignedNative(CV(3));
- CPOP(4);
- loadImage(interp,helperImage,HELPER_STRING_SIZE,
- functions[id] == F_DRAW_IMAGE ? 0 : 1);
- if (functions[id] == F_DRAW_IMAGE)
- SAF_drawImage(helperImage,ys,xs,y,x);
- else
- SAF_drawImageCompressed(helperImage,ys,xs,y,x);
- break;
- }
- case F_DRAW_IMAGE_1BIT:
- {
- int8_t xs, ys;
- x = CV(0); y = CV(1); z = CV(2);
- CPOP(3);
- loadImage(interp,helperImage + HELPER_IMAGE_SIZE / 2,
- HELPER_IMAGE_SIZE / 2,2);
- xs = CMN_unsignedToSignedNative(CV(0));
- ys = CMN_unsignedToSignedNative(CV(1));
- CPOP(2);
- loadImage(interp,helperImage,HELPER_IMAGE_SIZE / 2,2);
- SAF_drawImage1Bit(helperImage,ys,xs,helperImage + HELPER_IMAGE_SIZE / 2,
- z,y,x);
- break;
- }
- case F_COLOR_TO_GRAYSCALE: x = CV(0); CPUSH(SAF_colorToGrayscale(x)); break;
- case F_COLOR_TO_1BIT: x = CV(0); CPUSH(SAF_colorTo1Bit(x)); break;
- case F_COLOR_INVERT: x = CV(0); CPUSH(SAF_colorInvert(x)); break;
- case F_COLOR_YELLOW: CPUSH(SAF_COLOR_YELLOW); break;
- case F_COLOR_BLACK: CPUSH(SAF_COLOR_BLACK); break;
- case F_COLOR_WHITE: CPUSH(SAF_COLOR_WHITE); break;
- case F_COLOR_GRAY: CPUSH(SAF_COLOR_GRAY); break;
- case F_COLOR_GRAY_DARK: CPUSH(SAF_COLOR_GRAY_DARK); break;
- case F_COLOR_RED: CPUSH(SAF_COLOR_RED); break;
- case F_COLOR_RED_DARK: CPUSH(SAF_COLOR_RED_DARK); break;
- case F_COLOR_GREEN: CPUSH(SAF_COLOR_GREEN); break;
- case F_COLOR_GREEN_DARK: CPUSH(SAF_COLOR_GREEN_DARK); break;
- case F_COLOR_BLUE: CPUSH(SAF_COLOR_BLUE); break;
- case F_COLOR_BLUE_DARK: CPUSH(SAF_COLOR_BLUE_DARK); break;
- case F_COLOR_ORANGE: CPUSH(SAF_COLOR_ORANGE); break;
- case F_COLOR_BROWN: CPUSH(SAF_COLOR_BROWN); break;
- case F_BUTTON_UP: CPUSH(SAF_BUTTON_UP); break;
- case F_BUTTON_DOWN: CPUSH(SAF_BUTTON_DOWN); break;
- case F_BUTTON_LEFT: CPUSH(SAF_BUTTON_LEFT); break;
- case F_BUTTON_RIGHT: CPUSH(SAF_BUTTON_RIGHT); break;
- case F_BUTTON_A: CPUSH(SAF_BUTTON_A); break;
- case F_BUTTON_B: CPUSH(SAF_BUTTON_B); break;
- case F_BUTTON_C: CPUSH(SAF_BUTTON_C); break;
- case F_SOUND_BEEP: CPUSH(SAF_SOUND_BEEP); break;
- case F_SOUND_CLICK: CPUSH(SAF_SOUND_CLICK); break;
- case F_SOUND_BOOM: CPUSH(SAF_SOUND_BOOM); break;
- case F_SOUND_BUMP: CPUSH(SAF_SOUND_BUMP); break;
- case F_TRANSFORM_NONE: CPUSH(SAF_TRANSFORM_NONE); break;
- case F_TRANSFORM_ROTATE_90: CPUSH(SAF_TRANSFORM_ROTATE_90); break;
- case F_TRANSFORM_ROTATE_180: CPUSH(SAF_TRANSFORM_ROTATE_180); break;
- case F_TRANSFORM_ROTATE_270: CPUSH(SAF_TRANSFORM_ROTATE_270); break;
- case F_TRANSFORM_FLIP: CPUSH(SAF_TRANSFORM_FLIP); break;
- case F_TRANSFORM_SCALE_2: CPUSH(SAF_TRANSFORM_SCALE_2); break;
- case F_TRANSFORM_SCALE_3: CPUSH(SAF_TRANSFORM_SCALE_3); break;
- case F_TRANSFORM_SCALE_4: CPUSH(SAF_TRANSFORM_SCALE_4); break;
- case F_TRANSFORM_INVERT: CPUSH(SAF_TRANSFORM_INVERT); break;
- case F_SCREEN_WIDTH: CPUSH(SAF_SCREEN_WIDTH); break;
- case F_SCREEN_HEIGHT: CPUSH(SAF_SCREEN_HEIGHT); break;
- case F_FPS: CPUSH(SAF_FPS); break;
- default: break;
- }
- }
- #undef CV
- #undef CPOP
- #undef CPUSH
- void SAF_init(void)
- {
- #if !PRECOMPILED
- CMN_compilerInit(&compiler,bytecodeMem,BYTECODEDMEM_SIZE,(char *) workingMem,
- WORKINGMEM_SIZE,0);
- FILE *f = fopen(GAME_FILE_NAME,"r");
- if (!f)
- {
- fputs("ERROR: couldn't open file \"" GAME_FILE_NAME "\"",stderr);
- ok = 0;
- }
- else
- {
- int line = 1;
- while (1)
- {
- int c = fgetc(f);
- if (c == '\n')
- line++;
- uint8_t cState = CMN_compilerFeedChar(&compiler,c == EOF ? 0 : c);
- if (cState != CMN_COMPILER_OK)
- {
- const char *errorStr = "unknown";
- switch (cState)
- {
- case CMN_COMPILER_ERROR_BAD_TOKEN: errorStr = "bad token"; break;
- case CMN_COMPILER_ERROR_UNEXPECTED_TOKEN: errorStr = "unexpected"; break;
- case CMN_COMPILER_ERROR_UNKNOWN_NAME: errorStr = "unknown name"; break;
- case CMN_COMPILER_ERROR_REDEFINED: errorStr = "symbol redefined"; break;
- case CMN_COMPILER_ERROR_UNEXPECTED_END: errorStr = "early end"; break;
- case CMN_COMPILER_ERROR_BYTECODE_TOO_BIG: errorStr = "program too big"; break;
- case CMN_COMPILER_ERROR_SYMBOL_TABLE: errorStr = "symbol table too small"; break;
- case CMN_COMPILER_ERROR_PARSE_STACK: errorStr = "parse stack overflow"; break;
- default: break;
- }
- fprintf(stderr,"ERROR: compilation failed, line %d: %s\n",line,errorStr);
- ok = 0;
- break;
- }
- if (c == EOF)
- break;
- }
- fclose(f);
- if (ok)
- {
- CMN_bytecodeOptimize(bytecodeMem,
- CMN_OPTIMIZE_REMOVE_NOPS | CMN_OPTIMIZE_INLINE |
- CMN_OPTIMIZE_REPLACE_OPS,&compiler);
- loopFunctionID = CMN_compilerFindFunction(&compiler,"SAF_loop",0);
- if (loopFunctionID < 0)
- {
- fputs("ERROR: no \"SAF_loop\" function\n",stderr);
- ok = 0;
- }
- else
- {
- for (uint8_t i = 0; i < FUNCTIONS_TOTAL; ++i)
- functions[i] = -1;
- int8_t id;
- #define FIND_FUNC(f,c)\
- id = CMN_compilerFindFunction(&compiler,f,1); \
- if (id >= 0 && id < FUNCTIONS_TOTAL) functions[id] = c;
- FIND_FUNC("SAF_buttonPressed",F_BUTTON_PRESSED)
- FIND_FUNC("SAF_buttonJustPressed",F_BUTTON_JUST_PRESSED)
- FIND_FUNC("SAF_playSound",F_PLAY_SOUND)
- FIND_FUNC("SAF_save",F_SAVE)
- FIND_FUNC("SAF_load",F_LOAD)
- FIND_FUNC("SAF_frame",F_FRAME)
- FIND_FUNC("SAF_time",F_TIME)
- FIND_FUNC("SAF_random",F_RANDOM)
- FIND_FUNC("SAF_randomSeed",F_RANDOM_SEED)
- FIND_FUNC("SAF_sin",F_SIN)
- FIND_FUNC("SAF_cos",F_COS)
- FIND_FUNC("SAF_sqrt",F_SQRT)
- FIND_FUNC("SAF_colorFromRGB",F_COLOR_FROM_RGB)
- FIND_FUNC("SAF_colorToRGB",F_COLOR_TO_RGB)
- FIND_FUNC("SAF_colorToGrayscale",F_COLOR_TO_GRAYSCALE)
- FIND_FUNC("SAF_colorTo1Bit",F_COLOR_TO_1BIT)
- FIND_FUNC("SAF_colorInvert",F_COLOR_INVERT)
- FIND_FUNC("SAF_drawPixel",F_DRAW_PIXEL)
- FIND_FUNC("SAF_drawRect",F_DRAW_RECT)
- FIND_FUNC("SAF_drawLine",F_DRAW_LINE)
- FIND_FUNC("SAF_drawCircle",F_DRAW_CIRCLE)
- FIND_FUNC("SAF_clearScreen",F_CLEAR_SCREEN)
- FIND_FUNC("SAF_drawText",F_DRAW_TEXT)
- FIND_FUNC("SAF_getFontCharacter",F_GET_FONT_CHARACTER)
- FIND_FUNC("SAF_drawImage",F_DRAW_IMAGE)
- FIND_FUNC("SAF_drawImageCompressed",F_DRAW_IMAGE_COMPRESSED)
- FIND_FUNC("SAF_drawImage1Bit",F_DRAW_IMAGE_1BIT)
- FIND_FUNC("SAF_intToStr",F_INT_TO_STR)
- FIND_FUNC("SAF_BUTTON_UP",F_BUTTON_UP)
- FIND_FUNC("SAF_BUTTON_RIGHT",F_BUTTON_RIGHT)
- FIND_FUNC("SAF_BUTTON_DOWN",F_BUTTON_DOWN)
- FIND_FUNC("SAF_BUTTON_LEFT",F_BUTTON_LEFT)
- FIND_FUNC("SAF_BUTTON_A",F_BUTTON_A)
- FIND_FUNC("SAF_BUTTON_B",F_BUTTON_B)
- FIND_FUNC("SAF_BUTTON_C",F_BUTTON_C)
- FIND_FUNC("SAF_COLOR_BLACK",F_COLOR_BLACK)
- FIND_FUNC("SAF_COLOR_WHITE",F_COLOR_WHITE)
- FIND_FUNC("SAF_COLOR_GRAY",F_COLOR_GRAY)
- FIND_FUNC("SAF_COLOR_GRAY_DARK",F_COLOR_GRAY_DARK)
- FIND_FUNC("SAF_COLOR_RED",F_COLOR_RED)
- FIND_FUNC("SAF_COLOR_RED_DARK",F_COLOR_RED_DARK)
- FIND_FUNC("SAF_COLOR_GREEN",F_COLOR_GREEN)
- FIND_FUNC("SAF_COLOR_GREEN_DARK",F_COLOR_GREEN_DARK)
- FIND_FUNC("SAF_COLOR_BLUE",F_COLOR_BLUE)
- FIND_FUNC("SAF_COLOR_BLUE_DARK",F_COLOR_BLUE_DARK)
- FIND_FUNC("SAF_COLOR_YELLOW",F_COLOR_YELLOW)
- FIND_FUNC("SAF_COLOR_ORANGE",F_COLOR_ORANGE)
- FIND_FUNC("SAF_COLOR_BROWN",F_COLOR_BROWN)
- FIND_FUNC("SAF_SOUND_BEEP",F_SOUND_BEEP)
- FIND_FUNC("SAF_SOUND_CLICK",F_SOUND_CLICK)
- FIND_FUNC("SAF_SOUND_BOOM",F_SOUND_BOOM)
- FIND_FUNC("SAF_SOUND_BUMP",F_SOUND_BUMP)
- FIND_FUNC("SAF_TRANSFORM_NONE",F_TRANSFORM_NONE)
- FIND_FUNC("SAF_TRANSFORM_ROTATE_90",F_TRANSFORM_ROTATE_90)
- FIND_FUNC("SAF_TRANSFORM_ROTATE_180",F_TRANSFORM_ROTATE_180)
- FIND_FUNC("SAF_TRANSFORM_ROTATE_270",F_TRANSFORM_ROTATE_270)
- FIND_FUNC("SAF_TRANSFORM_FLIP",F_TRANSFORM_FLIP)
- FIND_FUNC("SAF_TRANSFORM_SCALE_2",F_TRANSFORM_SCALE_2)
- FIND_FUNC("SAF_TRANSFORM_SCALE_3",F_TRANSFORM_SCALE_3)
- FIND_FUNC("SAF_TRANSFORM_SCALE_4",F_TRANSFORM_SCALE_4)
- FIND_FUNC("SAF_TRANSFORM_INVERT",F_TRANSFORM_INVERT)
- FIND_FUNC("SAF_SCREEN_WIDTH",F_SCREEN_WIDTH)
- FIND_FUNC("SAF_SCREEN_HEIGHT",F_SCREEN_HEIGHT)
- FIND_FUNC("SAF_FPS",F_FPS)
- #undef FIND_FUNC
- // now print the compiled bytecode (for precompiled version)
- puts("Compiled data follows (for making a precompiled version):");
- puts("#define PRECOMPILED 1");
- printf("int32_t loopFunctionID = %d;\n",loopFunctionID);
- unsigned int realSize = 0;
-
- for (uint32_t i = 0; i < BYTECODEDMEM_SIZE; i += 2)
- {
- realSize += 2;
- if (i > CMN_BYTECODE_HEADER_SIZE && bytecodeMem[i] == CMN_OPCODE_END)
- break;
- }
- printf("#define BYTECODEDMEM_SIZE %d\n",realSize);
- printf("uint8_t bytecodeMem[BYTECODEDMEM_SIZE] = {");
- for (uint32_t i = 0; i < realSize; ++i)
- {
- if (i != 0)
- putchar(',');
- if (i % 32 == 0)
- printf("\n ");
- printf("%d",bytecodeMem[i]);
- }
- printf("};\nint8_t functions[] = {");
- for (uint32_t i = 0; i < FUNCTIONS_TOTAL; ++i)
- {
- if (i != 0)
- putchar(',');
- if (i % 32 == 0)
- printf("\n ");
- printf("%d",functions[i]);
- }
- puts("};");
- #endif
- if (!CMN_interpreterInit(&interpreter,bytecodeMem,workingMem,
- WORKINGMEM_SIZE,64,ioFunction,functionCall,0,0))
- {
- fputs("ERROR: couldn't initialize interpreter\n",stderr);
- ok = 0;
- }
- else if (CMN_interpreterStep(&interpreter,0) != CMN_INTERPRETER_END)
- {
- fputs("ERROR: runtime error during initialization\n",stderr);
- ok = 0;
- }
- #if !PRECOMPILED
- }
- }
- }
- #endif
- }
- uint8_t SAF_loop()
- {
- if (ok)
- {
- CMN_interpreterCallFunction(&interpreter,loopFunctionID);
- uint8_t interpreterState = CMN_interpreterStep(&interpreter,0);
- if (interpreterState != CMN_INTERPRETER_END)
- {
- #if !PRECOMPILED
- fputs("ERROR: error at runtime: ",stderr);
- switch(interpreterState)
- {
- case CMN_INTERPRETER_ERROR_CALLSTACK:
- fputs("call stack overflow",stderr); break;
- case CMN_INTERPRETER_ERROR_STACK_OF:
- fputs("stack overflow",stderr); break;
- case CMN_INTERPRETER_ERROR_ZERODIV:
- fputs("division by zero",stderr); break;
- default: fputs("unknown",stderr); break;
- }
- fputc('\n',stderr);
- #endif
- ok = 0;
- }
- }
- else
- {
- SAF_clearScreen(SAF_COLOR_RED);
- SAF_drawText("ERROR",6,17,SAF_COLOR_BLACK,2);
- }
- return 1;
- }
|