Free Hero Mesh

Diff
Login
This is a mirror of the main repository for Free Hero Mesh. New tickets and changes will not be accepted at this mirror.

Differences From Artifact [b6ec622234]:

To Artifact [150ed1a0ef]:


169
170
171
172
173
174
175
176







































177

178














































179











180
181
182
183
184
185
186
  objects[n]=0;
  generation_number_inc=1;
}

static inline Uint8 resolve_dir(Uint32 n,Uint32 d) {
  return d<8?d:(objects[n]->dir+d)&7;
}








































static void animate(Uint32 n,Uint32 f,Uint32 a0,Uint32 a1,Uint32 t) {

  objects[n]->image=a0;














































  //TODO











}

static Uint32 obj_above(Uint32 i) {
  Object*o;
  if(i==VOIDLINK) return VOIDLINK;
  o=objects[i];
  i=o->up;








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

>

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







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  objects[n]=0;
  generation_number_inc=1;
}

static inline Uint8 resolve_dir(Uint32 n,Uint32 d) {
  return d<8?d:(objects[n]->dir+d)&7;
}

/*
  Working of animation: There are two separate animations, being logical
  and visual animations. New animations replace the current logical
  animation; if there isn't one, but there is a visual animation, then a
  new logical animation is added at the end. The logical animation is
  always at the same step or ahead of the visual animation.

  - lstep - Step number of the logical animation; this cannot equal or
  exceed max_animation. Only a single logical step is present at once.

  - vstep - Step number of the visual animation; this cannot equal or
  exceed max_animation. The tail of the visual animation is the same as
  the head of the logical animation, and the buffer is circular.

  - status - Contains bit flags. If the ANISTAT_LOGICAL flag is set, then
  it means a logical animation is active. If the ANISTAT_VISUAL flag is
  set, then it means a visual animation is active. ANISTAT_SYNCHRONIZED
  is set only for synchronized animations, which are visual only.

  - ltime - Amount of logical time passed

  - vtime - Number of centiseconds elapsed.

  - vimage - If the status field has the ANISTAT_VISUAL bit set, then this
  will decide the picture to display rather than using the object's image.

  - count - Number of logical animation steps so far this turn. If it is
  equal to max_animation then no more animations can be added this turn.

  Synchronized animations only use vstep, status, and vimage.
*/

static Animation*animalloc(void) {
  Animation*a=malloc(sizeof(Animation)+max_animation*sizeof(AnimationStep));
  if(!a) fatal("Allocation failed\n");
  a->lstep=a->vstep=a->ltime=a->vtime=a->status=a->count=0;
  return a;
}

static void animate(Uint32 n,Uint32 f,Uint32 a0,Uint32 a1,Uint32 t) {
  Animation*an=objects[n]->anim;
  objects[n]->image=a0;
  f&=0x0A;
  if(!an) an=objects[n]->anim=animalloc();
  if(an->status&ANISTAT_SYNCHRONIZED) an->status=0;
  if(an->count==max_animation) f=ANI_STOP;
  if(f&(ANI_ONCE|ANI_LOOP)) {
    switch(an->status) {
      case 0:
        an->vtime=an->lstep=an->vstep=0;
        an->vimage=a0;
        break;
      case ANISTAT_LOGICAL:
        an->vstep=an->lstep;
        an->vtime=0;
        an->vimage=a0;
        break;
      case ANISTAT_VISUAL:
        an->lstep++;
        if(an->lstep>=max_animation) an->lstep=0;
        if(an->lstep==an->vstep && max_animation>1) {
          an->vstep++;
          if(an->vstep==max_animation) an->vstep=0;
          an->vimage=an->step[an->vstep].start;
          an->vtime=0;
        }
        break;
      case ANISTAT_VISUAL|ANISTAT_LOGICAL:
        if(an->lstep==an->vstep) {
          an->vimage=a0;
          an->vtime=0;
        }
        break;
    }
    an->step[an->lstep].flag=f;
    an->step[an->lstep].start=a0;
    an->step[an->lstep].end=a1;
    an->step[an->lstep].speed=t;
    an->ltime=0;
    an->status=ANISTAT_VISUAL|ANISTAT_LOGICAL;
    an->count++;
  } else if(an->lstep==an->vstep) {
    an->status=0;
  } else if(an->status&ANISTAT_LOGICAL) {
    an->lstep=(an->lstep?:max_animation)-1;
    an->status&=~ANISTAT_LOGICAL;
  }
}

