Free Hero Mesh

Check-in [655771dcba]
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:Add the maxTrigger resource, to try to prevent some kinds of infinite loops
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 655771dcba2eb90ffdd086f09962806fbf363545
User & Date: user on 2021-03-30 06:32:46
Other Links: manifest | tags
Context
2021-03-31
07:04
Remove the unimplemented QueueTurn instruction. check-in: e6516c4496 user: user tags: trunk
2021-03-30
06:32
Add the maxTrigger resource, to try to prevent some kinds of infinite loops check-in: 655771dcba user: user tags: trunk
2021-03-29
23:48
Implement saving solutions. check-in: 07dd5d8d17 user: user tags: trunk
Changes

Modified config.doc from [51ec860823] to [dcc6a279c8].

53
54
55
56
57
58
59






60
61
62
63
64
65
66
  Specifies the 1-based order number of the level to start at.

.margin
  The X coordinate of the left margin. To the left is the status area, and
  to the right of the margin is the playfield. This should be at least 64,
  or the picture size, whichever is greater.







.palette
  If defined, the file name of the palette to use (if not set, then the
  internal palette is used instead). The file format is hex rrggbb format
  separated by any kind of whitespaces.

.progress
  If positive, how many steps between dots in the progress report for the







>
>
>
>
>
>







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  Specifies the 1-based order number of the level to start at.

.margin
  The X coordinate of the left margin. To the left is the status area, and
  to the right of the margin is the playfield. This should be at least 64,
  or the picture size, whichever is greater.

.maxTrigger
  If nonzero, the maximum number of times that the trigger phase may loop
  during each turn (it starts counting from zero each turn). If it loops
  more, it displays an error message and results in loss of game. (This
  does not prevent other kinds of infinite loops, though.)

.palette
  If defined, the file name of the palette to use (if not set, then the
  internal palette is used instead). The file format is hex rrggbb format
  separated by any kind of whitespaces.

.progress
  If positive, how many steps between dots in the progress report for the

Modified default.heromeshrc from [3ef6cce4af] to [29103a4844].

1
2
3
4
5
6

7
8
9
10
11
12
13
! Hero Mesh configuration settings
?.screenWidth: 800
?.screenHeight: 600
?.imageSize: 24
?.traceAll: true
?.showInventory: 0


! Game inputs
?.gameKey.A: 'A
?.gameKey.B: 'B
?.gameKey.C: 'C
?.gameKey.D: 'D
?.gameKey.E: 'E






>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
! Hero Mesh configuration settings
?.screenWidth: 800
?.screenHeight: 600
?.imageSize: 24
?.traceAll: true
?.showInventory: 0
?.maxTrigger: 32767

! Game inputs
?.gameKey.A: 'A
?.gameKey.B: 'B
?.gameKey.C: 'C
?.gameKey.D: 'D
?.gameKey.E: 'E

Modified exec.c from [0b49747d29] to [6e356ea1be].

36
37
38
39
40
41
42

43
44
45
46
47
48
49
Uint32 ninventory;
unsigned char**levelstrings;
Uint16 nlevelstrings;
Value*array_data;
Uint16 ndeadanim;
DeadAnimation*deadanim;
Uint8 no_dead_anim;


typedef struct {
  Uint16 msg;
  Uint32 from;
  Value arg1,arg2,arg3;
} MessageVars;








>







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Uint32 ninventory;
unsigned char**levelstrings;
Uint16 nlevelstrings;
Value*array_data;
Uint16 ndeadanim;
DeadAnimation*deadanim;
Uint8 no_dead_anim;
Uint32 max_trigger;

typedef struct {
  Uint16 msg;
  Uint32 from;
  Value arg1,arg2,arg3;
} MessageVars;

1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
      if(a->step[a->lstep].start>a->step[a->lstep].end) --o->image; else ++o->image;
    }
  }
}

