Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Credits go to SNV
- #include "common.h"
- #include "sk_pals.h"
- typedef struct {
- u1 NFrames;
- u1 Unknown; // 0x80
- //frameHeader[NFrames];
- } __attribute__ ((packed)) header;
- typedef struct {
- u4 Off;
- u2 Len;
- } __attribute__ ((packed)) frameHeader;
- typedef struct {
- u2 T; // type or palette?
- u2 Width;
- u2 Height;
- u2 X; // X/Y is where monster's legs are located
- u2 Y;
- u2 R; // 320? related to screen dimension?
- u4 U; // zeroes
- u4 Size; // size of compressed image
- //Data[Size];
- } __attribute__ ((packed)) frame;
- // palette header
- typedef struct {
- u2 Len;
- //u1 Colors[Len*3];
- } __attribute__ ((packed)) palHeader;
- static void decodeLZ77(u1 *D, u1 *S, int L) {
- u1 *P, *E = S+L;
- int C, B, R;
- while (S < E) {
- C = *S++;
- times (B, 8) {
- if (C&(1<<B)) { // backreference: 12-bit distance and 4-bit length
- R = *(u2*)S;
- S += 2;
- P = D-(R>>4);
- R = (R&0xF)+3;
- while(R--) *D++ = *P++;
- } else {
- *D++ = *S++;
- }
- }
- }
- }
- static void decodeRLE(u1 *D, u1 *S, int L) {
- while (L > 0) {
- int C = *S++;
- if (C&0x80) {
- C&=0x7f;
- while (C-- && L--) *D++ = 0;
- } else {
- while (C-- && L--) {
- *D++ = *S++&0x7F; // no idea why, but it overflows at 0x80
- }
- }
- }
- }
- static void loadPal(u1 *Out, char *Name) {
- int I;
- palHeader *PH = readFile(0, sizeof(palHeader), Name);
- u1 *Pal = readFile(sizeof(palHeader), PH->Len*3, Name);
- times (I, PH->Len) { // as usual, VGA palette requires color-shift
- Out[I*4+0] = Pal[I*3+0]<<2;
- Out[I*4+1] = Pal[I*3+1]<<2;
- Out[I*4+2] = Pal[I*3+2]<<2;
- Out[I*4+3] = 0;
- }
- free(Pal);
- }
- spr *monLoad(char *Input) {
- char Tmp[1024], Dir[1024], Name[128], Ext[32];
- u1 *Buf;
- int I, J, X, Y, C;
- spr *S;
- pic *P;
- u1 *Pal;
- frame *F;
- int L = fileSize(Input);
- u1 *D = readFile(0, L, Input);
- header *H = (header*)D;
- frameHeader *FH = (frameHeader*)(D+sizeof(header));
- pathParts(Dir, Name, Ext, Input);
- downcase(Ext);
- S = sprNew();
- S->Palette = ns(u1, 4*256);
- sprintf(Tmp, "%s/%s.PAL", Dir, Name);
- unless (fileP(Tmp)) {
- printf("Missing '%s'\n", Tmp);
- abort();
- }
- Pal = DUNGEO01_PAL+2;
- times (I, 256) {
- S->Palette[I*4+0] = Pal[I*3+0]<<2;
- S->Palette[I*4+1] = Pal[I*3+1]<<2;
- S->Palette[I*4+2] = Pal[I*3+2]<<2;
- S->Palette[I*4+3] = 0;
- }
- loadPal(S->Palette, Tmp);
- S->NAnis = 1;
- S->Anis = ns(ani, S->NAnis);
- S->Anis[0].NFacs = 1;
- S->Anis[0].Facs = ns(fac,S->Anis[0].NFacs);
- S->Anis[0].Facs[0].NPics = H->NFrames;
- S->Anis[0].Facs[0].Pics = ns(pic*, S->Anis[0].Facs[0].NPics);
- times (I, H->NFrames) {
- if (!FH[I].Off) continue; // probably delay-frame
- F = (frame*)(D+FH[I].Off);
- //printf("%03d: Off=#%08x Len=#%04x\n", I, FH[I].Off, FH[I].Len);
- //printf(" T=%d %dx%d %d,%d R=%d U=%d S=%d\n"
- // ,F->T, F->Width, F->Height, F->X, F->Y, F->R, F->U, F->Size);
- P = S->Anis[0].Facs[0].Pics[I] = picNew(F->Width, F->Height, 8);
- P->SharedPalette = 1;
- free(P->P);
- P->P = S->Palette;
- Buf = ns(u1, 2*F->Width*F->Height);
- decodeLZ77(Buf, (u1*)F+sizeof(frame), F->Size);
- decodeRLE(P->D, Buf, F->Width*F->Height);
- free(Buf);
- }
- return S;
- }
- int monInit(format *F) {
- F->Type = FMT_SPRITE;
- F->Name = "mon";
- F->Description = "Stonekeep sprites (MON, MSP, POJ, WPN, GXX)";
- // MMP and UBG are two other formats
- F->Load = monLoad;
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement