Advertisement
Guest User

fmt_mon.c

a guest
Aug 15th, 2012
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.54 KB | None | 0 0
  1. //Credits go to SNV
  2.  
  3. #include "common.h"
  4. #include "sk_pals.h"
  5.  
  6. typedef struct {
  7.   u1 NFrames;
  8.   u1 Unknown; // 0x80
  9.   //frameHeader[NFrames];
  10. } __attribute__ ((packed)) header;
  11.  
  12. typedef struct {
  13.   u4 Off;
  14.   u2 Len;
  15. } __attribute__ ((packed)) frameHeader;
  16.  
  17. typedef struct {
  18.   u2 T; // type or palette?
  19.   u2 Width;
  20.   u2 Height;
  21.   u2 X; // X/Y is where monster's legs are located
  22.   u2 Y;
  23.   u2 R; // 320? related to screen dimension?
  24.   u4 U; // zeroes
  25.   u4 Size; // size of compressed image
  26.   //Data[Size];
  27. } __attribute__ ((packed)) frame;
  28.  
  29.  
  30.  
  31. // palette header
  32. typedef struct {
  33.   u2 Len;
  34.   //u1 Colors[Len*3];
  35. } __attribute__ ((packed)) palHeader;
  36.  
  37.  
  38.  
  39. static void decodeLZ77(u1 *D, u1 *S, int L) {
  40.   u1 *P, *E = S+L;
  41.   int C, B, R;
  42.  
  43.   while (S < E) {
  44.     C = *S++;
  45.     times (B, 8) {
  46.       if (C&(1<<B)) { // backreference: 12-bit distance and 4-bit length
  47.          R = *(u2*)S;
  48.          S += 2;
  49.          P = D-(R>>4);
  50.          R = (R&0xF)+3;
  51.          while(R--) *D++ = *P++;
  52.       } else {
  53.         *D++ = *S++;
  54.       }
  55.     }
  56.   }
  57. }
  58.  
  59. static void decodeRLE(u1 *D, u1 *S, int L) {
  60.   while (L > 0) {
  61.     int C = *S++;
  62.     if (C&0x80) {
  63.       C&=0x7f;
  64.       while (C-- && L--) *D++ = 0;
  65.     } else {
  66.       while (C-- && L--) {
  67.          *D++ = *S++&0x7F; // no idea why, but it overflows at 0x80
  68.       }
  69.     }
  70.   }
  71. }
  72.  
  73.  
  74. static void loadPal(u1 *Out, char *Name) {
  75.   int I;
  76.   palHeader *PH = readFile(0, sizeof(palHeader), Name);
  77.   u1 *Pal = readFile(sizeof(palHeader), PH->Len*3,  Name);
  78.  
  79.   times (I, PH->Len) { // as usual, VGA palette requires color-shift
  80.     Out[I*4+0] = Pal[I*3+0]<<2;
  81.     Out[I*4+1] = Pal[I*3+1]<<2;
  82.     Out[I*4+2] = Pal[I*3+2]<<2;
  83.     Out[I*4+3] = 0;
  84.   }
  85.  
  86.   free(Pal);
  87. }
  88.  
  89. spr *monLoad(char *Input) {
  90.   char Tmp[1024], Dir[1024], Name[128], Ext[32];
  91.   u1 *Buf;
  92.   int I, J, X, Y, C;
  93.   spr *S;
  94.   pic *P;
  95.   u1 *Pal;
  96.   frame *F;
  97.   int L = fileSize(Input);
  98.   u1 *D = readFile(0, L, Input);
  99.   header *H = (header*)D;
  100.   frameHeader *FH = (frameHeader*)(D+sizeof(header));
  101.  
  102.   pathParts(Dir, Name, Ext, Input);
  103.   downcase(Ext);
  104.  
  105.   S = sprNew();
  106.   S->Palette = ns(u1, 4*256);
  107.  
  108.   sprintf(Tmp, "%s/%s.PAL", Dir, Name);
  109.  
  110.   unless (fileP(Tmp)) {
  111.     printf("Missing '%s'\n", Tmp);
  112.     abort();
  113.   }
  114.  
  115.   Pal = DUNGEO01_PAL+2;
  116.  
  117.  
  118.   times (I, 256) {
  119.     S->Palette[I*4+0] = Pal[I*3+0]<<2;
  120.     S->Palette[I*4+1] = Pal[I*3+1]<<2;
  121.     S->Palette[I*4+2] = Pal[I*3+2]<<2;
  122.     S->Palette[I*4+3] = 0;
  123.   }
  124.  
  125.   loadPal(S->Palette, Tmp);
  126.  
  127.   S->NAnis = 1;
  128.   S->Anis = ns(ani, S->NAnis);
  129.   S->Anis[0].NFacs = 1;
  130.   S->Anis[0].Facs = ns(fac,S->Anis[0].NFacs);
  131.   S->Anis[0].Facs[0].NPics = H->NFrames;
  132.   S->Anis[0].Facs[0].Pics = ns(pic*, S->Anis[0].Facs[0].NPics);
  133.  
  134.   times (I, H->NFrames) {
  135.     if (!FH[I].Off) continue; // probably delay-frame
  136.     F = (frame*)(D+FH[I].Off);
  137.     //printf("%03d: Off=#%08x Len=#%04x\n", I, FH[I].Off, FH[I].Len);
  138.     //printf(" T=%d %dx%d %d,%d R=%d U=%d S=%d\n"
  139.     //      ,F->T, F->Width, F->Height, F->X, F->Y, F->R, F->U, F->Size);
  140.  
  141.     P = S->Anis[0].Facs[0].Pics[I] = picNew(F->Width, F->Height, 8);
  142.     P->SharedPalette = 1;
  143.     free(P->P);
  144.     P->P = S->Palette;
  145.  
  146.     Buf = ns(u1, 2*F->Width*F->Height);
  147.     decodeLZ77(Buf, (u1*)F+sizeof(frame), F->Size);
  148.     decodeRLE(P->D, Buf, F->Width*F->Height);
  149.     free(Buf);
  150.   }
  151.   return S;
  152. }
  153.  
  154. int monInit(format *F) {
  155.   F->Type = FMT_SPRITE;
  156.   F->Name = "mon";
  157.   F->Description = "Stonekeep sprites (MON, MSP, POJ, WPN, GXX)";
  158.   // MMP and UBG are two other formats
  159.   F->Load = monLoad;
  160.   return 1;
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement