Free Hero Mesh

Check-in [77553ee70b]
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:Start to implement move list encoding, to be used in future if coordinate input is implemented (and possibly other features that might benefit from this capability).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 77553ee70b720d9417f152e44e0fca77a07b9918
User & Date: user on 2022-06-22 22:40:15
Other Links: manifest | tags
Context
2022-06-26
04:05
Use the new move list functions in move list import/export functions, and change the type of replay_size from Uint16 to size_t. check-in: cafa4fd29b user: user tags: trunk
2022-06-22
22:40
Start to implement move list encoding, to be used in future if coordinate input is implemented (and possibly other features that might benefit from this capability). check-in: 77553ee70b user: user tags: trunk
2022-06-15
21:33
In the OBJECTS virtual table, efficiently check if you are trying to find only bizarro objects in the normal world or vice versa. check-in: 4d77f3e034 user: user tags: trunk
Changes

Modified exec.c from [a97a36c4b3] to [cb23d27153].

3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
    case OP_WALKABLE_C: StackReq(3,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); t3=Pop(); i=(t3.t==TY_CLASS?v_walkable_c(t3.u,t1.u,t2.u):v_walkable(v_object(t3),t1.u,t2.u)); Push(NVALUE(i)); break;
    case OP_WEIGHT: StackReq(0,1); Push(NVALUE(o->weight)); break;
    case OP_WEIGHT_C: StackReq(1,1); Push(GetVariableOrAttributeOf(weight,NVALUE)); break;
    case OP_WEIGHT_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->weight=t1.u; break;
    case OP_WEIGHT_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->weight=t1.u&0xFFFF; break;
    case OP_WEIGHT_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->weight=t1.u; break;
    case OP_WEIGHT_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->weight=t1.u&0xFFFF; break;
    case OP_WINLEVEL: key_ignored=0; gameover=1; gameover_score=move_number+1; Throw(0); break;
    case OP_WINLEVEL_C: StackReq(1,0); t1=Pop(); Numeric(t1); key_ignored=0; gameover=1; gameover_score=t1.s; Throw(0); break;
    case OP_XDIR: StackReq(1,1); t1=Pop(); Numeric(t1); Push(NVALUE(o->x+x_delta[resolve_dir(obj,t1.u)])); break;
    case OP_XDIR_C: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else Push(NVALUE(objects[i]->x+x_delta[resolve_dir(i,t1.u)])); break;
    case OP_XLOC: StackReq(0,1); Push(NVALUE(o->x)); break;
    case OP_XLOC_C: StackReq(1,1); Push(GetVariableOf(x,NVALUE)); break;
    case OP_XSTEP: StackReq(1,1); t1=Pop(); Numeric(t1); Push(NVALUE(x_delta[resolve_dir(obj,t1.u)])); break;
    case OP_XSTEP_C: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else Push(NVALUE(x_delta[resolve_dir(i,t1.u)])); break;







|







3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
    case OP_WALKABLE_C: StackReq(3,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); t3=Pop(); i=(t3.t==TY_CLASS?v_walkable_c(t3.u,t1.u,t2.u):v_walkable(v_object(t3),t1.u,t2.u)); Push(NVALUE(i)); break;
    case OP_WEIGHT: StackReq(0,1); Push(NVALUE(o->weight)); break;
    case OP_WEIGHT_C: StackReq(1,1); Push(GetVariableOrAttributeOf(weight,NVALUE)); break;
    case OP_WEIGHT_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->weight=t1.u; break;
    case OP_WEIGHT_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->weight=t1.u&0xFFFF; break;
    case OP_WEIGHT_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->weight=t1.u; break;
    case OP_WEIGHT_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->weight=t1.u&0xFFFF; break;
    case OP_WINLEVEL: key_ignored=0; gameover=1; gameover_score=NO_SCORE; Throw(0); break;
    case OP_WINLEVEL_C: StackReq(1,0); t1=Pop(); Numeric(t1); key_ignored=0; gameover=1; gameover_score=t1.s; Throw(0); break;
    case OP_XDIR: StackReq(1,1); t1=Pop(); Numeric(t1); Push(NVALUE(o->x+x_delta[resolve_dir(obj,t1.u)])); break;
    case OP_XDIR_C: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else Push(NVALUE(objects[i]->x+x_delta[resolve_dir(i,t1.u)])); break;
    case OP_XLOC: StackReq(0,1); Push(NVALUE(o->x)); break;
    case OP_XLOC_C: StackReq(1,1); Push(GetVariableOf(x,NVALUE)); break;
    case OP_XSTEP: StackReq(1,1); t1=Pop(); Numeric(t1); Push(NVALUE(x_delta[resolve_dir(obj,t1.u)])); break;
    case OP_XSTEP_C: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else Push(NVALUE(x_delta[resolve_dir(i,t1.u)])); break;

Modified function.c from [e594635ab6] to [d994ad6d78].

325
326
327
328
329
330
331










332




333
334
335
336
337
338
339
}

static void fn_modstate(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  sqlite3_result_int(cxt,SDL_GetModState());
}

static void fn_move_list(sqlite3_context*cxt,int argc,sqlite3_value**argv) {










  if(replay_count) sqlite3_result_blob(cxt,replay_list,replay_count,SQLITE_TRANSIENT);




}

static void fn_movenumber(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  sqlite3_result_int(cxt,replay_pos);
}

static void fn_mvalue(sqlite3_context*cxt,int argc,sqlite3_value**argv) {







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







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
}

static void fn_modstate(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  sqlite3_result_int(cxt,SDL_GetModState());
}