static void animate_sync(Uint32 n,Uint32 sl,Uint32 a0) {
  Animation*an=objects[n]->anim;
  objects[n]->image=a0;
  sl&=7;
  if(!an) an=objects[n]->anim=animalloc();
  an->status=ANISTAT_VISUAL|ANISTAT_SYNCHRONIZED;
  an->vimage=a0+anim_slot[sl].frame;
  an->lstep=an->vstep=0;
  an->step->flag=ANI_LOOP|ANI_SYNC;
  an->step->start=a0;
  an->step->slot=sl;
}

static Uint32 obj_above(Uint32 i) {
  Object*o;
  if(i==VOIDLINK) return VOIDLINK;
  o=objects[i];
  i=o->up;
943
944
945
946
947
948
949

950
951
952
953
954
955
956
    case OP_STRENGTH_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->strength=t1.u; break;
    case OP_STRENGTH_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->strength=t1.u&0xFFFF; break;
    case OP_STRENGTH_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->strength=t1.u; break;
    case OP_STRENGTH_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->strength=t1.u; break;
    case OP_SOUND: StackReq(2,0); t2=Pop(); t1=Pop(); break; // Sound not implemented at this time
    case OP_SUB: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u-t2.u)); break;
    case OP_SWAP: StackReq(2,2); t1=Pop(); t2=Pop(); Push(t1); Push(t2); break;

    case OP_TRACE: StackReq(3,0); trace_stack(obj); break;
    case OP_TUCK: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t2); Push(t1); Push(t2); break;
    case OP_USERSIGNAL: StackReq(0,1); if(o->oflags&OF_USERSIGNAL) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_USERSIGNAL_C: StackReq(1,1); GetFlagOf(OF_USERSIGNAL); break;
    case OP_USERSIGNAL_E: NoIgnore(); StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_USERSIGNAL; else o->oflags&=~OF_USERSIGNAL; break;
    case OP_USERSIGNAL_EC: NoIgnore(); StackReq(2,0); SetFlagOf(OF_USERSIGNAL); break;
    case OP_USERSTATE: StackReq(0,1); if(o->oflags&OF_USERSTATE) Push(NVALUE(1)); else Push(NVALUE(0)); break;







>







1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
    case OP_STRENGTH_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->strength=t1.u; break;
    case OP_STRENGTH_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->strength=t1.u&0xFFFF; break;
    case OP_STRENGTH_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->strength=t1.u; break;
    case OP_STRENGTH_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->strength=t1.u; break;
    case OP_SOUND: StackReq(2,0); t2=Pop(); t1=Pop(); break; // Sound not implemented at this time
    case OP_SUB: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u-t2.u)); break;
    case OP_SWAP: StackReq(2,2); t1=Pop(); t2=Pop(); Push(t1); Push(t2); break;
    case OP_SYNCHRONIZE: StackReq(2,0); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); animate_sync(obj,t1.u,t2.u); break;
    case OP_TRACE: StackReq(3,0); trace_stack(obj); break;
    case OP_TUCK: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t2); Push(t1); Push(t2); break;
    case OP_USERSIGNAL: StackReq(0,1); if(o->oflags&OF_USERSIGNAL) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_USERSIGNAL_C: StackReq(1,1); GetFlagOf(OF_USERSIGNAL); break;
    case OP_USERSIGNAL_E: NoIgnore(); StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_USERSIGNAL; else o->oflags&=~OF_USERSIGNAL; break;
    case OP_USERSIGNAL_EC: NoIgnore(); StackReq(2,0); SetFlagOf(OF_USERSIGNAL); break;
    case OP_USERSTATE: StackReq(0,1); if(o->oflags&OF_USERSTATE) Push(NVALUE(1)); else Push(NVALUE(0)); break;
1097
1098
1099
1100
1101
1102
1103

1104
1105
1106
1107
1108
1109
1110
  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);

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







>







1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
  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";