Free Hero Mesh

Check-in [2f7b9e4144]
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:Remove the IOF_DEAD and IOF_ANIM flags; use a different implementation
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2f7b9e414489c9a65c4e967c4d15ccaed095319e
User & Date: user on 2020-12-05 08:02:02
Other Links: manifest | tags
Context
2020-12-05
22:29
Add a few of the things necessary to implement timers, for animation. check-in: 3ec62d29f5 user: user tags: trunk
08:02
Remove the IOF_DEAD and IOF_ANIM flags; use a different implementation check-in: 2f7b9e4144 user: user tags: trunk
03:51
Implement some more instructions, and correct a mistake in the instruction compiler check-in: aa53c20de4 user: user tags: trunk
Changes

Modified exec.c from [526f219188] to [50874cfa56].

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
    case OP_BROADCASTEX_D: StackReq(5,0); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); v_broadcast(obj,t1,t2,t3,t4,t5,0); break;
    case OP_BROADCASTSUM: StackReq(4,1); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_broadcast(obj,t1,t2,t3,t4,NVALUE(0),1)); break;
    case OP_BROADCASTSUMEX: StackReq(5,1); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_broadcast(obj,t1,t2,t3,t4,t5,1)); break;
    case OP_BXOR: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u^t2.u)); break;
    case OP_CALLSUB: execute_program(code,code[ptr++],obj); break;
    case OP_CLASS: StackReq(0,1); Push(CVALUE(o->class)); break;
    case OP_CLASS_C: StackReq(1,1); Push(GetVariableOf(class,CVALUE)); break;
    case OP_DIR: StackReq(0,1); Push(NVALUE(o->dir&7)); break;
    case OP_DISTANCE: StackReq(0,1); Push(NVALUE(o->distance)); 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_EQ: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t2)?1:0)); break;
    case OP_GE: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t2,t1)?0:1)); break;
    case OP_GE_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t2,t1)?0:1)); break;







|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
    case OP_BROADCASTEX_D: StackReq(5,0); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); v_broadcast(obj,t1,t2,t3,t4,t5,0); break;
    case OP_BROADCASTSUM: StackReq(4,1); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_broadcast(obj,t1,t2,t3,t4,NVALUE(0),1)); break;
    case OP_BROADCASTSUMEX: StackReq(5,1); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_broadcast(obj,t1,t2,t3,t4,t5,1)); break;
    case OP_BXOR: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u^t2.u)); break;
    case OP_CALLSUB: execute_program(code,code[ptr++],obj); break;
    case OP_CLASS: StackReq(0,1); Push(CVALUE(o->class)); break;
    case OP_CLASS_C: StackReq(1,1); Push(GetVariableOf(class,CVALUE)); break;
    case OP_DIR: StackReq(0,1); Push(NVALUE(o->dir)); break;
    case OP_DISTANCE: StackReq(0,1); Push(NVALUE(o->distance)); 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_EQ: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t2)?1:0)); break;
    case OP_GE: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t2,t1)?0:1)); break;
    case OP_GE_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t2,t1)?0:1)); break;
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
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;
          default:
            if(v.t<=TY_MAXTYPE) Throw("Invalid return type for BroadcastSum");







|






|







461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
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 && o->generation) t++;
    return t;
  }
  if(lastobj==VOIDLINK) return;
  n=lastobj;
  while(o=objects[n]) {
    p=o->prev;
    if((!c || o->class==c) && o->generation) {
      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;
          default:
            if(v.t<=TY_MAXTYPE) Throw("Invalid return type for BroadcastSum");

Modified function.c from [b98040a48d] to [5bdde93d2d].

252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
static void fn_ovalue(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  Uint32 a;
  if(sqlite3_value_type(*argv)==SQLITE_NULL) {
    sqlite3_result_int(cxt,0);
    return;
  }
  a=sqlite3_value_int64(*argv)&0xFFFFFFFF;
  if(a>=nobjects || !objects[a] || (objects[a]->dir&IOF_DEAD)) return; // result is null if object does not exist
  sqlite3_result_int64(cxt,a|((sqlite3_int64)objects[a]->generation<<32));
}

static void fn_pfsize(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  sqlite3_result_int(cxt,*(Uint8*)sqlite3_user_data(cxt));
}








|







252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
static void fn_ovalue(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  Uint32 a;
  if(sqlite3_value_type(*argv)==SQLITE_NULL) {
    sqlite3_result_int(cxt,0);
    return;
  }
  a=sqlite3_value_int64(*argv)&0xFFFFFFFF;
  if(a>=nobjects || !objects[a] || !objects[a]->generation) return; // result is null if object does not exist
  sqlite3_result_int64(cxt,a|((sqlite3_int64)objects[a]->generation<<32));
}

static void fn_pfsize(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  sqlite3_result_int(cxt,*(Uint8*)sqlite3_user_data(cxt));
}

654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
      }
      goto atxy;
    }
  } else {
    // This shouldn't happen
    return SQLITE_INTERNAL;
  }
  if(!cur->eof && (objects[cur->rowid]->dir&IOF_DEAD)) goto again;
  return SQLITE_OK;
}

static int vt1_objects_filter(sqlite3_vtab_cursor*pcur,int idxNum,const char*idxStr,int argc,sqlite3_value**argv) {
  Cursor*cur=(void*)pcur;
  int i;
  Uint32 t;







|







654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
      }
      goto atxy;
    }
  } else {
    // This shouldn't happen
    return SQLITE_INTERNAL;
  }
  if(!cur->eof && !objects[cur->rowid]->generation) goto again;
  return SQLITE_OK;
}

static int vt1_objects_filter(sqlite3_vtab_cursor*pcur,int idxNum,const char*idxStr,int argc,sqlite3_value**argv) {
  Cursor*cur=(void*)pcur;
  int i;
  Uint32 t;

Modified heromesh.h from [95c7ddddb0] to [c9a54ecacf].

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

void init_sql_functions(sqlite3_int64*ptr0,sqlite3_int64*ptr1);

// == 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, and OF_DESTROYED must be set, too.

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;





extern Uint32 max_objects;
extern Uint32 generation_number;
extern Object**objects;
extern Uint32 nobjects;
extern Value globals[0x800];
extern Uint32 firstobj,lastobj;







|
|
|
<









>



>
>
>
>







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

void init_sql_functions(sqlite3_int64*ptr0,sqlite3_int64*ptr1);

// == exec ==

#define VOIDLINK ((Uint32)(-1))

typedef struct {
  //TODO
} Animation;


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;
  Animation*anim;
  Value misc1,misc2,misc3,misc4,misc5,misc6,misc7;
  Value uservars[0];
} Object;

// Some objects may remain in memory for animation purposes even after they have been
// destroyed. In this case, their "generation" value is zero, and they will always
// have the OF_DESTROYED flag.

extern Uint32 max_objects;
extern Uint32 generation_number;
extern Object**objects;
extern Uint32 nobjects;
extern Value globals[0x800];
extern Uint32 firstobj,lastobj;