static void fn_move_list(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  char*p=0;
  size_t s=0;
  FILE*f=open_memstream(&p,&s);
  if(!f) {
    sqlite3_result_error_nomem(cxt);
    return;
  }
  encode_move_list(f);
  fclose(f);
  if(s) {
    sqlite3_result_blob(cxt,p,s,free);
  } else {
    sqlite3_result_zeroblob(cxt,0);
    free(p);
  }
}

static void fn_movenumber(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  sqlite3_result_int(cxt,replay_pos);
}

static void fn_mvalue(sqlite3_context*cxt,int argc,sqlite3_value**argv) {

Modified game.c from [3e921952d6] to [104890bd44].

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36









































37
38
39
40
41
42
43
#include "sqlite3.h"
#include "smallxrm.h"
#include "heromesh.h"
#include "quarks.h"
#include "cursorshapes.h"
#include "names.h"

Uint8*replay_list;
Uint16 replay_size,replay_count,replay_pos,replay_mark;
Uint8 solution_replay=255;

static volatile Uint8 timerflag;
static int exam_scroll;
static Uint8*inputs;
static int inputs_size,inputs_count;
static Uint8 side_mode=255;
static Uint8 should_record_solution;
static Uint8 replay_speed;
static Uint8 replay_time;
static Uint8 solved;
static Uint8 inserting,saved_inserting;
static sqlite3_stmt*autowin;










































static void record_solution(void);

static void setup_game(void) {
  const char*v;
  optionquery[1]=Q_showInventory;
  v=xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"";







|





|








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







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "sqlite3.h"
#include "smallxrm.h"
#include "heromesh.h"
#include "quarks.h"
#include "cursorshapes.h"
#include "names.h"

MoveItem*replay_list;
Uint16 replay_size,replay_count,replay_pos,replay_mark;
Uint8 solution_replay=255;

static volatile Uint8 timerflag;
static int exam_scroll;
static MoveItem*inputs;
static int inputs_size,inputs_count;
static Uint8 side_mode=255;
static Uint8 should_record_solution;
static Uint8 replay_speed;
static Uint8 replay_time;
static Uint8 solved;
static Uint8 inserting,saved_inserting;
static sqlite3_stmt*autowin;

int encode_move(FILE*fp,MoveItem v) {
  // Encodes a single move and writes the encoded move to the file.
  // Returns the number of bytes of the encoded move.
  fputc(v,fp);
  return 1;
}

int encode_move_list(FILE*fp) {
  // Encodes the current replay list into the file; returns the number of bytes.
  fwrite(replay_list,1,replay_count,fp);
  return replay_count;
}

MoveItem decode_move(FILE*fp) {
  // Decodes a single move from the file, and returns the move.
  // Returns zero if there is no more moves.
  int v=fgetc(fp);
  return (v==EOF?0:v);
}

int decode_move_list(FILE*fp) {
  // Decodes a move list from the file, and stores it in replay_list and replay_count.
  // Returns the number of moves (replay_count).
  MoveItem v;
  size_t s=0;
  free(replay_list);
  replay_list=0;
  replay_count=0;
  FILE*o=open_memstream((char**)&replay_list,&s);
  if(!o) fatal("Allocation failed\n");
  while(replay_count<0xFFFD && (v=decode_move(fp))) {
    fwrite(&v,1,sizeof(MoveItem),o);
    replay_count++;
  }
  fclose(o);
  if(replay_count && !replay_list) fatal("Allocation failed\n");
  s/=sizeof(MoveItem);
  replay_size=(s>0xFFFF?0xFFFF:s);
  return replay_count;
}

static void record_solution(void);

static void setup_game(void) {
  const char*v;
  optionquery[1]=Q_showInventory;
  v=xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"";

Modified heromesh.h from [1eb8371df6] to [afc1524574].

230
231
232
233
234
235
236

237
238
239
240
241
242
243
// == function ==

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

// == exec ==

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


#define ANI_STOP 0x00
#define ANI_ONCE 0x01
#define ANI_LOOP 0x02
#define ANI_OSC 0x08
#define ANI_SYNC 0x80








>







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
// == function ==

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

// == exec ==

#define VOIDLINK ((Uint32)(-1))
#define NO_SCORE ((Sint32)(0x80000000))

#define ANI_STOP 0x00
#define ANI_ONCE 0x01
#define ANI_LOOP 0x02
#define ANI_OSC 0x08
#define ANI_SYNC 0x80

315
316
317
318
319
320
321


322
323
324





325
326
327
328
329
330
331
void annihilate(void);
const char*execute_turn(int key);
const char*init_level(void);
void swap_world(void);

// == game ==



extern Uint8*replay_list;
extern Uint16 replay_size,replay_count,replay_pos,replay_mark;
extern Uint8 solution_replay;






void run_game(void);
void run_auto_test(void);
void locate_me(int x,int y);

// == edit ==








>
>
|


>
>
>
>
>







316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
void annihilate(void);
const char*execute_turn(int key);
const char*init_level(void);
void swap_world(void);

// == game ==

typedef Uint8 MoveItem;

extern MoveItem*replay_list;
extern Uint16 replay_size,replay_count,replay_pos,replay_mark;
extern Uint8 solution_replay;

int encode_move(FILE*fp,MoveItem v);
int encode_move_list(FILE*fp);
MoveItem decode_move(FILE*fp);
int decode_move_list(FILE*fp);

void run_game(void);
void run_auto_test(void);
void locate_me(int x,int y);

// == edit ==