Free Hero Mesh

Check-in [cafa4fd29b]
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:Use the new move list functions in move list import/export functions, and change the type of replay_size from Uint16 to size_t.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: cafa4fd29bb4a262372379de966d6988d7f889f9
User & Date: user on 2022-06-26 04:05:02
Other Links: manifest | tags
Context
2022-06-28
03:57
Some more changes in game.c and in documentation, to work with the new move list encoding/decoding functions. check-in: c295ff21b6 user: user tags: trunk
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
Changes

Modified class.doc from [0fe9aa62ea] to [854a736d64].

1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
HeightAt  ( x y -- height )
  Finds the greatest height among objects at the specified location.

HitMe  ( dir -- bool ) **
  Checks hardness/sharpness and shoving like is done by Move, subject to
  From and Arg3. The direction is a direction relative to From, not to
  Self. The result is 1 if shoving or sharpness is successful, or 0
  otherwise. This will update Arg3,including at least setting the low
  three bits; the new value of Arg3 may then be used as the return value
  from HITBY. It is intended that this instruction is used inside of a
  HITBY block, in case you want to do some of your own processing. The
  Compatible and VisualOnly flags of this object are not checked.

IgnoreKey  ( -- )
  There is no effect outside of the input phase. During the input phase,







|







1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
HeightAt  ( x y -- height )
  Finds the greatest height among objects at the specified location.

HitMe  ( dir -- bool ) **
  Checks hardness/sharpness and shoving like is done by Move, subject to
  From and Arg3. The direction is a direction relative to From, not to
  Self. The result is 1 if shoving or sharpness is successful, or 0
  otherwise. This will update Arg3, including at least setting the low
  three bits; the new value of Arg3 may then be used as the return value
  from HITBY. It is intended that this instruction is used inside of a
  HITBY block, in case you want to do some of your own processing. The
  Compatible and VisualOnly flags of this object are not checked.

IgnoreKey  ( -- )
  There is no effect outside of the input phase. During the input phase,

Modified game.c from [104890bd44] to [dd24aafcf7].

16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
#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;







>
|







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

MoveItem*replay_list;
size_t replay_size;
Uint16 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;
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
  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;







<


>

|







<
<







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
  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;

  free(replay_list);
  replay_list=0;
  replay_size=0;
  replay_count=0;
  FILE*o=open_memstream((char**)&replay_list,&replay_size);
  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");


  return replay_count;
}

static void record_solution(void);

