Free Hero Mesh

Check-in [d872cd754a]
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:Implement creating new objects and linking objects into the playfield (program execution is only started a bit and is not even nearly close to being written enough yet)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d872cd754a833441e9acd147ff277cf82bcaeee2
User & Date: user on 2018-07-02 21:24:50
Other Links: manifest | tags
Context
2018-07-02
21:27
Correct some errors in exec.c introduced in the previous commit check-in: 59319cbd25 user: user tags: trunk
21:24
Implement creating new objects and linking objects into the playfield (program execution is only started a bit and is not even nearly close to being written enough yet) check-in: d872cd754a user: user tags: trunk
2018-06-24
02:12
Implement stack overflow protection check-in: 9f57c48591 user: user tags: trunk
Changes

Modified exec.c from [6979fc1925] to [40d4351374].

9
10
11
12
13
14
15
16
17
18



19






20
21


22















































































































23
24

25
26
27
#include <stdlib.h>
#include <string.h>
#include "sqlite3.h"
#include "smallxrm.h"
#include "heromesh.h"

Uint32 generation_number;
Object*objects;
Uint32 nobjects;
Value globals[0x800];










static jmp_buf my_env;
static int my_error;


















































































































int execute_turn(int key) {
  if(setjmp(my_env)) return my_error;

  
  return 0;
}







|


>
>
>

>
>
>
>
>
>

|
>
>

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

>



9
10
11
12
13
14
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <stdlib.h>
#include <string.h>
#include "sqlite3.h"
#include "smallxrm.h"
#include "heromesh.h"

Uint32 generation_number;
Object**objects;
Uint32 nobjects;
Value globals[0x800];
Uint32 firstobj=VOIDLINK;
Uint32 lastobj=VOIDLINK;
Uint32 playfield[64*64];

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

static jmp_buf my_env;
static const char*my_error;
static MessageVars msgvars;
static char lastimage_processing;

#define Throw(x) (my_error=(x),longjmp(my_env,1))
#define StackReq(x,y)

void pfunlink(Uint32 n) {
  Object*o=objects[n];
  if(o->down==VOIDLINK) playfield[o->x+o->y*64-65]=o->up;
  else objects[o->down]->up=o->up;
  if(o->up!=VOIDLINK) objects[o->up]->down=o->down;
  o->down=o->up=VOIDLINK;
}

void pflink(Uint32 n) {
  Object*o=objects[n];
  int p=o->x+o->y*64-65;
  if(p<0) return;
  if(playfield[p]==VOIDLINK) {
    playfield[p]=n;
  } else {
    Sint32 d=o->density;
    Uint32 m=playfield[p];
    Uint32 t=VOIDLINK;
    while(m!=VOIDLINK && objects[m]->density>=d) t=m,m=objects[m]->up;
    o->down=t;
    o->up=m;
    if(t!=VOIDLINK) objects[t]->up=n; else playfield[p]=n;
    if(m!=VOIDLINK) objects[m]->down=n;
  }
}

#define OBJECT_ARRAY_BLOCK 256
Uint32 objalloc(Uint16 c) {
  // c must be a valid (nonzero) class number, and not a class with CF_GROUP, CF_NOCLASS1, or CF_NOCLASS2 flags.
  Uint32 n;
  Class*cl=classes[c];
  Object*o=calloc(1,sizeof(Object)+cl->uservars*sizeof(Value));
  if(!o) fatal("Allocation failed\n");
  o->class=c;
  o->generation=generation_number;
#define C(x) o->x=cl->x;
  C(height) C(weight) C(climb) C(density) C(volume) C(strength) C(arrivals) C(departures) C(temperature)
  C(shape) C(shovable) C(oflags)
  C(sharp[0]) C(sharp[1]) C(sharp[2]) C(sharp[3])
  C(hard[0]) C(hard[1]) C(hard[2]) C(hard[3])
#undef C
  o->misc4=NVALUE(cl->misc4);
  o->misc5=NVALUE(cl->misc5);
  o->misc6=NVALUE(cl->misc6);
  o->misc7=NVALUE(cl->misc7);
  if(nobjects) for(n=nobjects-1;;n--) {
    if(!objects[n]) goto found;
    if(!n) break;
  }
  if(nobjects>=0xFFFF0000L) fatal("Too many objects\n");
  objects=realloc(objects,(nobjects+OBJECT_ARRAY_BLOCK)*sizeof(Object*));
  if(!objects) fatal("Allocation failed\n");
  for(n=nobjects;n<nobjects+OBJECT_ARRAY_BLOCK;n++) objects[n]=0;
  n=nobjects;
  nobjects+=OBJECT_ARRAY_BLOCK;
  found:
  o->up=o->down=o->prev=o->next=VOIDLINK;
  if(cl->nmsg || classes[0]->nmsg) {
    o->prev=lastobj;
    if(lastobj!=VOIDLINK) objects[lastobj]->next=n;
    lastobj=n;
    if(firstobj==VOIDLINK) firstobj=n;
  }
  objects[n]=o;
  return n;
}

