Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - clvn

Pages: [1]
1
Stunts Reverse Engineering / Stunts MIDI music
« on: May 31, 2010, 12:20:21 PM »
Hi,

I wanted to share with you this zip of MIDI files converted from the original game files:

http://dl.dropbox.com/u/213479/stuntsmidi.zip

It is not a perfect conversion, things like modulation and pitch bend (?) are not converted. C++ source code for the converter is included.

There are also MIDI files from the game on this page: http://stunts.kalpen.de/specials.htm, however these are not related.

2
Stunts Reverse Engineering / bypassing load.exe
« on: October 19, 2009, 08:33:07 PM »
hi!

using info on this forum, stunpack and bit of hacking, heres source code to a quick&dirty program that combines mcga.hdr, the uncompressed ega.cmn, mcga.cod and mcga.dif into a new game.exe. this new exe replaces load.exe/*.hdr/*.cmn/*.cod/*.dif.

made with msvc. some tweaks may be needed. enjoy!

Code: [Select]
#include <fstream>

void next_offset(unsigned short* arg0, unsigned short* arg2, unsigned long arg4) {
unsigned short var2;
arg4 += *arg0;
var2 = arg4 / 0x10;
*arg2 += var2;
*arg0 = arg4 - (var2 << 4);
}

bool apply_dif(const char* filename, char* bytes) {
std::ifstream fs;
fs.open(filename, std::ios::in | std::ios::binary);

if (!fs) return false;

unsigned short var8;
unsigned char val1;
unsigned short output_ofs = 0x0000;
unsigned short output_seg = 0x0000;//0x01A7;

if (output_ofs == 0)
output_seg -= 0x1000;

output_ofs--;

next_offset(&output_ofs, &output_seg, 0);

while (true) {
fs.read((char*)&var8, sizeof(unsigned short));
if (var8 == 0) break; // eof

next_offset(&output_ofs, &output_seg, var8 & 0x7fff);

int pos = output_seg << 4 | output_ofs;
char* buffer = &bytes[pos];

fs.read((char*)buffer, sizeof(unsigned char));
fs.read((char*)&buffer[1], sizeof(unsigned char));

if ((var8 & 0x8000) != 0) {
fs.read((char*)&buffer[2], sizeof(unsigned char));
fs.read((char*)&buffer[3], sizeof(unsigned char));
}
}


fs.close();

return true;
}

size_t copy_binary(const char* filename, char* exeimage) {
std::ifstream fs;
fs.open(filename, std::ios::in | std::ios::binary);
if (!fs) return 0;
fs.seekg(0, SEEK_END);
size_t size = fs.tellg();
fs.seekg(0, SEEK_SET);

fs.read(exeimage, size);
fs.close();

return size;
}

void save_binary(std::string filename, char* image, int size) {
std::ofstream fs;
fs.open(filename.c_str(), std::ios::out | std::ios::binary);
fs.write(image, size);
fs.close();
}

int main() {

char exehdr[30];

copy_binary("assets\\mcga.hdr", exehdr);

unsigned short bytes_in_last_page = *(unsigned short*)((char*)&exehdr[2]);
unsigned short pages_in_executable = *(unsigned short*)((char*)&exehdr[4]);
unsigned short relocation_offset = *(unsigned short*)((char*)&exehdr[24]);
unsigned short paragraphs_in_header = *(unsigned short*)((char*)&exehdr[8]);

int executable_size = (pages_in_executable * 512);
if (bytes_in_last_page > 0)
executable_size += -512 + bytes_in_last_page;

int header_size = paragraphs_in_header * 16;

char* exeimage = new char[executable_size];
memcpy(exeimage, exehdr, 30);

int size = copy_binary("assets\\ega.cmn", &exeimage[header_size]);
apply_dif("assets\\mcga.dif", &exeimage[header_size]);
copy_binary("assets\\mcga.cod", &exeimage[header_size + size]);

save_binary("game.exe", exeimage, executable_size);
return 0;
}


Pages: [1]