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 [c418f63360]:

To Artifact [f785d8c807]:


173
174
175
176
177
178
179

























































































































180
181
182
183
184
185
186
  sqlite3_bind_int(st,2,lvl);
  sqlite3_bind_text(st,3,lvl==LUMP_CLASS_DEF?"CLASS.DEF":lvl==LUMP_LEVEL_IDX?"LEVEL.IDX":sol?".SOL":".LVL",-1,SQLITE_STATIC);
  sqlite3_bind_blob64(st,4,data,sz,0);
  while((e=sqlite3_step(st))==SQLITE_ROW);
  if(e!=SQLITE_DONE) fatal("SQL error (%d): %s\n",e,sqlite3_errmsg(userdb));
  sqlite3_finalize(st);
}


























































































































static void flush_usercache_1(int sol) {
  sqlite3_int64 uc_id=sol?solutionuc:leveluc;
  FILE*fp=sol?solutionfp:levelfp;
  int fd=fileno(fp);
  sqlite3_stmt*st;
  sqlite3_int64 of,of2;







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







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
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
  sqlite3_bind_int(st,2,lvl);
  sqlite3_bind_text(st,3,lvl==LUMP_CLASS_DEF?"CLASS.DEF":lvl==LUMP_LEVEL_IDX?"LEVEL.IDX":sol?".SOL":".LVL",-1,SQLITE_STATIC);
  sqlite3_bind_blob64(st,4,data,sz,0);
  while((e=sqlite3_step(st))==SQLITE_ROW);
  if(e!=SQLITE_DONE) fatal("SQL error (%d): %s\n",e,sqlite3_errmsg(userdb));
  sqlite3_finalize(st);
}

const char*load_level(int lvl) {
  // Load level by ID. Returns null pointer if successful, or an error message if it failed.
  long sz=0;
  unsigned char*buf=lvl>=0?read_lump(FIL_LEVEL,lvl,&sz,0):0;
  unsigned char*p=buf;
  unsigned char*end=buf+sz;
  int i,n,x,y,z;
  Uint32 o;
  Uint32 mru[2];
  if(lvl<0) return "Invalid level ID";
  if(!buf) return "Cannot find level";
  annihilate();
  generation_number=TY_MAXTYPE+1;
  p+=4; // skip level version and level code for now
  pfwidth=(*p++&63)+1;
  pfheight=(*p++&63)+1;
  while(*p && p<end) p++; // skip text for now
  p++; // skip null terminator
  if(p==end) goto bad1;
  x=0;
  y=1;
  n=0;
  mru[0]=mru[1]=VOIDLINK;
  for(;;) {
    if(n) {
      o=objalloc(objects[*mru]->class);
      if(o==VOIDLINK) goto bad3;
      objects[o]->image=objects[*mru]->image;
      objects[o]->misc1=objects[*mru]->misc1;
      objects[o]->misc2=objects[*mru]->misc2;
      objects[o]->misc3=objects[*mru]->misc3;
      objects[o]->dir=objects[*mru]->dir;
      objects[o]->x=++x;
      objects[o]->y=y;
      if(x>pfwidth) goto bad2;
      pflink(o);
      --n;
    } else {
      if(p>=end) goto bad1;
      z=*p++;
      if(z==0xFF) break;
      if(z&0x20) x=*p++;
      if(z&0x10) y=*p++;
      if(z&0x40) x++;
      if(!x || !y || x>pfwidth || y>pfheight) goto bad2;
      if(z&0x80) {
        // MRU
        n=playfield[x+y*64-65]==VOIDLINK?0:1;
        if(mru[n]==VOIDLINK) goto bad1;
        o=objalloc(objects[mru[n]]->class);
        if(o==VOIDLINK) goto bad3;
        objects[o]->image=objects[mru[n]]->image;
        objects[o]->misc1=objects[mru[n]]->misc1;
        objects[o]->misc2=objects[mru[n]]->misc2;
        objects[o]->misc3=objects[mru[n]]->misc3;
        objects[o]->dir=objects[mru[n]]->dir;
        objects[o]->x=x;
        objects[o]->y=y;
        pflink(o);
        n=z&15;
      } else {
        // Not MRU
        n=playfield[x+y*64-65];
        n=n==VOIDLINK?0:objects[n]->down==VOIDLINK?1:2;
        i=*p++;
        i|=*p++<<8;
        o=objalloc(i&0x3FFF);
        if(o==VOIDLINK) goto bad3;
        if(n!=2) mru[n]=o;
        if(i&0x8000) {
          n=objects[o]->class;
          for(i=0;i<classes[n]->nimages;i++) {
            if(classes[n]->images[i]&0x8000) {
              objects[o]->image=i;
              break;
            }
          }
        } else {
          objects[o]->image=*p++;
        }
        objects[o]->dir=z&7;
        if(z&0x08) {
          z=*p++;
          if(z&0xC0) {
            // Misc1
            objects[o]->misc1=UVALUE(p[0]|(p[1]<<8),(z>>0)&3);
            p+=2;
          }
          if((z&0xC0)!=0x40) {
            // Misc2
            objects[o]->misc2=UVALUE(p[0]|(p[1]<<8),(z>>2)&3);
            p+=2;
          }
          if(!((z&0xC0)%0xC0)) {
            // Misc3
            objects[o]->misc1=UVALUE(p[0]|(p[1]<<8),(z>>4)&3);
            p+=2;
          }
        }
        objects[o]->x=x;
        objects[o]->y=y;
        pflink(o);
        n=0;
      }
    }
  }
  // skip level strings for now
  if(p>end) goto bad1;
  free(buf);
  return 0;
bad1:
  free(buf);
  return "Corrupted level data";
bad2:
  free(buf);
  return "Object out of bounds";
bad3:
  free(buf);
  return "Bad object in level";
}

