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]
Stunts Reverse Engineering / Stunts MIDI music
« on: May 31, 2010, 12:20:21 PM »

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

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:, however these are not related.

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

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;, 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;


next_offset(&output_ofs, &output_seg, 0);

while (true) {*)&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];*)buffer, sizeof(unsigned char));*)&buffer[1], sizeof(unsigned char));

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


return true;

size_t copy_binary(const char* filename, char* exeimage) {
std::ifstream fs;, 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);, size);

return size;

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

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]