Overview
Comment: | Start writing code for executing class codes (untested) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
52a2dcb87da8fc0e370fcab6bce17a2c |
User & Date: | user on 2019-05-18 03:37:17 |
Other Links: | manifest | tags |
Context
2019-07-15
| ||
03:27 | Add gameover,key_ignored,changed variables for future use check-in: b39ff189b9 user: user tags: trunk | |
2019-05-18
| ||
03:37 | Start writing code for executing class codes (untested) check-in: 52a2dcb87d user: user tags: trunk | |
2019-02-10
| ||
18:10 | Allow left and right arrow keys in class select menu to select which image check-in: 2da745c85b user: user tags: trunk | |
Changes
Modified exec.c from [c5ee33d3db] to [29671639e9].
︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <stdio.h> #include <stdlib.h> #include <string.h> #include "sqlite3.h" #include "smallxrm.h" #include "heromesh.h" #include "instruc.h" Uint32 max_objects; Uint32 generation_number; Object**objects; Uint32 nobjects; Value globals[0x800]; Uint32 firstobj=VOIDLINK; | > > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <stdio.h> #include <stdlib.h> #include <string.h> #include "sqlite3.h" #include "smallxrm.h" #include "heromesh.h" #include "instruc.h" #ifndef VSTACKSIZE #define VSTACKSIZE 0x400 #endif Uint32 max_objects; Uint32 generation_number; Object**objects; Uint32 nobjects; Value globals[0x800]; Uint32 firstobj=VOIDLINK; |
︙ | ︙ | |||
29 30 31 32 33 34 35 36 37 | Value arg1,arg2,arg3; } MessageVars; static jmp_buf my_env; static const char*my_error; static MessageVars msgvars; static char lastimage_processing; #define Throw(x) (my_error=(x),longjmp(my_env,1)) | > > | > > | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | Value arg1,arg2,arg3; } MessageVars; static jmp_buf my_env; static const char*my_error; static MessageVars msgvars; static char lastimage_processing; static Value vstack[VSTACKSIZE]; static int vstackptr; #define Throw(x) (my_error=(x),longjmp(my_env,1)) #define StackReq(x,y) do{ if(vstackptr<(x)) Throw("Stack underflow"); if(vstackptr-(x)+(y)>=VSTACKSIZE) Throw("Stack overflow"); }while(0) #define Push(x) (vstack[vstackptr++]=(x)) #define Pop() (vstack[--vstackptr]) void pfunlink(Uint32 n) { Object*o=objects[n]; if(o->down==VOIDLINK) playfield[o->x+o->y*64-65]=o->up; else objects[o->down]->up=o->up; if(o->up!=VOIDLINK) objects[o->up]->down=o->down; o->down=o->up=VOIDLINK; |
︙ | ︙ | |||
106 107 108 109 110 111 112 113 114 115 116 117 118 119 | } objects[n]=o; return n; bad: free(o); return VOIDLINK; } // Here is where the execution of a Free Hero Mesh bytecode subroutine is executed. static void execute_program(Uint16*code,int ptr,Uint32 obj) { Object*o=objects[obj]; if(StackProtection()) Throw("Call stack overflow"); for(;;) switch(code[ptr++]) { case OP_GOTO: ptr=code[ptr]; break; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > < > > > > > > | > | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | } objects[n]=o; return n; bad: free(o); return VOIDLINK; } static inline int v_bool(Value v) { switch(v.t) { case TY_NUMBER: return v.u!=0; case TY_SOUND: case TY_USOUND: Throw("Cannot convert sound to boolean"); default: return 1; } } static Uint32 v_object(Value v) { if(v.t==TY_NUMBER) { if(v.u) Throw("Cannot convert number to object"); return VOIDLINK; } else if(v.t>TY_MAXTYPE) { if(v.u>=nobjects || !objects[v.u]) Throw("Attempt to use a nonexistent object"); if(objects[v.u]->generation!=v.t) Throw("Attempt to use a nonexistent object"); return v.u; } else { Throw("Cannot convert non-object to object"); } } // Here is where the execution of a Free Hero Mesh bytecode subroutine is executed. static void execute_program(Uint16*code,int ptr,Uint32 obj) { Object*o=objects[obj]; Value t1,t2; if(StackProtection()) Throw("Call stack overflow"); for(;;) switch(code[ptr++]) { case 0x0000 ... 0x00FF: StackReq(0,1); Push(NVALUE(code[ptr-1])); break; case 0x0100 ... 0x01FF: StackReq(0,1); Push(NVALUE(code[ptr-1]-0x200)); break; case 0x0200 ... 0x02FF: StackReq(0,1); Push(MVALUE(code[ptr-1]&255)); break; case 0x0300 ... 0x03FF: StackReq(0,1); Push(UVALUE(code[ptr-1]&255,TY_SOUND)); break; case 0x0400 ... 0x04FF: StackReq(0,1); Push(UVALUE(code[ptr-1]&255,TY_USOUND)); break; case 0x4000 ... 0x7FFF: StackReq(0,1); Push(CVALUE(code[ptr-1]-0x4000)); break; case 0x87E8 ... 0x87FF: StackReq(0,1); Push(NVALUE(1UL<<(code[ptr-1]&31))); break; case 0xC000 ... 0xFFFF: StackReq(0,1); Push(NVALUE((code[ptr-1]&0x3FFF)+256)); break; case OP_CALLSUB: execute_program(code,code[ptr++],obj); break; case OP_DROP: StackReq(1,0); Pop(); break; case OP_DROP_D: StackReq(2,0); Pop(); Pop(); break; case OP_DUP: StackReq(1,2); t1=Pop(); Push(t1); Push(t1); break; case OP_GOTO: ptr=code[ptr]; break; case OP_IF: StackReq(1,0); if(v_bool(Pop())) ptr=code[ptr]; else ptr++; break; case OP_INT16: StackReq(0,1); Push(NVALUE(code[ptr++])); break; case OP_INT32: StackReq(0,1); t1=UVALUE(code[ptr++]<<16,TY_NUMBER); t1.u|=code[ptr++]; Push(t1); break; case OP_LAND: StackReq(2,1); t1=Pop(); t2=Pop(); if(v_bool(t1) && v_bool(t2)) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_LNOT: StackReq(1,1); if(v_bool(Pop())) Push(NVALUE(0)); else Push(NVALUE(1)); break; case OP_LOR: StackReq(2,1); t1=Pop(); t2=Pop(); if(v_bool(t1) || v_bool(t2)) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_NIP: StackReq(2,1); t1=Pop(); Pop(); Push(t1); break; case OP_RET: return; case OP_SWAP: StackReq(2,2); t1=Pop(); t2=Pop(); Push(t1); Push(t2); break; default: Throw("Internal error: Unrecognized opcode"); } } static Value send_message(Uint32 from,Uint32 to,Uint16 msg,Value arg1,Value arg2,Value arg3) { MessageVars saved=msgvars; Uint16 c=objects[to]->class; Uint16 p=get_message_ptr(c,msg); Uint16*code; int stackptr=vstackptr; if(p==0xFFFF) { p=get_message_ptr(0,msg); if(!p) return NVALUE(0); code=classes[0]->codes; } else { code=classes[c]->codes; } msgvars=(MessageVars){msg,from,arg1,arg2,arg3}; execute_program(code,p,to); msgvars=saved; if(vstackptr<stackptr) Throw("Message code used up too much data from stack"); if(vstackptr>stackptr+1) Throw("Message code left too much data on stack"); if(vstackptr==stackptr) { return NVALUE(0); } else { return Pop(); } } void annihilate(void) { Uint32 i; for(i=0;i<64*64;i++) playfield[i]=VOIDLINK; firstobj=lastobj=VOIDLINK; if(!objects) return; for(i=0;i<nobjects;i++) free(objects[i]); nobjects=0; free(objects); objects=0; } const char*execute_turn(int key) { if(setjmp(my_env)) return my_error; lastimage_processing=0; vstackptr=0; return 0; } |
Modified heromesh.h from [a8db97cff3] to [5dda80566c].
︙ | ︙ | |||
165 166 167 168 169 170 171 172 173 174 175 176 177 178 | // == exec == #define VOIDLINK ((Uint32)(-1)) // The following "internal object flags" are part of the "dir" variable: #define IOF_DEAD 0x10 // object doesn't exist, except to continue an animation #define IOF_ANIM 0x20 // an animation is being displayed typedef struct { Sint32 height,weight,climb,density,volume,strength,arrivals,departures,temperature; Uint32 arrived,departed,arrived2,departed2,generation; Uint32 up,down,prev,next; // links to other objects Uint16 class,oflags; Uint16 sharp[4]; | > | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | // == exec == #define VOIDLINK ((Uint32)(-1)) // The following "internal object flags" are part of the "dir" variable: #define IOF_DEAD 0x10 // object doesn't exist, except to continue an animation #define IOF_ANIM 0x20 // an animation is being displayed // If the IOF_DEAD flag is set, then generation should also be set to zero. typedef struct { Sint32 height,weight,climb,density,volume,strength,arrivals,departures,temperature; Uint32 arrived,departed,arrived2,departed2,generation; Uint32 up,down,prev,next; // links to other objects Uint16 class,oflags; Uint16 sharp[4]; |
︙ | ︙ |