/*#### READ THIS FIRST ##### GIVE CREDIT IF YOU USE THIS CODE. The ASM was a total pain in the *** to reverse-engineer!! This is DKCRE v0050's Original DKC2 decompression routine. Coded by Simion32. Please note that the code is very, very messy (and old too). I can't be bothered to clean it up. Provided you credit me for this code, do whatever with it. You use it at your own risk. */ #include "include.h" #include "RE_Trilogy_Data.h" int c = 0x00; //Control byte int f = 0x00; //Function byte int d = 0x00000000; //Data offset int w = 0; //Write offset int r = 1; //Read Offset int m[2] = {0}; //Used for file I/O vector::iterator it; //Used when writing to vector short int RdData(bool n) { if(!n) {m[0] = (DKC2[(d + r)] & 0xFF); r++; return m[0];} else {m[0] = (DKC2[(d + r)] & 0xFF); m[1] = (DKC2[((d + r) + 1)] & 0xFF); r+=2; return (m[0] + (m[1] << 8));} } void WrData(int d,vector& g) { g.insert(it,d); it = g.end(); w++; } void Function_8E02_ASM(void) {c = RdData(0); f = ((c & 0xF0) >> 2);} void Function_8E10_ASM(void) {f = (((c & 0x0F) << 2) + 0x3F);} void Function_8E1D_ASM(int b) {f = (((b & 0x0F) << 2) + 0x3F);} void RE_DKC2_CopyCastleData(vector& out, int dof, int size) { vector::iterator t; t = out.end(); for(int c = dof;c != (dof+size);c++) {out.insert(t,DKC2[c]); t = out.end();} t = out.begin(); t+=0x2580; out.insert(t,0x22C0,0x00); } void DKC2_Extraction_Routine(vector& out, int dof) { c = 0x00; f = 0x00; w = 0x00; r = 0x01; int HTable[0x100] = {0}; int LTable[0x100] = {0}; for(int i = 0x0000, j = 0x0000;i != 0x0100;i++) {LTable[i] = j; j = ((j + 0x10) & 0xF0);} for(int i = 0x0000;i != 0x0100;i++) {HTable[i] = (i >> 4);} bool DONE = false; it = out.end(); d = dof; short int p[5] = {0}; p[0] = RdData(0); p[1] = RdData(0); p[2] = RdData(0); p[3] = RdData(0); p[4] = RdData(1); r = 0x0027; Function_8E02_ASM(); while(!DONE) { switch(f) { case 0x00:{ int variable = (c & 0x0F); if(variable == 0x00) {DONE = true; break;/* QUIT DECOMPRESSION LOOP */} for(int i = 0;i != variable;i++) {WrData(RdData(0),out);} Function_8E02_ASM(); } break; case 0x04:{ int bytetwo = RdData(0); WrData((LTable[c] | HTable[bytetwo]),out); Function_8E1D_ASM(bytetwo); } break; case 0x08:{ int byteone = RdData(0); WrData((HTable[byteone] | LTable[c]),out); c = byteone; int bytetwo = RdData(0); WrData((HTable[bytetwo] | LTable[c]),out); Function_8E1D_ASM(bytetwo); } break; case 0x0C:{ RdData(0); for(int i = 0;i != ((c & 0x0F) + 3);i++) {WrData(m[0],out);} Function_8E02_ASM(); } break; case 0x10:{ for(int i = 0;i != ((c & 0x0F) + 3);i++) {WrData(p[0],out);} Function_8E02_ASM(); } break; case 0x14:{ for(int i = 0;i != ((c & 0x0F) + 3);i++) {WrData(p[1],out);} Function_8E02_ASM(); } break; case 0x18:{ WrData((p[4] & 0x00FF),out); WrData(((p[4] & 0xFF00) >> 8),out); Function_8E10_ASM(); } break; case 0x1C:{ WrData(p[2],out); Function_8E10_ASM(); } break; case 0x20:{ WrData(p[3],out); Function_8E10_ASM(); } break; case 0x24:{ WrData(out[(w - ((c & 0x0F) + 2))],out); WrData(out[(w - ((c & 0x0F) + 2))],out); Function_8E02_ASM(); } break; case 0x28:{ int byteone = RdData(0); int variable = (w - byteone - ((c & 0x0F) + 3)); for(int i = 0;i != ((c & 0x0F) + 3);i++) {WrData(out[(variable + i)],out);} Function_8E02_ASM(); } break; case 0x2C:{ int loopnumber = ((c & 0x0F) + 3); int byteone = RdData(0); int bytetwo = RdData(0); c = (((byteone & 0xFF) << 8) + (bytetwo & 0xFF)); int variable = (w - ((c >> 4) + 0x0103)); for(int i = 0;i != loopnumber;i++) {WrData(out[(variable + i)],out);} Function_8E10_ASM(); } break; case 0x30:{ RdData(1); int variable = (w - ((m[0] << 8) + m[1])); for(int i = 0;i != ((c & 0x0F) + 3);i++) {WrData(out[(variable + i)],out);} Function_8E02_ASM(); } break; case 0x34:{ WrData(out[(w - 1)],out); Function_8E10_ASM(); } break; case 0x38:{ WrData(out[(w - 2)],out); WrData(out[(w - 2)],out); Function_8E10_ASM(); } break; case 0x3C:{ WrData(DKC2[(d + (((c & 0x000F) << 1) + 7))],out); WrData(DKC2[(d + (((c & 0x000F) << 1) + 8))],out); Function_8E02_ASM(); } break; case 0x3F:{ int byteone = RdData(0); c = byteone; if(HTable[byteone] == 0) {DONE = true; break;/* QUIT DECOMPRESSION LOOP */} for(int i = 0;i != HTable[byteone];i++) { int variable = LTable[c]; c = RdData(0); WrData((HTable[c] | variable),out); } Function_8E10_ASM(); } break; case 0x43:{ WrData(RdData(0),out); Function_8E02_ASM(); } break; case 0x47:{ RdData(1); WrData(m[0],out); WrData(m[1],out); Function_8E02_ASM(); } break; case 0x4B:{ int byteone = RdData(0); int bytetwo = RdData(0); int variable = (HTable[bytetwo] | LTable[byteone]); for(int i = 0;i != (HTable[byteone] + 3);i++) {WrData(variable,out);} Function_8E1D_ASM(bytetwo); } break; case 0x4F:{ RdData(0); for(int i = 0;i != (HTable[m[0]] + 3);i++) {WrData(p[0],out);} Function_8E1D_ASM(m[0]); } break; case 0x53:{ int byteone = RdData(0); for(int i = 0;i != (HTable[byteone] + 3);i++) {WrData(p[1],out);} Function_8E1D_ASM(byteone); } break; case 0x57:{ WrData((p[4] & 0x00FF),out); WrData(((p[4] & 0xFF00) >> 8),out); Function_8E02_ASM(); } break; case 0x5B:{ WrData(p[2],out); Function_8E02_ASM(); } break; case 0x5F:{ WrData(p[3],out); Function_8E02_ASM(); } break; case 0x63:{ int byteone = RdData(0); WrData(out[(w - (HTable[byteone] + 2))],out); WrData(out[(w - (HTable[byteone] + 2))],out); Function_8E1D_ASM(byteone); } break; case 0x67:{ int byteone = RdData(0); c = byteone; int bytetwo = RdData(0); int variable = ((w - (LTable[byteone] | HTable[bytetwo])) - (HTable[byteone] + 3)); for(int i = 0;i != (HTable[byteone] + 3);i++) {WrData(out[(variable + i)],out);} Function_8E1D_ASM(bytetwo); } break; case 0x6B:{ int byteone = RdData(0); int bytetwo = RdData(0); int variable = (w - ((bytetwo + ((byteone & 0x0F) << 8)) + 0x0103)); for(int i = 0;i != (HTable[byteone] + 3);i++) {WrData(out[(variable + i)],out);} Function_8E02_ASM(); } break; case 0x6F:{ int byteone = RdData(0); int bytetwo = RdData(0); int bytethree = RdData(0); int variable = (w - (((((byteone << 8) + bytetwo) << 4) & 0xFFFF) | (HTable[bytethree] & 0x000F))); for(int i = 0;i != (HTable[byteone] + 3);i++) {WrData(out[(variable + i)],out);} Function_8E1D_ASM(bytethree); } break; case 0x73:{ WrData(out[(w - 1)],out); Function_8E02_ASM(); } break; case 0x77:{ WrData(out[(w - 2)],out); WrData(out[(w - 2)],out); Function_8E02_ASM(); } break; case 0x7B:{ c = RdData(0); WrData((DKC2[(d + (((c & 0x00F0) >> 3) + 7) )] & 0xFF),out); WrData((DKC2[((d + (((c & 0x00F0) >> 3) + 7) ) + 1)] & 0xFF),out); Function_8E10_ASM(); } break; default:{ string error = "Found unemulated function $"; error += int2hexstr(f,2); error += " with control byte $"; error += int2hexstr(c,2); error += "\n\nThis most likely means that something went wrong\nwhen trying to decompress the given data."; MessageBox(MAIN_WINDOW_HANDLE, error.c_str(), "DKC2 Decompression Error",MB_OK | MB_ICONERROR); return; } } } }