static void setup_game(void) {
  const char*v;
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

static void save_replay(void) {
  long sz=replay_size;
  if(solution_replay || !replay_list) return;
  if(sz<replay_count+6) {
    replay_list=realloc(replay_list,sz=replay_count+6);
    if(!replay_list) fatal("Allocation failed\n");
    replay_size=(sz>0xFFFF?0xFFFF:sz);
  }
  if(gameover==1) solved=1;
  sz=replay_count+6;
  replay_list[sz-6]=replay_mark>>8;
  replay_list[sz-5]=replay_mark;
  replay_list[sz-4]=(level_version+solved-1)>>8;
  replay_list[sz-3]=level_version+solved-1;







|







292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

static void save_replay(void) {
  long sz=replay_size;
  if(solution_replay || !replay_list) return;
  if(sz<replay_count+6) {
    replay_list=realloc(replay_list,sz=replay_count+6);
    if(!replay_list) fatal("Allocation failed\n");
    replay_size=sz;
  }
  if(gameover==1) solved=1;
  sz=replay_count+6;
  replay_list[sz-6]=replay_mark>>8;
  replay_list[sz-5]=replay_mark;
  replay_list[sz-4]=(level_version+solved-1)>>8;
  replay_list[sz-3]=level_version+solved-1;
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
      i=3;
      if(replay_list[2]&1) {
        while(i<sz && replay_list[i]) i++;
        i++;
      }
      if(replay_list[2]&2) i+=8;
      if(i>=sz || sz-i>0xFFFF) goto notfound;
      replay_size=(sz>0xFFFF?0xFFFF:sz);
      memmove(replay_list,replay_list+i,replay_count=sz-i);
      replay_mark=0;
    } else {
      goto notfound;
    }
  } else {
    replay_list=read_userstate(FIL_LEVEL,level_id,&sz);
    if(sz>=2) {
      replay_size=(sz>0xFFFF?0xFFFF:sz);
      replay_count=(replay_list[sz-2]<<8)|replay_list[sz-1];
      if(sz-replay_count>=4) replay_mark=(replay_list[replay_count]<<8)|replay_list[replay_count+1]; else replay_mark=0;
      if(sz-replay_count>=6) {
        i=(replay_list[replay_count+2]<<8)|replay_list[replay_count+3];
        if(i==level_version) solved=1;
      }
    } else {







|








|







322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
      i=3;
      if(replay_list[2]&1) {
        while(i<sz && replay_list[i]) i++;
        i++;
      }
      if(replay_list[2]&2) i+=8;
      if(i>=sz || sz-i>0xFFFF) goto notfound;
      replay_size=sz;
      memmove(replay_list,replay_list+i,replay_count=sz-i);
      replay_mark=0;
    } else {
      goto notfound;
    }
  } else {
    replay_list=read_userstate(FIL_LEVEL,level_id,&sz);
    if(sz>=2) {
      replay_size=sz;
      replay_count=(replay_list[sz-2]<<8)|replay_list[sz-1];
      if(sz-replay_count>=4) replay_mark=(replay_list[replay_count]<<8)|replay_list[replay_count+1]; else replay_mark=0;
      if(sz-replay_count>=6) {
        i=(replay_list[replay_count+2]<<8)|replay_list[replay_count+3];
        if(i==level_version) solved=1;
      }
    } else {
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  int i;
  if(!arg || !arg[strspn(arg," \t")]) return;
  fp=popen(arg,"r");
  if(!fp) {
    screen_message("Unable to open pipe for reading");
    return;
  }
  replay_list=realloc(replay_list,0x10000);
  if(!replay_list) fatal("Allocation failed");
  replay_mark=0;
  replay_size=0xFFFF;
  i=fread(replay_list,1,0xFFFD,fp);
  if(i&~0xFFFF) i=0;
  replay_count=i;
  pclose(fp);
}

static void do_export_moves(const char*arg) {
  FILE*fp;
  int i;
  if(!arg || !arg[strspn(arg," \t")]) return;
  fp=popen(arg,"w");
  if(!fp) {
    screen_message("Unable to open pipe for writing");
    return;
  }
  if(replay_count) fwrite(replay_list,1,replay_count,fp);
  pclose(fp);
}

static void do_load_moves(sqlite3_stmt*st) {
  int i=sqlite3_column_bytes(st,1);
  if(i&~0xFFFF) return;
  if(replay_size<i) replay_list=realloc(replay_list,replay_size=i);







<
<

<
|
<
<












|







708
709
710
711
712
713
714


715

716


717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
  int i;
  if(!arg || !arg[strspn(arg," \t")]) return;
  fp=popen(arg,"r");
  if(!fp) {
    screen_message("Unable to open pipe for reading");
    return;
  }


  replay_mark=0;

  decode_move_list(fp);


  pclose(fp);
}

static void do_export_moves(const char*arg) {
  FILE*fp;
  int i;
  if(!arg || !arg[strspn(arg," \t")]) return;
  fp=popen(arg,"w");
  if(!fp) {
    screen_message("Unable to open pipe for writing");
    return;
  }
  encode_move_list(fp);
  pclose(fp);
}

static void do_load_moves(sqlite3_stmt*st) {
  int i=sqlite3_column_bytes(st,1);
  if(i&~0xFFFF) return;
  if(replay_size<i) replay_list=realloc(replay_list,replay_size=i);

Modified heromesh.h from [afc1524574] to [e542ddb045].

319
320
321
322
323
324
325

326
327
328
329
330
331
332
333
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);








>
|







319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
void swap_world(void);

// == game ==

typedef Uint8 MoveItem;

extern MoveItem*replay_list;
extern size_t replay_size;
extern Uint16 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);