Free Hero Mesh

Check-in [6d36e2c377]
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:Improve the converter program
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6d36e2c3776df381dbedc42221fadad0fd92c66e
User & Date: user on 2018-03-17 06:10:14
Other Links: manifest | tags
Context
2018-03-18
04:37
Finally, class codes can be converted now. check-in: fa63933e67 user: user tags: trunk
2018-03-17
06:10
Improve the converter program check-in: 6d36e2c377 user: user tags: trunk
2018-03-16
01:51
More details figured out of the file format check-in: 67bacbf22a user: user tags: trunk
Changes

Modified mbtofhm.c from [9fbf2afe75] to [fc1c32314d].

36
37
38
39
40
41
42

43
44
45
46
47
48
49
  short nsubslbl;
  unsigned char*subslbl;
  unsigned char*subscode;
  short nmsgslbl;
  unsigned char*msgslbl;
  unsigned short nmsgs;
  unsigned char**msgscode;

} ClassInfo;
static int nusermsg;
static char**usermsg;
static ClassInfo*class[512];

// Levels
static int nlevels;







>







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  short nsubslbl;
  unsigned char*subslbl;
  unsigned char*subscode;
  short nmsgslbl;
  unsigned char*msgslbl;
  unsigned short nmsgs;
  unsigned char**msgscode;
  short defpic;
} ClassInfo;
static int nusermsg;
static char**usermsg;
static ClassInfo*class[512];

// Levels
static int nlevels;
277
278
279
280
281
282
283

284
285
286

287

288


289
290
291
292
293
294
295
  }
  fread(Allocate(class[id]->desc,i+1),1,i,stdin);
  class[id]->desc[i]=0;
  fread(class[id]->attr,1,62,stdin);
  j=fgetc(stdin);
  j|=fgetc(stdin)<<8;
  class[id]->npic=j;

  for(i=0;i<j;i++) {
    k=fgetc(stdin);
    k|=fgetc(stdin)<<8;

    if(i<128) class[id]->pic[i]=k;

  }


  if(j>128) class[id]->npic=128;
  j=fgetc(stdin);
  j|=fgetc(stdin)<<8;
  class[id]->nvars=j;
  fread(Allocate(class[id]->vars,j<<3),j,8,stdin);
  j=fgetc(stdin);
  j|=fgetc(stdin)<<8;







>



>
|
>
|
>
>







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
  }
  fread(Allocate(class[id]->desc,i+1),1,i,stdin);
  class[id]->desc[i]=0;
  fread(class[id]->attr,1,62,stdin);
  j=fgetc(stdin);
  j|=fgetc(stdin)<<8;
  class[id]->npic=j;
  class[id]->defpic=256;
  for(i=0;i<j;i++) {
    k=fgetc(stdin);
    k|=fgetc(stdin)<<8;
    if(i<128) {
      class[id]->pic[i]=k;
      if(k<512 && class[id]->defpic==256 && picavail[k]) class[id]->defpic=i;
    }
  }
  class[id]->defpic&=255;
  if(j>128) class[id]->npic=128;
  j=fgetc(stdin);
  j|=fgetc(stdin)<<8;
  class[id]->nvars=j;
  fread(Allocate(class[id]->vars,j<<3),j,8,stdin);
  j=fgetc(stdin);
  j|=fgetc(stdin)<<8;
320
321
322
323
324
325
326












































































327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361

static inline void do_classes(void) {
  int n;
  n=fgetc(stdin);
  n|=fgetc(stdin)<<8;
  while(n--) read_one_class();
}













































































