Free Hero Mesh

Check-in [d1b2616e10]
Login
This is a mirror of the main repository for Free Hero Mesh. New tickets and changes will not be accepted at this mirror.
Overview
Comment:Implement message tracing, fix a few mistakes, start to implement level initialization
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d1b2616e101ae5ca9eaaf203c3eb2eb6c597f293
User & Date: user on 2020-11-29 23:50:43
Other Links: manifest | tags
Context
2020-11-30
21:37
Add names for Transform, TRANSFORMING, and TRANSFORMED; not implemented yet check-in: 56fff32581 user: user tags: trunk
2020-11-29
23:50
Implement message tracing, fix a few mistakes, start to implement level initialization check-in: d1b2616e10 user: user tags: trunk
2020-11-27
00:27
Start to implement tracing. check-in: 6683ba9878 user: user tags: trunk
Changes

Modified exec.c from [0edd8bec4e] to [00ba881dd8].

9
10
11
12
13
14
15

16
17
18
19
20
21
22
#include <stdlib.h>
#include <string.h>
#include "sqlite3.h"
#include "smallxrm.h"
#include "quarks.h"
#include "heromesh.h"
#include "instruc.h"


#ifndef VSTACKSIZE
#define VSTACKSIZE 0x400
#endif

Uint32 max_objects;
Uint32 generation_number;







>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdlib.h>
#include <string.h>
#include "sqlite3.h"
#include "smallxrm.h"
#include "quarks.h"
#include "heromesh.h"
#include "instruc.h"
#include "names.h"

#ifndef VSTACKSIZE
#define VSTACKSIZE 0x400
#endif

Uint32 max_objects;
Uint32 generation_number;
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  Object*o;
  if(!main_options['t']) return;
  if(!traceprefix) {
    optionquery[1]=Q_tracePrefix;
    traceprefix=xrm_get_resource(resourcedb,optionquery,optionquery,2);
    if(!traceprefix) traceprefix="";
  }
  printf("%sTrace : %d : %u %u",traceprefix,vstackptr,t0.t,t0.u);
  if(t0.t>TY_MAXTYPE && t0.u<nobjects && objects[t0.u] && objects[t0.u]->generation==t0.t) {
    o=objects[t0.u];
    printf(" [$%s %d %d]",classes[o->class]->name,o->x,o->y);
  }
  o=objects[obj];
  printf(" : %u %u [$%s %d %d]",o->generation,obj,classes[o->class]->name,o->x,o->y);
  printf(" : %u %u : %u %u\n",t1.t,t1.u,t2.t,t2.u);







|







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
  Object*o;
  if(!main_options['t']) return;
  if(!traceprefix) {
    optionquery[1]=Q_tracePrefix;
    traceprefix=xrm_get_resource(resourcedb,optionquery,optionquery,2);
    if(!traceprefix) traceprefix="";
  }
  printf("%s%d : Trace : %d : %u %u",traceprefix,move_number,vstackptr,t0.t,t0.u);
  if(t0.t>TY_MAXTYPE && t0.u<nobjects && objects[t0.u] && objects[t0.u]->generation==t0.t) {
    o=objects[t0.u];
    printf(" [$%s %d %d]",classes[o->class]->name,o->x,o->y);
  }
  o=objects[obj];
  printf(" : %u %u [$%s %d %d]",o->generation,obj,classes[o->class]->name,o->x,o->y);
  printf(" : %u %u : %u %u\n",t1.t,t1.u,t2.t,t2.u);
227
228
229
230
231
232
233

















234
235
236
237
238
239
240
241
242
243
244
245
246
247
248





249
250
251
252
253
254
255
256
257
258




































259
260
261
262
263
264
265
266
267
268
269
270
271
272

273
274
275
276
277




278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294

295
296
297
    case OP_RET: return;
    case OP_SWAP: StackReq(2,2); t1=Pop(); t2=Pop(); Push(t1); Push(t2); break;
    case OP_TRACE: StackReq(3,0); trace_stack(obj); break;
    case OP_WINLEVEL: key_ignored=0; gameover=1; Throw(0); 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;
  gameover=0;
}

const char*execute_turn(int key) {

  if(setjmp(my_env)) return my_error;
  changed=0;
  key_ignored=0;
  lastimage_processing=0;
  vstackptr=0;




  
  if(key_ignored && changed) return "Invalid use of IgnoreKey";
  
  if(key_ignored && changed) return "Invalid use of IgnoreKey";
  if(generation_number<=TY_MAXTYPE) return "Too many generations of objects";
  return 0;
}

const char*init_level(void) {
  if(setjmp(my_env)) return my_error;

  gameover=0;
  changed=0;
  key_ignored=0;
  lastimage_processing=0;
  vstackptr=0;
  move_number=0;
  

  if(generation_number<=TY_MAXTYPE) return "Too many generations of objects";
  return 0;
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>















>
>
>
>
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>














>





>
>
>
>










>






|
>



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
    case OP_RET: return;
    case OP_SWAP: StackReq(2,2); t1=Pop(); t2=Pop(); Push(t1); Push(t2); break;
    case OP_TRACE: StackReq(3,0); trace_stack(obj); break;
    case OP_WINLEVEL: key_ignored=0; gameover=1; Throw(0); break;
    default: Throw("Internal error: Unrecognized opcode");
  }
}