static void flush_usercache_1(int sol) {
  sqlite3_int64 uc_id=sol?solutionuc:leveluc;
  FILE*fp=sol?solutionfp:levelfp;
  int fd=fileno(fp);
  sqlite3_stmt*st;
  sqlite3_int64 of,of2;
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538

539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558

559
560
561
562
563
564
565
      exit(0);
      break;
  }
}

static void do_sql_mode(void) {
  int m=sqlite3_limit(userdb,SQLITE_LIMIT_SQL_LENGTH,-1);
  char*txt=malloc(m);
  int n=0;
  int c;
  int bail=1;
  if(m>1000000) m=1000000;
  txt=malloc(m+2);
  if(!txt) fatal("Allocation failed\n");
  for(;;) {
    c=fgetc(stdin);
    if(c=='\n' || c==EOF) {

      if(!n) continue;
      if(*txt=='#') {
        n=0;
      } else if(*txt=='.') {
        txt[n]=0;
        n=0;
        switch(txt[1]) {
          case 'b': bail=strtol(txt+2,0,0); break;
          case 'f': sqlite3_db_cacheflush(userdb); sqlite3_db_release_memory(userdb); break;
          case 'i': puts(sqlite3_db_filename(userdb,"main")); break;
          case 'q': exit(0); break;
          case 'u': flush_usercache(); break;
          case 'x': sqlite3_enable_load_extension(userdb,strtol(txt+2,0,0)); break;
          default: fatal("Invalid dot command .%c\n",txt[1]);
        }
      } else {
        txt[n]=0;
        if(sqlite3_complete(txt)) {
          n=sqlite3_exec(userdb,txt,test_sql_callback,0,0);
          if(bail && n) fatal("SQL error (%d): %s\n",n,sqlite3_errmsg(userdb));

          n=0;
        } else {
          txt[n++]='\n';
        }
      }
      if(c==EOF) break;
    } else {







|









>




















>







643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
      exit(0);
      break;
  }
}

static void do_sql_mode(void) {
  int m=sqlite3_limit(userdb,SQLITE_LIMIT_SQL_LENGTH,-1);
  char*txt;
  int n=0;
  int c;
  int bail=1;
  if(m>1000000) m=1000000;
  txt=malloc(m+2);
  if(!txt) fatal("Allocation failed\n");
  for(;;) {
    c=fgetc(stdin);
    if(c=='\n' || c==EOF) {
      if(!n && c==EOF) break;
      if(!n) continue;
      if(*txt=='#') {
        n=0;
      } else if(*txt=='.') {
        txt[n]=0;
        n=0;
        switch(txt[1]) {
          case 'b': bail=strtol(txt+2,0,0); break;
          case 'f': sqlite3_db_cacheflush(userdb); sqlite3_db_release_memory(userdb); break;
          case 'i': puts(sqlite3_db_filename(userdb,"main")); break;
          case 'q': exit(0); break;
          case 'u': flush_usercache(); break;
          case 'x': sqlite3_enable_load_extension(userdb,strtol(txt+2,0,0)); break;
          default: fatal("Invalid dot command .%c\n",txt[1]);
        }
      } else {
        txt[n]=0;
        if(sqlite3_complete(txt)) {
          n=sqlite3_exec(userdb,txt,test_sql_callback,0,0);
          if(bail && n) fatal("SQL error (%d): %s\n",n,sqlite3_errmsg(userdb));
          else if(n) fprintf(stderr,"SQL error (%d): %s\n",n,sqlite3_errmsg(userdb));
          n=0;
        } else {
          txt[n++]='\n';
        }
      }
      if(c==EOF) break;
    } else {
632
633
634
635
636
637
638



639
640
641
642
643
644
645
646
647
  load_pictures();
  if(main_options['T']) {
    test_mode();
    return 0;
  }
  init_usercache();
  load_classes();



  if(main_options['x']) {
    fprintf(stderr,"Ready for executing SQL statements.\n");
    do_sql_mode();
    return 0;
  }
  optionquery[1]=Q_maxObjects;
  max_objects=strtoll(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"",0,0)?:0xFFFF0000L;
  return 0; // for(;;) { if(main_options['e']) run_editor(); else run_game(); }
}







>
>
>





<
<


755
756
757
758
759
760
761
762
763
764
765
766
767
768
769


770
771
  load_pictures();
  if(main_options['T']) {
    test_mode();
    return 0;
  }
  init_usercache();
  load_classes();
  optionquery[1]=Q_maxObjects;
  max_objects=strtoll(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"",0,0)?:0xFFFF0000L;
  annihilate();
  if(main_options['x']) {
    fprintf(stderr,"Ready for executing SQL statements.\n");
    do_sql_mode();
    return 0;
  }


  return 0; // for(;;) { if(main_options['e']) run_editor(); else run_game(); }
}