static void execute_program(Uint16*code,int ptr,Uint32 obj) {
  Object*o=objects[obj];
  if(StackProtection()) Throw("Call stack overflow");
  for(;;) switch(code[ptr++]) {
    case OP_GOTO: ptr=code[ptr]; break;
    case OP_CALLSUB: execute_program(code,code[ptr++],obj); break;
    case OP_RET: return;
    default: Throw("Internal error: Unrecognized opcode");
  }
}

static Value send_message(Uint32 from,Uint32 to,Uint16 msg,Value arg1,Value arg2,Value arg3) {
  MessageVars saved=msgvars;
  Uint16 c=classes[objects[to]->class];
  Uint16 p=get_message_ptr(c,msg);
  Uint16*code;
  if(p==0xFFFF) {
    p=get_message_ptr(0,msg);
    if(!p) return NVALUE(0);
    code=classes[0]->codes;
  } else {
    code=classes[c]->codes;
  }
  
  msgvars={msg,from,arg1,arg2,arg3};
  execute_program(code,p,to);
  msgvars=saved;
  
}

void annihilate(void) {
  Uint32 i;
  if(!objects) return;
  for(i=0;i<nobjects;i++) free(objects[i]);
  nobjects=0;
  free(objects);
  objects=0;
  firstobj=lastobj=VOIDLINK;
  for(i=0;i<64*64;i++) playfield[i]=VOIDLINK;
}

const char*execute_turn(int key) {
  if(setjmp(my_env)) return my_error;
  lastimage_processing=0;
  
  return 0;
}

Modified heromesh.h from [11a368eb64] to [38fd763986].

25
26
27
28
29
30
31

32
33
34
35
36
37
38
} Value;
#define UVALUE(x,y) ((Value){.u=x,.t=y})
#define SVALUE(x,y) ((Value){.s=x,.t=y})
#define NVALUE(x) SVALUE(x,TY_NUMBER)
#define CVALUE(x) UVALUE(x,TY_CLASS)
#define MVALUE(x) UVALUE(x,TY_MESSAGE)
#define ZVALUE(x) UVALUE(x,TY_STRING)


#define N_MESSAGES 23
extern const char*const standard_message_names[];
extern const char*const standard_sound_names[];
extern const char*const heromesh_key_names[256];

extern sqlite3*userdb;







>







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
} Value;
#define UVALUE(x,y) ((Value){.u=x,.t=y})
#define SVALUE(x,y) ((Value){.s=x,.t=y})
#define NVALUE(x) SVALUE(x,TY_NUMBER)
#define CVALUE(x) UVALUE(x,TY_CLASS)
#define MVALUE(x) UVALUE(x,TY_MESSAGE)
#define ZVALUE(x) UVALUE(x,TY_STRING)
#define OVALUE(x) UVALUE(x,objects[x]->generation)

#define N_MESSAGES 23
extern const char*const standard_message_names[];
extern const char*const standard_sound_names[];
extern const char*const heromesh_key_names[256];

extern sqlite3*userdb;
142
143
144
145
146
147
148


149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
166
167
168


169






const UserCommand*find_key_binding(SDL_Event*ev,int editing);

// == function ==

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

// == exec ==



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

typedef struct {
  Sint32 height,weight,climb,density,volume,strength,arrivals,departures,temperature;
  Uint32 arrived,departed,arrived2,departed2,generation,up;

  Uint16 class,oflags;
  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 generation_number;
extern Object*objects;
extern Uint32 nobjects;
extern Value globals[0x800];
















>
>







|
>









|


>
>

>
>
>
>
>
>
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
const UserCommand*find_key_binding(SDL_Event*ev,int editing);

// == function ==

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

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;
  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 generation_number;
extern Object**objects;
extern Uint32 nobjects;
extern Value globals[0x800];
extern Uint32 firstobj,lastobj;
extern Uint32 playfield[64*64];

void pfunlink(Uint32 n);
void pflink(Uint32 n);
Uint32 objalloc(Uint16 c);
void annihilate(void);
const char*execute_turn(int key);