static void trace_message(Uint32 obj) {
  Object*o;
  const char*s;
  if(!traceprefix) {
    optionquery[1]=Q_tracePrefix;
    traceprefix=xrm_get_resource(resourcedb,optionquery,optionquery,2);
    if(!traceprefix) traceprefix="";
  }
  if(msgvars.msg<256) s=standard_message_names[msgvars.msg]; else s=messages[msgvars.msg-256];
  o=msgvars.from==VOIDLINK?0:objects[msgvars.from];
  printf("%s%d : %s : %d : %u %u",traceprefix,move_number,s,vstackptr,o?o->generation:0,o?msgvars.from:0);
  if(o) printf(" [$%s %d %d]",classes[o->class]->name,o->x,o->y);
  o=objects[obj];
  printf(" : %u %u [$%s %d %d]",o->generation,obj,classes[o->class]->name,o->x,o->y);
  printf(" : %u %u : %u %u\n",msgvars.arg1.t,msgvars.arg1.u,msgvars.arg2.t,msgvars.arg2.u,msgvars.arg3.t,msgvars.arg3.u);
}

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};
  if(main_options['t']) {
    if(from==VOIDLINK || (classes[objects[from]->class]->cflags&CF_TRACEOUT)) {
      if((classes[c]->cflags&CF_TRACEIN) && (message_trace[msg>>3]&(1<<(msg&7)))) trace_message(to);
    }
  }
  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();
  }
}

static Uint32 broadcast(Uint32 from,int c,Uint16 msg,Value arg1,Value arg2,Value arg3,int s) {
  Uint32 t=0;
  Uint32 n,p;
  Object*o;
  Value v;
  if(c && !classes[c]->nmsg && (!classes[0] || !classes[0]->nmsg)) {
    if(s) return 0;
    for(n=0;n<nobjects;n++) if((o=objects[n]) && o->class==c) t++;
    return t;
  }
  if(lastobj==VOIDLINK) return;
  n=lastobj;
  while(o=objects[n]) {
    p=o->prev;
    if(!c || o->class==c) {
      v=send_message(from,n,msg,arg1,arg2,arg3);
      if(s>0) {
        switch(v.t) {
          case TY_NUMBER: t+=v.u; break;
          case TY_CLASS: t++; break;
          case TY_MESSAGE: break;
          default:
            if(v.t<=TY_MAXTYPE) Throw("Invalid return type for BroadcastSum");
            t++;
        }
      } else {
        if(s<0) arg2=v;
        t++;
      }
    }
    if(p==VOIDLINK) break;
    o=objects[p];
  }
  return t;
}

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;
  gameover=0;
}

const char*execute_turn(int key) {
  Uint32 n;
  if(setjmp(my_env)) return my_error;
  changed=0;
  key_ignored=0;
  lastimage_processing=0;
  vstackptr=0;
  for(n=0;n<nobjects;n++) if(objects[n]) {
    objects[n]->distance=0;
    objects[n]->oflags&=~(OF_KEYCLEARED|OF_DONE);
  }
  
  if(key_ignored && changed) return "Invalid use of IgnoreKey";
  
  if(key_ignored && changed) return "Invalid use of IgnoreKey";
  if(generation_number<=TY_MAXTYPE) return "Too many generations of objects";
  return 0;
}

const char*init_level(void) {
  if(setjmp(my_env)) return my_error;
  if(main_options['t']) printf("[Level %d restarted]",level_id);
  gameover=0;
  changed=0;
  key_ignored=0;
  lastimage_processing=0;
  vstackptr=0;
  move_number=0;
  broadcast(0,0,MSG_INIT,NVALUE(0),NVALUE(0),NVALUE(0),0);
  broadcast(0,0,MSG_POSTINIT,NVALUE(0),NVALUE(0),NVALUE(0),0);
  if(generation_number<=TY_MAXTYPE) return "Too many generations of objects";
  return 0;
}

Modified heromesh.h from [92dd4bcba0] to [2d7b9d4e3c].

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#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];
  Uint16 hard[4];
  Uint8 x,y,shape,shovable,image,dir;
  Value misc1,misc2,misc3,misc4,misc5,misc6,misc7;
  Value uservars[0];
} Object;








|







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#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,distance;
  Uint16 sharp[4];
  Uint16 hard[4];
  Uint8 x,y,shape,shovable,image,dir;
  Value misc1,misc2,misc3,misc4,misc5,misc6,misc7;
  Value uservars[0];
} Object;

Modified names.h from [6e0057f4c8] to [dc5ce5565f].

19
20
21
22
23
24
25

26
27
28
29
30
31
32
#define MSG_CREATED 17
#define MSG_POSTINIT 18
#define MSG_END_TURN 19
#define MSG_CLEANUP 20
#define MSG_COLLIDING 21
#define MSG_COLLIDE 22
#define MSG_BIZARRO_SWAP 23