static inline void out_classes(void) {
  FILE*fp;
  ClassInfo*c;
  int i,j,n;
  sprintf(nam,"%s.class",basename);
  fp=fopen(nam,"w");
  if(!fp) fatal("Cannot open file '%s' for writing\n",nam);
  fprintf(fp,"; Note: This file was automatically converted.\n; Remove this notice if you have corrected it.\n");
  for(n=0;n<512;n++) if(c=class[n]) {
    fprintf(fp,"\n($%s\n  Compatible",c->name);
    if(c->attr[1]&1) fprintf(fp," Input");
    if(c->attr[1]&128) fprintf(fp," Player");
    if(!strcmp(c->name,"Quiz")) fprintf(fp," Quiz");
    fprintf(fp,"\n  (Image");
    for(j=i=0;i<c->npic;i++) {
      fprintf(fp," \"%d\"",c->pic[i]);
      if(picavail[c->pic[i]]) j++;
    }
    fprintf(fp,")\n");
    if(!j) {
      fprintf(fp,"  (DefaultImage ())\n");
    } else if(j!=c->npic) {
      fprintf(fp,"  (DefaultImage");
      for(i=0;i<c->npic;i++) if(picavail[c->pic[i]]) fprintf(fp," %d",i);
      fprintf(fp,")\n");
    }
    //TODO: Description
    if(c->attr[2] || c->attr[3]) fprintf(fp,"  (Misc4 0x%04X)\n",c->attr[2]|(c->attr[3]<<8));
    if(c->attr[4] || c->attr[5]) fprintf(fp,"  (Misc5 0x%04X)\n",c->attr[4]|(c->attr[5]<<8));
    if(c->attr[6] || c->attr[7]) fprintf(fp,"  (Misc6 0x%04X)\n",c->attr[6]|(c->attr[7]<<8));
    if(c->attr[8] || c->attr[9]) fprintf(fp,"  (Misc7 0x%04X)\n",c->attr[8]|(c->attr[9]<<8));
    if(c->attr[50] || c->attr[51]) fprintf(fp,"  (Temperature %d)\n",c->attr[50]|(c->attr[51]<<8));
    if(c->attr[10]) {
      if(c->attr[10]==0x55) {







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










|
















|







326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

static inline void do_classes(void) {
  int n;
  n=fgetc(stdin);
  n|=fgetc(stdin)<<8;
  while(n--) read_one_class();
}

static void out_description(FILE*fp,const char*txt) {
  // CLASS section
  if(!strncmp("[CLASS]\r\n",txt,9)) txt+=9;
  while(txt[0]=='\r' && txt[1]=='\n') txt+=2;
  if(!strncmp("[LEVEL]\r\n",txt,9)) goto level_area;
  if(!strncmp("[GAME]\r\n",txt,8)) goto game_area;
  fprintf(fp,"  ; ");
  for(;;) {
    if(*txt=='\r') {
      if(!strncmp("\r\n[LEVEL]\r\n",txt,11)) {
        fputc('\n',fp);
        txt+=11;
        goto level_area;
      } else if(!strncmp("\r\n[GAME]\r\n",txt,10)) {
        fputc('\n',fp);
        txt+=10;
        goto game_area;
      } else {
        fprintf(fp,"\n  ; ");
        txt+=2;
      }
    } else if(!*txt) {
      fputc('\n',fp);
      return;
    } else {
      fputc(*txt++,fp);
    }
  }
  // LEVEL section
  level_area:
  if(!strncmp("[LEVEL]\r\n",txt,9)) txt+=9;
  while(txt[0]=='\r' && txt[1]=='\n') txt+=2;
  if(!strncmp("[GAME]\r\n",txt,8)) goto game_area;
  fprintf(fp,"  (EditorHelp\n    \"");
  for(;;) {
    if(*txt=='\r') {
      if(!strncmp("\r\n[GAME]\r\n",txt,10)) {
        fprintf(fp,"\"\n  )\n");
        txt+=10;
        goto game_area;
      } else {
        fprintf(fp,"\"\n    \"");
        txt+=2;
      }
    } else if(!*txt) {
      fprintf(fp,"\"\n  )\n");
      return;
    } else {
      if(*txt=='"') fputc('\\',fp);
      fputc(*txt++,fp);
    }
  }
  // GAME section
  game_area:
  if(!strncmp("[GAME]\r\n",txt,8)) txt+=8;
  while(txt[0]=='\r' && txt[1]=='\n') txt+=2;
  fprintf(fp,"  (Help\n    \"");
  for(;;) {
    if(*txt=='\r') {
      if(txt[1]=='\n' && !txt[2]) {
        fprintf(fp,"\"\n  )\n");
        return;
      } else {
        fprintf(fp,"\"\n    \"");
        txt+=2;
      }
    } else if(!*txt) {
      fprintf(fp,"\"\n  )\n");
      return;
    } else {
      if(*txt=='"') fputc('\\',fp);
      fputc(*txt++,fp);
    }
  }
}

static inline void out_classes(void) {
  FILE*fp;
  ClassInfo*c;
  int i,j,n;
  sprintf(nam,"%s.class",basename);
  fp=fopen(nam,"w");
  if(!fp) fatal("Cannot open file '%s' for writing\n",nam);
  fprintf(fp,"; Note: This file was automatically converted.\n; Remove this notice if you have corrected it.\n");
  for(n=0;n<512;n++) if(c=class[n]) {
    fprintf(fp,"\n($%s Compatible",c->name);
    if(c->attr[1]&1) fprintf(fp," Input");
    if(c->attr[1]&128) fprintf(fp," Player");
    if(!strcmp(c->name,"Quiz")) fprintf(fp," Quiz");
    fprintf(fp,"\n  (Image");
    for(j=i=0;i<c->npic;i++) {
      fprintf(fp," \"%d\"",c->pic[i]);
      if(picavail[c->pic[i]]) j++;
    }
    fprintf(fp,")\n");
    if(!j) {
      fprintf(fp,"  (DefaultImage ())\n");
    } else if(j!=c->npic) {
      fprintf(fp,"  (DefaultImage");
      for(i=0;i<c->npic;i++) if(picavail[c->pic[i]]) fprintf(fp," %d",i);
      fprintf(fp,")\n");
    }
    out_description(fp,c->desc);
    if(c->attr[2] || c->attr[3]) fprintf(fp,"  (Misc4 0x%04X)\n",c->attr[2]|(c->attr[3]<<8));
    if(c->attr[4] || c->attr[5]) fprintf(fp,"  (Misc5 0x%04X)\n",c->attr[4]|(c->attr[5]<<8));
    if(c->attr[6] || c->attr[7]) fprintf(fp,"  (Misc6 0x%04X)\n",c->attr[6]|(c->attr[7]<<8));
    if(c->attr[8] || c->attr[9]) fprintf(fp,"  (Misc7 0x%04X)\n",c->attr[8]|(c->attr[9]<<8));
    if(c->attr[50] || c->attr[51]) fprintf(fp,"  (Temperature %d)\n",c->attr[50]|(c->attr[51]<<8));
    if(c->attr[10]) {
      if(c->attr[10]==0x55) {
398
399
400
401
402
403
404








405






406
407
408
409
410
411
412
    }
    if(c->attr[22] || c->attr[23]) fprintf(fp,"  (Density %d)\n",c->attr[22]|(c->attr[23]<<8));
    if(c->attr[24] || c->attr[25]) fprintf(fp,"  (Volume %d)\n",c->attr[24]|(c->attr[25]<<8));
    if(c->attr[26] || c->attr[27]) fprintf(fp,"  (Strength %d)\n",c->attr[26]|(c->attr[27]<<8));
    if(c->attr[28] || c->attr[29]) fprintf(fp,"  (Weight %d)\n",c->attr[28]|(c->attr[29]<<8));
    if(c->attr[46] || c->attr[47]) fprintf(fp,"  (Height %d)\n",c->attr[46]|(c->attr[47]<<8));
    if(c->attr[48] || c->attr[49]) fprintf(fp,"  (Climb %d)\n",c->attr[48]|(c->attr[49]<<8));








    //TODO: Shape






    if(memcmp(c->attr+30,"\0\0\0\0\0\0\0\0",8)) {
      if(memcmp(c->attr+30,c->attr+32,2) || memcmp(c->attr+30,c->attr+34,4)) {
        fprintf(fp,"  (Hard");
        if(c->attr[30] || c->attr[31]) fprintf(fp," (E %d)",c->attr[30]|(c->attr[31]<<8));
        if(c->attr[32] || c->attr[33]) fprintf(fp," (N %d)",c->attr[32]|(c->attr[33]<<8));
        if(c->attr[34] || c->attr[35]) fprintf(fp," (W %d)",c->attr[34]|(c->attr[35]<<8));
        if(c->attr[36] || c->attr[37]) fprintf(fp," (S %d)",c->attr[36]|(c->attr[37]<<8));







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







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
    }
    if(c->attr[22] || c->attr[23]) fprintf(fp,"  (Density %d)\n",c->attr[22]|(c->attr[23]<<8));
    if(c->attr[24] || c->attr[25]) fprintf(fp,"  (Volume %d)\n",c->attr[24]|(c->attr[25]<<8));
    if(c->attr[26] || c->attr[27]) fprintf(fp,"  (Strength %d)\n",c->attr[26]|(c->attr[27]<<8));
    if(c->attr[28] || c->attr[29]) fprintf(fp,"  (Weight %d)\n",c->attr[28]|(c->attr[29]<<8));
    if(c->attr[46] || c->attr[47]) fprintf(fp,"  (Height %d)\n",c->attr[46]|(c->attr[47]<<8));
    if(c->attr[48] || c->attr[49]) fprintf(fp,"  (Climb %d)\n",c->attr[48]|(c->attr[49]<<8));
    switch(i=c->attr[52]) {
      case 0x00:
        // Nothing
        break;
      case 0x55: case 0xAA: case 0xFF:
        fprintf(fp,"  (Shape %d)\n",i&3);
        break;
      default:
        fprintf(fp,"  (Shape");
        if(i&0x03) fprintf(fp," (E %d)",(i>>0)&3);
        if(i&0x0C) fprintf(fp," (N %d)",(i>>2)&3);
        if(i&0x30) fprintf(fp," (W %d)",(i>>4)&3);
        if(i&0xC0) fprintf(fp," (S %d)",(i>>6)&3);
        fprintf(fp,")\n");
    }
    if(memcmp(c->attr+30,"\0\0\0\0\0\0\0\0",8)) {
      if(memcmp(c->attr+30,c->attr+32,2) || memcmp(c->attr+30,c->attr+34,4)) {
        fprintf(fp,"  (Hard");
        if(c->attr[30] || c->attr[31]) fprintf(fp," (E %d)",c->attr[30]|(c->attr[31]<<8));
        if(c->attr[32] || c->attr[33]) fprintf(fp," (N %d)",c->attr[32]|(c->attr[33]<<8));
        if(c->attr[34] || c->attr[35]) fprintf(fp," (W %d)",c->attr[34]|(c->attr[35]<<8));
        if(c->attr[36] || c->attr[37]) fprintf(fp," (S %d)",c->attr[36]|(c->attr[37]<<8));
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
  //     bit6 = Next position
  //     bit5 = New X position
  //     bit4 = New Y position
  //     bit3 = Has MiscVars (RLE in case of MRU)
  //     bit2-bit0 = LastDir (RLE in case of MRU)
  //   * new X if applicable
  //   * new Y if applicable
  //   * class (one-based; add 0x8000 for image 0) (two bytes)
  //   * image (one byte)
  //   * data types (if has MiscVars):
  //     bit7-bit6 = How many (0=has Misc2 and Misc3, not Misc1)
  //     bit5-bit4 = Misc3 type
  //     bit3-bit2 = Misc2 type
  //     bit1-bit0 = Misc1 type
  //   * misc data (variable size)







|







589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
  //     bit6 = Next position
  //     bit5 = New X position
  //     bit4 = New Y position
  //     bit3 = Has MiscVars (RLE in case of MRU)
  //     bit2-bit0 = LastDir (RLE in case of MRU)
  //   * new X if applicable
  //   * new Y if applicable
  //   * class (one-based; add 0x8000 for default image) (two bytes)
  //   * image (one byte)
  //   * data types (if has MiscVars):
  //     bit7-bit6 = How many (0=has Misc2 and Misc3, not Misc1)
  //     bit5-bit4 = Misc3 type
  //     bit3-bit2 = Misc2 type
  //     bit1-bit0 = Misc1 type
  //   * misc data (variable size)
530
531
532
533
534
535
536


537
538
539
540
541


542
543
544
545
546
547
548
    } else if(r) {
      fputc(r+0xBF,fp),r=0;
    }
    fputc(i,fp);
    if(i&0x20) fputc(x,fp);
    if(i&0x10) fputc(y,fp);
    if(i<0x80) {


      if(buf[2]) {
        fwrite(buf,1,3,fp);
      } else {
        fputc(*buf,fp);
        fputc(buf[1]|0x80,fp);


      }
    }
    if(i&0x08) {
      i=buf[5]&0x3F;
      if(buf[14] || buf[15]) i|=0xC0;
      else if(buf[12] || buf[13]) i|=0x80;
      else i|=0x40;







>
>
|
<
<


>
>







626
627
628
629
630
631
632
633
634
635


636
637
638
639
640
641
642
643
644
645
646
    } else if(r) {
      fputc(r+0xBF,fp),r=0;
    }
    fputc(i,fp);
    if(i&0x20) fputc(x,fp);
    if(i&0x10) fputc(y,fp);
    if(i<0x80) {
      j=buf[0]|(buf[1]<<8);
      if(!j || j>512 || !class[j-1]) fatal("Object of invalid class number %d found in level\n",j);
      if(buf[2]==class[j-1]->defpic) {


        fputc(*buf,fp);
        fputc(buf[1]|0x80,fp);
      } else {
        fwrite(buf,1,3,fp);
      }
    }
    if(i&0x08) {
      i=buf[5]&0x3F;
      if(buf[14] || buf[15]) i|=0xC0;
      else if(buf[12] || buf[13]) i|=0x80;
      else i|=0x40;
571
572
573
574
575
576
577


578
579
580
581
582
583
584
          fwrite(buf+14,1,2,fp);
        }
      }
    }
  }
  if(r) fputc(r+0xBF,fp);
  fputc(255,fp); // End of objects


  n=fgetc(stdin);
  n|=fgetc(stdin)<<8;
  while(n--) {
    i=fgetc(stdin);
    i|=fgetc(stdin)<<8;
    // fputc(17,fp); // Select proportional font
    while(i--) {







>
>







669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
          fwrite(buf+14,1,2,fp);
        }
      }
    }
  }
  if(r) fputc(r+0xBF,fp);
  fputc(255,fp); // End of objects
  //TODO: Long alternating sequences of 0xC0 0x80 are common, so we should
  // implement compression of this.
  n=fgetc(stdin);
  n|=fgetc(stdin)<<8;
  while(n--) {
    i=fgetc(stdin);
    i|=fgetc(stdin)<<8;
    // fputc(17,fp); // Select proportional font
    while(i--) {