const char*execute_turn(int key) {
  Uint8 busy,clock,x,y;
  Uint32 m,n,turn;
  Object*o;
  Value v;
  int i;
  if(!key) {
    // This is part of initialization; if anything triggered, it must be executed now
    all_flushed=1;
    goto trig;







|







1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
      if(a->step[a->lstep].start>a->step[a->lstep].end) --o->image; else ++o->image;
    }
  }
}

const char*execute_turn(int key) {
  Uint8 busy,clock,x,y;
  Uint32 m,n,turn,tc;
  Object*o;
  Value v;
  int i;
  if(!key) {
    // This is part of initialization; if anything triggered, it must be executed now
    all_flushed=1;
    goto trig;
1955
1956
1957
1958
1959
1960
1961

1962
1963
1964
1965
1966
1967
1968
  }
  changed=0;
  key_ignored=0;
  all_flushed=0;
  lastimage_processing=0;
  vstackptr=0;
  current_key=key;

  for(n=0;n<nobjects;n++) if(o=objects[n]) {
    o->distance=0;
    o->oflags&=~(OF_KEYCLEARED|OF_DONE);
    if(o->anim) {
      o->anim->count=0;
      if(o->anim->status==ANISTAT_VISUAL) o->anim->status=0;
    }







>







1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
  }
  changed=0;
  key_ignored=0;
  all_flushed=0;
  lastimage_processing=0;
  vstackptr=0;
  current_key=key;
  tc=0;
  for(n=0;n<nobjects;n++) if(o=objects[n]) {
    o->distance=0;
    o->oflags&=~(OF_KEYCLEARED|OF_DONE);
    if(o->anim) {
      o->anim->count=0;
      if(o->anim->status==ANISTAT_VISUAL) o->anim->status=0;
    }
1995
1996
1997
1998
1999
2000
2001



2002
2003
2004
2005
2006
2007
2008
  if(!all_flushed) {
    if(m==VOIDLINK) x=0,y=0; else x=objects[m]->x,y=objects[m]->y;
    broadcast(m,0,MSG_BEGIN_TURN,NVALUE(x),NVALUE(y),v,0);
  }
  turn=0;
  // Trigger phase
  trig:



  busy=0;
  clock=255;
  for(i=0;i<64*pfheight;i++) {
    n=playfield[i];
    while(n!=VOIDLINK) {
      o=objects[n];
      m=o->up;







>
>
>







1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
  if(!all_flushed) {
    if(m==VOIDLINK) x=0,y=0; else x=objects[m]->x,y=objects[m]->y;
    broadcast(m,0,MSG_BEGIN_TURN,NVALUE(x),NVALUE(y),v,0);
  }
  turn=0;
  // Trigger phase
  trig:
  if(max_trigger) {
    if(tc++>=max_trigger) return "Turn looped too many times";
  }
  busy=0;
  clock=255;
  for(i=0;i<64*pfheight;i++) {
    n=playfield[i];
    while(n!=VOIDLINK) {
      o=objects[n];
      m=o->up;

Modified heromesh.h from [81f8d108e9] to [c3de22e2d5].

260
261
262
263
264
265
266

267
268
269
270
271
272
273
extern Uint32 ninventory;
extern unsigned char**levelstrings;
extern Uint16 nlevelstrings;
extern Value*array_data;
extern Uint16 ndeadanim;
extern DeadAnimation*deadanim;
extern Uint8 no_dead_anim;


const unsigned char*value_string_ptr(Value v);
void pfunlink(Uint32 n);
void pflink(Uint32 n);
Uint32 objalloc(Uint16 c);
void objtrash(Uint32 n);
void annihilate(void);







>







260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
extern Uint32 ninventory;
extern unsigned char**levelstrings;
extern Uint16 nlevelstrings;
extern Value*array_data;
extern Uint16 ndeadanim;
extern DeadAnimation*deadanim;
extern Uint8 no_dead_anim;
extern Uint32 max_trigger;

const unsigned char*value_string_ptr(Value v);
void pfunlink(Uint32 n);
void pflink(Uint32 n);
Uint32 objalloc(Uint16 c);
void objtrash(Uint32 n);
void annihilate(void);

Modified main.c from [021cdac3a0] to [3e8c9f68c8].

911
912
913
914
915
916
917


918
919
920
921
922
923
924
925
926
927
  load_level_index();
  optionquery[1]=Q_maxObjects;
  max_objects=strtoll(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"",0,0)?:0xFFFF0000L;
  set_tracing();
  annihilate();
  optionquery[1]=Q_level;
  if(level_ord=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"",0,10)) log_if_error(load_level(-level_ord));


  if(main_options['a']) run_auto_test();
  if(main_options['x']) {
    fprintf(stderr,"Ready for executing SQL statements.\n");
    no_dead_anim=1;
    do_sql_mode();
    return 0;
  }
  set_autosave();
  for(;;) { if(main_options['e']) run_editor(); else run_game(); }
}







>
>










911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
  load_level_index();
  optionquery[1]=Q_maxObjects;
  max_objects=strtoll(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"",0,0)?:0xFFFF0000L;
  set_tracing();
  annihilate();
  optionquery[1]=Q_level;
  if(level_ord=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"",0,10)) log_if_error(load_level(-level_ord));
  optionquery[1]=Q_maxTrigger;
  max_trigger=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"",0,10);
  if(main_options['a']) run_auto_test();
  if(main_options['x']) {
    fprintf(stderr,"Ready for executing SQL statements.\n");
    no_dead_anim=1;
    do_sql_mode();
    return 0;
  }
  set_autosave();
  for(;;) { if(main_options['e']) run_editor(); else run_game(); }
}

Modified quarks from [b4afbd56b7] to [070f56c8ad].

214
215
216
217
218
219
220

221
stackProtection
maxObjects
traceAll
traceObject
showInventory
progress
autoSave









>

214
215
216
217
218
219
220
221
222
stackProtection
maxObjects
traceAll
traceObject
showInventory
progress
autoSave
maxTrigger

Modified quarks.h from [41522ff9b6] to [37ad5affad].

179
180
181
182
183
184
185

186
187
188
189
190
191
192
#define Q_stackProtection 180
#define Q_maxObjects 181
#define Q_traceAll 182
#define Q_traceObject 183
#define Q_showInventory 184
#define Q_progress 185
#define Q_autoSave 186

static const char*const global_quarks[]={
  "screenWidth",
  "screenHeight",
  "margin",
  "palette",
  "popupColors",
  "imageSize",







>







179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#define Q_stackProtection 180
#define Q_maxObjects 181
#define Q_traceAll 182
#define Q_traceObject 183
#define Q_showInventory 184
#define Q_progress 185
#define Q_autoSave 186
#define Q_maxTrigger 187
static const char*const global_quarks[]={
  "screenWidth",
  "screenHeight",
  "margin",
  "palette",
  "popupColors",
  "imageSize",
365
366
367
368
369
370
371

372
373
374
375
376
377
378
  "stackProtection",
  "maxObjects",
  "traceAll",
  "traceObject",
  "showInventory",
  "progress",
  "autoSave",

0};
#ifdef HEROMESH_BINDINGS
static const SDLKey quark_to_key[Q_undo+1-Q_backspace]={
SDLK_BACKSPACE,
SDLK_TAB,
SDLK_CLEAR,
SDLK_RETURN,







>







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
  "stackProtection",
  "maxObjects",
  "traceAll",
  "traceObject",
  "showInventory",
  "progress",
  "autoSave",
  "maxTrigger",
0};
#ifdef HEROMESH_BINDINGS
static const SDLKey quark_to_key[Q_undo+1-Q_backspace]={
SDLK_BACKSPACE,
SDLK_TAB,
SDLK_CLEAR,
SDLK_RETURN,