Free Hero Mesh

Check-in [3cce7686db]
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:Partially implement game input handling (so far, recording is not implemented); also implement the input phase and beginning phase so far
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3cce7686dbe71ab0a8c2682124ca2d74c6b2f22f
User & Date: user on 2020-12-16 06:25:50
Other Links: manifest | tags
Context
2020-12-16
07:20
Add class.doc (currently incomplete) check-in: b4a4c13454 user: user tags: trunk
06:25
Partially implement game input handling (so far, recording is not implemented); also implement the input phase and beginning phase so far check-in: 3cce7686db user: user tags: trunk
05:00
Add the backslash key code to the quarks file check-in: 9aaca3d1c5 user: user tags: trunk
Changes

Modified exec.c from [150ed1a0ef] to [c395230e3e].

42
43
44
45
46
47
48

49
50
51
52
53
54
55
static const char*my_error;
static MessageVars msgvars;
static char lastimage_processing,changed,all_flushed;
static Value vstack[VSTACKSIZE];
static int vstackptr;
static const char*traceprefix;
static Uint8 current_key;


#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])

// For arrival/departure masks







>







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
static const char*my_error;
static MessageVars msgvars;
static char lastimage_processing,changed,all_flushed;
static Value vstack[VSTACKSIZE];
static int vstackptr;
static const char*traceprefix;
static Uint8 current_key;
static Value quiz_obj;

#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])

// For arrival/departure masks
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
  Value v;
  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");
            t++;
        }
      } else {
        if(s<0) arg2=v;
        t++;
      }
    }
    if(p==VOIDLINK) break;
    n=p;
  }
  return t;







|








<







1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164

1165
1166
1167
1168
1169
1170
1171
  Value v;
  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) {
        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");
            t++;
        }
      } else {

        t++;
      }
    }
    if(p==VOIDLINK) break;
    n=p;
  }
  return t;
1183
1184
1185
1186
1187
1188
1189
1190


1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203










1204







1205


1206

1207


1208
1209
1210
1211
1212
1213
1214
1215
1216

1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
  nobjects=0;
  free(objects);
  objects=0;
  gameover=0;
}

const char*execute_turn(int key) {
  Uint32 n;


  if(!key) return 0;
  if(setjmp(my_env)) return my_error;
  changed=0;
  key_ignored=0;
  all_flushed=0;
  lastimage_processing=0;
  vstackptr=0;
  current_key=key;
  for(n=0;n<nobjects;n++) if(objects[n]) {
    objects[n]->distance=0;
    objects[n]->oflags&=~(OF_KEYCLEARED|OF_DONE);
    if(objects[n]->anim) objects[n]->anim->count=0;
  }










  







  current_key=0;


  if(key_ignored) return changed?"Invalid use of IgnoreKey":0;

  move_number++;


  
  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]\n",level_id);
  memcpy(globals,initglobals,sizeof(globals));

  gameover=0;
  changed=0;
  key_ignored=0;
  all_flushed=0;
  lastimage_processing=0;
  vstackptr=0;
  move_number=0;
  current_key=0;
  broadcast(VOIDLINK,0,MSG_INIT,NVALUE(0),NVALUE(0),NVALUE(0),0);
  broadcast(VOIDLINK,0,MSG_POSTINIT,NVALUE(0),NVALUE(0),NVALUE(0),0);
  if(generation_number<=TY_MAXTYPE) return "Too many generations of objects";
  return 0;
}







|
>
>













>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>

>
>
|
>

>
>









>













1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
  nobjects=0;
  free(objects);
  objects=0;
  gameover=0;
}

const char*execute_turn(int key) {
  Uint32 m,n;
  Value v;
  int i;
  if(!key) return 0;
  if(setjmp(my_env)) return my_error;
  changed=0;
  key_ignored=0;
  all_flushed=0;
  lastimage_processing=0;
  vstackptr=0;
  current_key=key;
  for(n=0;n<nobjects;n++) if(objects[n]) {
    objects[n]->distance=0;
    objects[n]->oflags&=~(OF_KEYCLEARED|OF_DONE);
    if(objects[n]->anim) objects[n]->anim->count=0;
  }
  // Input phase
  m=VOIDLINK;
  v=NVALUE(0);
  if(!quiz_obj.t) {
    n=lastobj;
    while(n!=VOIDLINK) {
      i=classes[objects[n]->class]->cflags;
      if(i&CF_INPUT) v=send_message(VOIDLINK,n,MSG_KEY,NVALUE(key),v,NVALUE(0));
      if(i&CF_PLAYER) m=n;
      n=objects[n]->prev;
    }
  } else {
    n=quiz_obj.u;
    if(objects[n]->generation!=quiz_obj.t) n=VOIDLINK;
    quiz_obj=NVALUE(0);
    //TODO
    v=send_message(VOIDLINK,n,MSG_KEY,NVALUE(key),NVALUE(0),NVALUE(1));
  }
  current_key=0;
  if(key_ignored) {
    quiz_obj=NVALUE(0);
    return changed?"Invalid use of IgnoreKey":0;
  }
  move_number++;
  // Beginning phase
  if(!all_flushed) broadcast(m,0,MSG_BEGIN_TURN,m==VOIDLINK?NVALUE(objects[m]->x):NVALUE(0),m==VOIDLINK?NVALUE(objects[m]->y):NVALUE(0),v,0);
  
  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]\n",level_id);
  memcpy(globals,initglobals,sizeof(globals));
  quiz_obj=NVALUE(0);
  gameover=0;
  changed=0;
  key_ignored=0;
  all_flushed=0;
  lastimage_processing=0;
  vstackptr=0;
  move_number=0;
  current_key=0;
  broadcast(VOIDLINK,0,MSG_INIT,NVALUE(0),NVALUE(0),NVALUE(0),0);
  broadcast(VOIDLINK,0,MSG_POSTINIT,NVALUE(0),NVALUE(0),NVALUE(0),0);
  if(generation_number<=TY_MAXTYPE) return "Too many generations of objects";
  return 0;
}

Modified game.c from [d0dfda7e81] to [2c811f4938].

16
17
18
19
20
21
22


23
24
25
26
27
28
29
#include "heromesh.h"
#include "quarks.h"
#include "cursorshapes.h"
#include "names.h"

static volatile Uint8 timerflag;
static int exam_scroll;



static void redraw_game(void) {
  char buf[32];
  SDL_Rect r;
  int x,y;
  r.x=r.y=0;
  r.h=screen->h;







>
>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "heromesh.h"
#include "quarks.h"
#include "cursorshapes.h"
#include "names.h"

static volatile Uint8 timerflag;
static int exam_scroll;
static Uint8*inputs;
static int inputs_size,inputs_count;

static void redraw_game(void) {
  char buf[32];
  SDL_Rect r;
  int x,y;
  r.x=r.y=0;
  r.h=screen->h;
134
135
136
137
138
139
140



141
142
143
144
145
146
147
  draw_text(0,40,buf,0xF0,0xF1);
  SDL_UnlockSurface(screen);
  SDL_Flip(screen);
}

static void begin_level(int id) {
  const char*t;



  t=load_level(id)?:init_level();
  if(t) {
    gameover=-1;
    screen_message(t);
  } else {
    gameover=0;
  }







>
>
>







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
  draw_text(0,40,buf,0xF0,0xF1);
  SDL_UnlockSurface(screen);
  SDL_Flip(screen);
}

static void begin_level(int id) {
  const char*t;
  free(inputs);
  inputs=0;
  inputs_size=inputs_count=0;
  t=load_level(id)?:init_level();
  if(t) {
    gameover=-1;
    screen_message(t);
  } else {
    gameover=0;
  }
380
381
382
383
384
385
386





387
388
389
390
391
392
393
394
    }
  }
}

static int game_command(int prev,int cmd,int number,int argc,sqlite3_stmt*args,void*aux) {
  switch(cmd) {
    case '\' ': // Play a move





      return number;
    case '^E': // Edit
      return -2;
    case '^Q': // Quit
      return -1;
    case '^o': // List objects
      list_objects_at(number-65);
      return prev;







>
>
>
>
>
|







385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
    }
  }
}

static int game_command(int prev,int cmd,int number,int argc,sqlite3_stmt*args,void*aux) {
  switch(cmd) {
    case '\' ': // Play a move
      if(inputs_count>=inputs_size) {
        inputs=realloc(inputs,inputs_size+=32);
        if(!inputs) fatal("Allocation failed\n");
      }
      inputs[inputs_count++]=number;
      return 0;
    case '^E': // Edit
      return -2;
    case '^Q': // Quit
      return -1;
    case '^o': // List objects
      list_objects_at(number-65);
      return prev;
423
424
425
426
427
428
429










430
431
432
433
434
435
436
  if(!timerflag) {
    static SDL_Event ev={SDL_USEREVENT};
    SDL_PushEvent(&ev);
  }
  timerflag=1;
  return n;
}











void run_game(void) {
  int i;
  SDL_Event ev;
  set_caption();
  begin_level(level_id);
  redraw_game();







>
>
>
>
>
>
>
>
>
>







433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
  if(!timerflag) {
    static SDL_Event ev={SDL_USEREVENT};
    SDL_PushEvent(&ev);
  }
  timerflag=1;
  return n;
}

static inline void input_move(Uint8 k) {
  const char*t=execute_turn(k);
  if(t) {
    screen_message(t);
    gameover=-1;
    return;
  }
  //TODO: Record this move, if applicable
}

void run_game(void) {
  int i;
  SDL_Event ev;
  set_caption();
  begin_level(level_id);
  redraw_game();
464
465
466
467
468
469
470





471
472
473
474
475
476
      command:
        if(i==-1) exit(0);
        if(i==-2) {
          main_options['e']=1;
          SDL_SetTimer(0,0);
          return;
        }





        redraw_game();
        timerflag=0;
        break;
    }
  }
}







>
>
>
>
>

|




484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
      command:
        if(i==-1) exit(0);
        if(i==-2) {
          main_options['e']=1;
          SDL_SetTimer(0,0);
          return;
        }
        if(inputs_count) {
          //TODO: Check for solution replay
          for(i=0;i<inputs_count && !gameover;i++) input_move(inputs[i]);
          inputs_count=0;
        }
        redraw_game();
        timerflag=0; // ensure we have not missed a timer event
        break;
    }
  }
}