const char*const standard_message_names[]={
 "INIT",
 "CREATE",
 "DESTROY",
 "BEGIN_TURN",
 "ARRIVED",
 "DEPARTED",







>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#define MSG_CREATED 17
#define MSG_POSTINIT 18
#define MSG_END_TURN 19
#define MSG_CLEANUP 20
#define MSG_COLLIDING 21
#define MSG_COLLIDE 22
#define MSG_BIZARRO_SWAP 23
#ifdef HEROMESH_MAIN
const char*const standard_message_names[]={
 "INIT",
 "CREATE",
 "DESTROY",
 "BEGIN_TURN",
 "ARRIVED",
 "DEPARTED",
45
46
47
48
49
50
51

52
53
54
55
56
57
58
 "POSTINIT",
 "END_TURN",
 "CLEANUP",
 "COLLIDING",
 "COLLIDE",
 "BIZARRO_SWAP",
};

#define SND_SPLASH 0
#define SND_POUR 1
#define SND_DOOR 2
#define SND_GLASS 3
#define SND_BANG 4
#define SND_UNHH 5
#define SND_UH_OH 6







>







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 "POSTINIT",
 "END_TURN",
 "CLEANUP",
 "COLLIDING",
 "COLLIDE",
 "BIZARRO_SWAP",
};
#endif
#define SND_SPLASH 0
#define SND_POUR 1
#define SND_DOOR 2
#define SND_GLASS 3
#define SND_BANG 4
#define SND_UNHH 5
#define SND_UH_OH 6
95
96
97
98
99
100
101

102
103
104
105
106
107
108
#define SND_GLISSANT 43
#define SND_BUZZER 44
#define SND_FAROUT 45
#define SND_KEWEL 46
#define SND_WHACK 47
#define SND_STEAM 48
#define SND_HAWK 49

const char*const standard_sound_names[]={
 "SPLASH",
 "POUR",
 "DOOR",
 "GLASS",
 "BANG",
 "UNHH",







>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#define SND_GLISSANT 43
#define SND_BUZZER 44
#define SND_FAROUT 45
#define SND_KEWEL 46
#define SND_WHACK 47
#define SND_STEAM 48
#define SND_HAWK 49
#ifdef HEROMESH_MAIN
const char*const standard_sound_names[]={
 "SPLASH",
 "POUR",
 "DOOR",
 "GLASS",
 "BANG",
 "UNHH",
233
234
235
236
237
238
239

 [191]="SLASH",
 [192]="TILDE",
 [219]="OBRACKET",
 [220]="BACKSLASH",
 [221]="CBRACKET",
 [222]="QUOTE",
};








>
236
237
238
239
240
241
242
243
 [191]="SLASH",
 [192]="TILDE",
 [219]="OBRACKET",
 [220]="BACKSLASH",
 [221]="CBRACKET",
 [222]="QUOTE",
};
#endif

Modified names.js from [1f5387d203] to [98abace569].

136
137
138
139
140
141
142

143
144
145

146

147
148
149
150
151
152

  heromesh_key_names[y]=z;
});
[..."ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"].forEach(x=>{
  heromesh_key_names[x.charCodeAt()]=x;
});
console.log("// Auto-generated! Do not modify directly!");
standard_message_names.forEach(([a,b,c])=>console.log("#define MSG_"+c+" "+b));

console.log("const char*const standard_message_names[]={");
standard_message_names.forEach(([a,b,c])=>console.log(" \""+c+"\","));
console.log("};");

standard_sound_names.forEach((x,y)=>console.log("#define SND_"+x+" "+y));

console.log("const char*const standard_sound_names[]={");
standard_sound_names.forEach(x=>console.log(" \""+x+"\","));
console.log("};");
console.log("const char*const heromesh_key_names[256]={");
Object.keys(heromesh_key_names).forEach(x=>console.log(" ["+x+"]=\""+heromesh_key_names[x]+"\","));
console.log("};");








>



>

>






>
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
  heromesh_key_names[y]=z;
});
[..."ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"].forEach(x=>{
  heromesh_key_names[x.charCodeAt()]=x;
});
console.log("// Auto-generated! Do not modify directly!");
standard_message_names.forEach(([a,b,c])=>console.log("#define MSG_"+c+" "+b));
console.log("#ifdef HEROMESH_MAIN");
console.log("const char*const standard_message_names[]={");
standard_message_names.forEach(([a,b,c])=>console.log(" \""+c+"\","));
console.log("};");
console.log("#endif");
standard_sound_names.forEach((x,y)=>console.log("#define SND_"+x+" "+y));
console.log("#ifdef HEROMESH_MAIN");
console.log("const char*const standard_sound_names[]={");
standard_sound_names.forEach(x=>console.log(" \""+x+"\","));
console.log("};");
console.log("const char*const heromesh_key_names[256]={");
Object.keys(heromesh_key_names).forEach(x=>console.log(" ["+x+"]=\""+heromesh_key_names[x]+"\","));
console.log("};");
console.log("#endif");