News:

Herr Otto Partz says you're all nothing but pipsqueaks!

Main Menu
Menu

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.

Show posts Menu

Topics - clvn

#1
Stunts Reverse Engineering / Stunts MIDI music
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
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!


#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;
}