From e3a3e60e8cdb8003a020b58723d2da5757a182f1 Mon Sep 17 00:00:00 2001 From: ketmar Date: Fri, 16 Mar 2012 17:37:12 +0200 Subject: [PATCH] cool feature: local room scripts (scripts that will be loaded with room from external file) --- src/awasm.c | 70 +++++++++++++++++++++++++++++++++---------------- src/awish.c | 6 ++++- src/game.c | 24 +++++++++++++++++ src/gameglobals.c | 30 ++++++++++++++++----- src/gameglobals.h | 7 ++--- src/resfile.c | 4 +++ src/vm.h | 2 +- src/vm_gamelabels.h | 3 +++ src/vm_gamelabelsdef.c | 3 +++ src/vm_gamelabelsinit.c | 3 +++ 10 files changed, 118 insertions(+), 34 deletions(-) diff --git a/src/awasm.c b/src/awasm.c index 105a2df..9f76aa9 100644 --- a/src/awasm.c +++ b/src/awasm.c @@ -68,6 +68,10 @@ enum { //////////////////////////////////////////////////////////////////////////////// +static int optWarnings = 1; + + +//////////////////////////////////////////////////////////////////////////////// static uint8_t vmcode[65536]; static int pc = 0; @@ -477,7 +481,10 @@ static void fixupLabelRefs (LabelInfo *l, int pc) { static void checkLabels (void) { for (LabelInfo *l = labels; l != NULL; l = l->next) { if (l->type == LB_CODE && l->ext >= 0 && l->value < 0) fatal("undefined %slabel: '%s'", l->used?"":"not referenced ", l->name); - if (!l->used) { l->used = -1; fprintf(stderr, "WARNING: unused %s label '%s'\n", ltnames[l->type], l->name); } + if (!l->used) { + l->used = -1; + if (optWarnings) fprintf(stderr, "WARNING: unused %s label '%s'\n", ltnames[l->type], l->name); + } } } @@ -504,7 +511,10 @@ static void freeLocalLabels (int onlyVars) { // if ((!onlyVars || l->type != LB_CODE) && l->name[0] == '.') { if (l->type == LB_CODE && l->ext >= 0 && l->value < 0) fatal("undefined %slabel: '%s'", l->used?"":"not referenced ", l->name); - if (!l->used) { l->used = -1; fprintf(stderr, "WARNING: unused %s label '%s'\n", ltnames[l->type], l->name); } + if (!l->used) { + l->used = -1; + if (optWarnings) fprintf(stderr, "WARNING: unused %s label '%s'\n", ltnames[l->type], l->name); + } //if (l->type == LB_CODE && l->value < 0) fatal("undefined label: '%s'", l->name); freeLabelRefList(l->fixes); freeLabelRefList(l->refs); @@ -1121,26 +1131,6 @@ static void parseVarList (int type, int local, int gotext) { } -static void parsePublics (void) { - for (;;) { - LabelInfo *l; - // - if (nextToken() != TK_ID) fatal("identifier expected"); - if (tstr[0] == '.') fatal("invalid label name: '%s'", tstr); - l = findLabel(tstr); - if (l != NULL) { - l->ext = 1; - } else { - l = addLabel(tstr); - l->ext = 1; - l->type = LB_CODE; - l->value = -1; - } - if (nextToken() != ',') break; - } -} - - static void parseLocList (void) { for (;;) { LabelInfo *l; @@ -1467,6 +1457,31 @@ static void parseDAscii (int zeroend) { } +static void parsePublics (void) { + for (;;) { + LabelInfo *l; + // + nextToken(); + if (token == TK_LABELDEF) { + parseLabel(0); + break; + } + if (token != TK_ID) fatal("identifier expected"); + if (tstr[0] == '.') fatal("invalid label name: '%s'", tstr); + l = findLabel(tstr); + if (l != NULL) { + l->ext = 1; + } else { + l = addLabel(tstr); + l->ext = 1; + l->type = LB_CODE; + l->value = -1; + } + if (nextToken() != ',') break; + } +} + + static void process (void) { int gotext = 0; LabelInfo *l = addLabel("retval"); @@ -1803,6 +1818,17 @@ int main (int argc, char *argv[]) { argc = k8argc; argv = k8argv; #endif + // + for (int f = 1; f < argc; ++f) { + if (strcmp(argv[f], "-Wno") == 0) { + optWarnings = 0; + for (int c = f+1; c < argc; ++c) argv[c-1] = argv[c]; + argv[--argc] = NULL; + --f; + continue; + } + } + // if (argc != 3) { fprintf(stderr, "usage: awasm infile outfile\n"); return 1; diff --git a/src/awish.c b/src/awish.c index 5f8deaa..450de9f 100644 --- a/src/awish.c +++ b/src/awish.c @@ -215,6 +215,10 @@ static int awishRST (int tid, int opcode, int argc, int argv[], int *argp[]) { // levelnum if (vmLoadArgs(tid, 2, argv, argp, argc, argv, argp) != 0) fatal("out of args"); vmGVars[GVAR_RST_RESULT] = loadLevel(argv[1]); + } else if (argv[0] == CONST_FRST_GET_MAX_THREADS) { + vmGVars[GVAR_RST_RESULT] = VM_MAX_THREADS; + } else if (argv[0] == CONST_FRST_GET_MAX_THREAD_ID) { + vmGVars[GVAR_RST_RESULT] = vmLastThread(); } else if (argv[0] == CONST_FRST_DEBUG_PRINT_STR) { int pos = 0, len = 0; // @@ -360,7 +364,7 @@ int main (int argc, char *argv[]) { vmGVars[120] = 0; // vmCodeSize = 100; - if ((csz = loadVMCode(&resfile, vmCodeSize)) < 1) { + if ((csz = loadVMCode(&resfile, vmCodeSize, 93)) < 1) { fprintf(stderr, "FATAL: can't load VM code!\n"); exit(1); } diff --git a/src/game.c b/src/game.c index 65f11e6..496bc6d 100644 --- a/src/game.c +++ b/src/game.c @@ -559,6 +559,7 @@ static void frmGameKey (SDL_KeyboardEvent *key) { //////////////////////////////////////////////////////////////////////////////// +#define ROOM_SCRIPTS_MARK " room script labels starts here " static int loadLevelInternal (ResFile *resfile, int lidx) { Uint8 *lvl; int sz, res = -1, pos; @@ -567,6 +568,13 @@ static int loadLevelInternal (ResFile *resfile, int lidx) { static int scrX, scrY; static int profX, profY; char buf[64]; + int csz; + LabelInfo *lm; + // + while ((lm = findMark(ROOM_SCRIPTS_MARK)) != NULL) { + vmCodeSize = lm->value; + freeLabelsUntilMark(ROOM_SCRIPTS_MARK); + } // message[0] = 0; // @@ -646,6 +654,22 @@ static int loadLevelInternal (ResFile *resfile, int lidx) { doSave = 0; res = 0; // + vmGVars[GVAR_ROOM_SCRIPT_TID] = -1; + lm = labelAddMark(ROOM_SCRIPTS_MARK); + lm->value = vmCodeSize; + if ((csz = loadVMCode(resfile, vmCodeSize, 94+lidx)) > 1) { + LabelInfo *l = findLabel("entry_local_room_script"); + // + if (l != NULL && l->type == LB_CODE) { + int tid; + // + vmCodeSize += csz; + tid = vmNewThread(l->value); + vmGVars[GVAR_ROOM_SCRIPT_TID] = tid; + if (goobers) fprintf(stderr, "local room script loaded and initialized\n"); + } + } + // quit: free(lvl); return res; diff --git a/src/gameglobals.c b/src/gameglobals.c index 055ff43..5062a1d 100644 --- a/src/gameglobals.c +++ b/src/gameglobals.c @@ -55,11 +55,12 @@ void freeLabels (void) { } -void freeLabelsUntilMark (void) { +void freeLabelsUntilMark (const char *name) { while (labels != NULL) { LabelInfo *l = labels; int isMark = (l->type == LB_MARK); // + if (!(isMark && ((name == NULL && l->name == NULL) || (l->name != NULL && name != NULL && strcmp(name, l->name) == 0)))) isMark = 0; labels = l->next; if (l->name) free(l->name); free(l); @@ -68,16 +69,21 @@ void freeLabelsUntilMark (void) { } -void labelAddMark (void) { +LabelInfo *labelAddMark (const char *name) { LabelInfo *l = malloc(sizeof(LabelInfo)); // if (l == NULL) fatal("out of memory"); l->name = NULL; + if (name != NULL) { + l->name = strdup(name); + if (l->name == NULL) fatal("out of memory"); + } l->type = LB_MARK; l->value = -1; l->next = labels; l->pub = 0; labels = l; + return l; } @@ -126,11 +132,11 @@ LabelInfo *addLabel (const char *name, int type, int value, int pub) { // return vm code size -int loadVMCode (ResFile *resfile, int pc) { +int loadVMCode (ResFile *resfile, int pc, int idx) { int rsz = 0, pos = 0; char sign[4]; int csize, lcnt, rcnt, elcnt; - uint8_t *buf = loadResFile(resfile, 93, &rsz); + uint8_t *buf = loadResFile(resfile, idx, &rsz); // if (buf == NULL) return -1; for (int f = 4; f < rsz; ++f) buf[f] ^= SECRET; @@ -199,7 +205,7 @@ int loadVMCode (ResFile *resfile, int pc) { } val = l->value; if (l->type == LB_GVAR) val |= 0x80; - fprintf(stderr, "%d: [%s]: ofs=%d, size=%d, value=%d (%d)\n", c, l->name, xpc, size, val, vmCode[xpc]); + //fprintf(stderr, "%d: [%s]: ofs=%d, size=%d, value=%d (%d)\n", c, l->name, xpc, size, val, vmCode[xpc]); if (size == 1 && (val < -128 || val > 255)) { if (goobers) fprintf(stderr, "VM: extern too big: '%s'\n", name); goto quitbufonly; @@ -209,7 +215,7 @@ int loadVMCode (ResFile *resfile, int pc) { } } // - labelAddMark(); // for this code labels + labelAddMark(NULL); // for this code labels for (int f = 0; f < lcnt; ++f) { unsigned char type, namelen, b; char name[258]; @@ -248,7 +254,7 @@ int loadVMCode (ResFile *resfile, int pc) { free(buf); return csize; quit: - freeLabelsUntilMark(); + freeLabelsUntilMark(NULL); quitbufonly: free(buf); return -1; @@ -314,6 +320,16 @@ int findConst (const char *name) { } +LabelInfo *findMark (const char *name) { + for (LabelInfo *l = labels; l != NULL; l = l->next) { + if (l->type != LB_MARK) continue; + if (name == NULL && l->name == NULL) return l; + if (name != NULL && l->name != NULL && strcmp(name, l->name) == 0) return l; + } + return NULL; +} + + //////////////////////////////////////////////////////////////////////////////// void initLabels (void) { #include "vm_gamelabelsinit.c" diff --git a/src/gameglobals.h b/src/gameglobals.h index 76a13fb..be78581 100644 --- a/src/gameglobals.h +++ b/src/gameglobals.h @@ -63,12 +63,12 @@ typedef struct LabelInfo { extern void fatal (const char *fmt, ...) __attribute__((__noreturn__)) __attribute__((format(printf, 1, 2))); // return code size -extern int loadVMCode (ResFile *resfile, int pc); +extern int loadVMCode (ResFile *resfile, int pc, int idx); extern void freeLabels (void); -extern void freeLabelsUntilMark (void); +extern void freeLabelsUntilMark (const char *name); -extern void labelAddMark (void); +extern LabelInfo *labelAddMark (const char *name); extern LabelInfo *addLabel (const char *name, int type, int value, int pub); extern LabelInfo *findLabel (const char *name); @@ -79,6 +79,7 @@ extern int findGVarIndex (const char *name); extern int findTVarIndex (const char *name); extern int findSVarIndex (const char *name); extern int findConst (const char *name); +extern LabelInfo *findMark (const char *name); extern void initLabels (void); diff --git a/src/resfile.c b/src/resfile.c index 00435d1..0b76be3 100644 --- a/src/resfile.c +++ b/src/resfile.c @@ -438,6 +438,10 @@ static uint8_t *loadDiskFile (int idx, int *rsz) { } return NULL; } + // + if (idx >= 94 && idx <= 94+73) { + TRY_FILES(NULL, -1, "maps/level%02d.vmd", idx-93); + } return NULL; } diff --git a/src/vm.h b/src/vm.h index 66c4f9f..81bd003 100644 --- a/src/vm.h +++ b/src/vm.h @@ -19,7 +19,7 @@ #define VM_STACK_SIZE (1024) #define VM_VARS_SIZE (127) -#define VM_MAX_THREADS (280) +#define VM_MAX_THREADS (512) enum { diff --git a/src/vm_gamelabels.h b/src/vm_gamelabels.h index 608a25a..80c8473 100644 --- a/src/vm_gamelabels.h +++ b/src/vm_gamelabels.h @@ -14,6 +14,7 @@ extern int TVAR_SPR_DIR; extern int TVAR_SPR_NUM; extern int TVAR_SPR_BANK; extern int TVAR_ITEM_ID; +extern int GVAR_ROOM_SCRIPT_TID; extern int GVAR_PROF_ITEM; extern int GVAR_CUR_LEVEL; extern int GVAR_SCR_Y; @@ -56,6 +57,8 @@ extern int CONST_GAME_STATE_STARTED; extern int CONST_GAME_STATE_PLAYING; extern int CONST_FRST_DEBUG_PRINT_NUM; extern int CONST_FRST_DEBUG_PRINT_STR; +extern int CONST_FRST_GET_MAX_THREAD_ID; +extern int CONST_FRST_GET_MAX_THREADS; extern int CONST_FRST_LOAD_LEVEL; extern int CONST_FRST_MINIMAP; extern int CONST_FRST_ML_GAME; diff --git a/src/vm_gamelabelsdef.c b/src/vm_gamelabelsdef.c index dce4a99..a42ab76 100644 --- a/src/vm_gamelabelsdef.c +++ b/src/vm_gamelabelsdef.c @@ -14,6 +14,7 @@ int TVAR_SPR_DIR; int TVAR_SPR_NUM; int TVAR_SPR_BANK; int TVAR_ITEM_ID; +int GVAR_ROOM_SCRIPT_TID; int GVAR_PROF_ITEM; int GVAR_CUR_LEVEL; int GVAR_SCR_Y; @@ -56,6 +57,8 @@ int CONST_GAME_STATE_STARTED; int CONST_GAME_STATE_PLAYING; int CONST_FRST_DEBUG_PRINT_NUM; int CONST_FRST_DEBUG_PRINT_STR; +int CONST_FRST_GET_MAX_THREAD_ID; +int CONST_FRST_GET_MAX_THREADS; int CONST_FRST_LOAD_LEVEL; int CONST_FRST_MINIMAP; int CONST_FRST_ML_GAME; diff --git a/src/vm_gamelabelsinit.c b/src/vm_gamelabelsinit.c index 48922cf..fbd3b37 100644 --- a/src/vm_gamelabelsinit.c +++ b/src/vm_gamelabelsinit.c @@ -14,6 +14,7 @@ TVAR_SPR_NUM = findTVarIndex("spr_num"); TVAR_SPR_BANK = findTVarIndex("spr_bank"); TVAR_ITEM_ID = findTVarIndex("item_id"); + GVAR_ROOM_SCRIPT_TID = findGVarIndex("room_script_tid"); GVAR_PROF_ITEM = findGVarIndex("prof_item"); GVAR_CUR_LEVEL = findGVarIndex("cur_level"); GVAR_SCR_Y = findGVarIndex("scr_y"); @@ -56,6 +57,8 @@ CONST_GAME_STATE_PLAYING = findConst("game_state_playing"); CONST_FRST_DEBUG_PRINT_NUM = findConst("frst_debug_print_num"); CONST_FRST_DEBUG_PRINT_STR = findConst("frst_debug_print_str"); + CONST_FRST_GET_MAX_THREAD_ID = findConst("frst_get_max_thread_id"); + CONST_FRST_GET_MAX_THREADS = findConst("frst_get_max_threads"); CONST_FRST_LOAD_LEVEL = findConst("frst_load_level"); CONST_FRST_MINIMAP = findConst("frst_minimap"); CONST_FRST_ML_GAME = findConst("frst_ml_game"); -- 2.11.4.GIT