HarmonyPatcher

Made by Bananen-Joe, written in C/C++.

Sourcecode

Originally published as part of the RM Interna CUECards-database.

/*
 Name:         HarmonyPatcher
 Version:      1.0
 Autor:        David Gausmann (alias Bananen-Joe)
 Anmerkungen:  Funktioniert mit 1.08 und 1.09
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

bool CheckFile_1_08(const char szDateiname[]);
void PatchFile_1_08(const char szDateiname[], long lSprache);

typedef FILE* LPFILE;

bool CheckStream(LPFILE hDatei, const char cCheck[], long lSize, long lAddress);

#define INITCODESIZE 740

char cInitCode[INITCODESIZE] =
 {
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HARMONY.DLL" */
  0xE8, 0, 0, 0, 0,                       /* CALL LoadLibraryA */
  0x85, 0xC0,                             /* TEST EAX, EAX */
  0x0F, 0x84, 0x4A, 0x01, 0x00, 0x00,     /* JZ NEAR Fehlermeldung */
  0xA3, 0, 0, 0, 0,                       /* MOV hHarmony, EAX */
  0x8B, 0xD8,                             /* MOV EBX, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyCreate" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyCreate, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyRelease" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyRelease, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyInitMidi" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyInitMidi, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyInitWave" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyInitWave, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyTermWave" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyTermWave, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyFadeInMusic" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyFadeInMusic, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyFadeOutMusic" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyFadeOutMusic, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonySetMusicVolume" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonySetMusicVolume, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonySetMusicSpeed" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonySetMusicSpeed, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonySetMusicPanpot" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonySetMusicPanpot, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyPlayMusic" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyPlayMusic, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyStopMusic" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyStopMusic, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyGetMusicPlaying" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyGetMusicPlaying, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyGetMusicLooping" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyGetMusicLooping, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyPlaySoundEx" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyPlaySoundEx, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyStopSound" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyStopSound, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyReserveSound" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyReserveSound, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyCancelSound" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyCancelSound, EAX */
  
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET "HarmonyGetMidiTick" */
  0x53,                                   /* PUSH EBX */
  0xE8, 0, 0, 0, 0,                       /* CALL GetProcAddress */
  0xA3, 0, 0, 0, 0,                       /* MOV lpHarmonyGetMidiTick, EAX */
  
  0xE8, 0, 0, 0, 0,                       /* CALL RPG_RT */
  0x50,                                   /* PUSH EAX */
  0xFF, 0x35, 0, 0, 0, 0,                 /* PUSH hHarmony */
  0xE8, 0, 0, 0, 0,                       /* CALL FreeLibrary */
  0x58,                                   /* POP EAX */
  0xC3,                                   /* RET */
  
  0x68, 0x30, 0, 0, 0,                    /* PUSH MB_ICONEXCLAMATION or MB_OK */
  0x6A, 0x00,                             /* PUSH 0 */
  0x68, 0, 0, 0, 0,                       /* PUSH OFFSET szFehlermeldung */
  0x6A, 0x00,                             /* PUSH 0 */
  0xE8, 0, 0, 0, 0,                       /* CALL MessageBoxA */
  0xB8, 0x01, 0x00, 0x00, 0x00,           /* MOV EAX, 1 */
  0xC3,                                   /* RET */
  'H', 'A', 'R', 'M', 'O', 'N', 'Y', '.', 'D', 'L', 'L', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'C', 'r', 'e', 'a', 't', 'e', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'R', 'e', 'l', 'e', 'a', 's', 'e', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'I', 'n', 'i', 't', 'M', 'i', 'd', 'i', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'I', 'n', 'i', 't', 'W', 'a', 'v', 'e', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'T', 'e', 'r', 'm', 'W', 'a', 'v', 'e', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'F', 'a', 'd', 'e', 'I', 'n', 'M', 'u', 's', 'i', 'c', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'F', 'a', 'd', 'e', 'O', 'u', 't', 'M', 'u', 's', 'i', 'c', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'S', 'e', 't', 'M', 'u', 's', 'i', 'c', 'V', 'o', 'l', 'u', 'm', 'e', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'S', 'e', 't', 'M', 'u', 's', 'i', 'c', 'S', 'p', 'e', 'e', 'd', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'S', 'e', 't', 'M', 'u', 's', 'i', 'c', 'P', 'a', 'n', 'p', 'o', 't', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'P', 'l', 'a', 'y', 'M', 'u', 's', 'i', 'c', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'S', 't', 'o', 'p', 'M', 'u', 's', 'i', 'c', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'G', 'e', 't', 'M', 'u', 's', 'i', 'c', 'P', 'l', 'a', 'y', 'i', 'n', 'g', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'G', 'e', 't', 'M', 'u', 's', 'i', 'c', 'L', 'o', 'o', 'p', 'i', 'n', 'g', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'P', 'l', 'a', 'y', 'S', 'o', 'u', 'n', 'd', 'E', 'x', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'S', 't', 'o', 'p', 'S', 'o', 'u', 'n', 'd', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'S', 'o', 'u', 'n', 'd', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'C', 'a', 'n', 'c', 'e', 'l', 'S', 'o', 'u', 'n', 'd', 0x00,
  'H', 'a', 'r', 'm', 'o', 'n', 'y', 'G', 'e', 't', 'M', 'i', 'd', 'i', 'T', 'i', 'c', 'k', 0x00
 };
 
#define JUMPCODESIZE 6
char cJumpCode[JUMPCODESIZE] = 
{
 0xFF, 0x25, 0, 0, 0, 0     /* JUMP NEAR XXXXXXXX */
};

#define FMD_LAENGE 41
const char szFehlermeldungDeutsch[FMD_LAENGE] = "Harmony.dll konnte nicht geladen werden!";
#define FME_LAENGE 27
const char szFehlermeldungEnglisch[FME_LAENGE] = "Couldn't load Harmony.dll!";

int main(int argc, char *argv[])
{
 long lSprache;
 
 if(argc != 3)
 {
  printf("Fehler: Keine Eingabe!\\r\\n");
  return -1;
 }
 else
 {
  if(argv[2][0] == '0' && argv[2][1] == 0)
   lSprache = 0;
  else if(argv[2][0] == '1' && argv[2][1] == 0)
   lSprache = 1;
  else
  {
   printf("Fehler: Ungültige Eingabe!\\r\\n");
   return -1;
  }
  if(CheckFile_1_08(argv[1]))
   PatchFile_1_08(argv[1], lSprache);
  else
  {
   printf("Unbekannte Datei!\\r\\n");
   return 1;
  }
 }
 printf("Patchen erfolgreich!\\r\\n");
 system("pause");
 return 0;
}

bool CheckStream(LPFILE hDatei, const char cCheck[], long lSize, long lAddress)
{
 char cStream[8];
 long I;
 
 //Überflüssige Sicherheitsabfrage
 if(lSize <= 0 || lSize > 8)
  return false;
 
 if(fseek(hDatei, lAddress, SEEK_SET))
  return false;
 if(fread(cStream, lSize, 1, hDatei) != 1)
  return false;
 for(I = 0; I < lSize; I++)
 {
  if(cStream[I] != cCheck[I])
   return false;
 }
 
 //Eingelesene Daten sind ok
 return true;
}

bool CheckFile_1_08(const char szDateiname[])
{
 LPFILE hDatei;
 char cStream[8];
 
 if((hDatei = fopen(szDateiname, "r")) != NULL)
 {
  //Die MagicNumber überprüfen
  if(!CheckStream(hDatei, "MZ", 2, 0))
   goto Fehler_Close;
  
  //Die Basis der Daten überprüfen
  cStream[0] = 0x00; cStream[1] = 0xA0; cStream[2] = 0x0C; cStream[3] = 0x00;
  if(!CheckStream(hDatei, cStream, sizeof(long), 0x130))
   goto Fehler_Close;
  
  //Entspricht: CMP DWORD PTR [004D1E08], 0
  cStream[0] = 0x83; cStream[1] = 0x3D; cStream[2] = 0x08; cStream[3] = 0x1E;
  cStream[4] = 0x4D; cStream[5] = 0x00; cStream[6] = 0x00;
  
  //Die neue HarmonyCreate überprüfen
  if(!CheckStream(hDatei, cStream, 7, 0x710E4))
   goto Fehler_Close;
  
  //Die neue HarmonyRelease überprüfen
  if(!CheckStream(hDatei, cStream, 7, 0x71108))
   goto Fehler_Close;
   
  //Die neue HarmonyInitMidi überprüfen
  if(!CheckStream(hDatei, cStream, 7, 0x7112C))
   goto Fehler_Close;
   
  //Die neue HarmonyInitWave überprüfen
  if(!CheckStream(hDatei, cStream, 7, 0x71150))
   goto Fehler_Close;
   
  //Die neue HarmonyTermWave überprüfen
  if(!CheckStream(hDatei, cStream, 7, 0x71174))
   goto Fehler_Close;
   
  //Die neue HarmonyStopMusic überprüfen
  if(!CheckStream(hDatei, cStream, 7, 0x712DC))
   goto Fehler_Close;
   
  //Die neue HarmonyGetMusicPlaying überprüfen
  if(!CheckStream(hDatei, cStream, 7, 0x71300))
   goto Fehler_Close;
   
  //Die neue HarmonyGetMusicLooping überprüfen
  if(!CheckStream(hDatei, cStream, 7, 0x71324))
   goto Fehler_Close;
   
  //Die neue HarmonyStopSound überprüfen
  if(!CheckStream(hDatei, cStream, 7, 0x713BC))
   goto Fehler_Close;
   
  //Die neue HarmonyGetMidiTick überprüfen
  if(!CheckStream(hDatei, cStream, 7, 0x714B0))
   goto Fehler_Close;
  
  //Entspricht: PUSH EBP / MOV EBP, ESP
  cStream[0] = 0x55; cStream[1] = 0x8B; cStream[2] = 0xEC;
  
  //Die neue HarmonyPlayMusic überprüfen
  if(!CheckStream(hDatei, cStream, 3, 0x71198))
   goto Fehler_Close;
   
  //Die neue HarmonyFadeInMusic überprüfen
  if(!CheckStream(hDatei, cStream, 3, 0x71200))
   goto Fehler_Close;
   
  //Die neue HarmonyFadeOutMusic überprüfen
  if(!CheckStream(hDatei, cStream, 3, 0x7122C))
   goto Fehler_Close;
   
  //Die neue HarmonySetMusicVolume überprüfen
  if(!CheckStream(hDatei, cStream, 3, 0x71258))
   goto Fehler_Close;
   
  //Die neue HarmonySetMusicSpeed überprüfen
  if(!CheckStream(hDatei, cStream, 3, 0x71284))
   goto Fehler_Close;
   
  //Die neue HarmonySetMusicPanpot überprüfen
  if(!CheckStream(hDatei, cStream, 3, 0x712B0))
   goto Fehler_Close;
   
  //Die neue HarmonyPlaySoundEx überprüfen
  if(!CheckStream(hDatei, cStream, 3, 0x71348))
   goto Fehler_Close;
   
  //Die neue HarmonyReserveSound überprüfen
  if(!CheckStream(hDatei, cStream, 3, 0x713E0))
   goto Fehler_Close;
   
  //Die neue HarmonyCancelSound überprüfen
  if(!CheckStream(hDatei, cStream, 3, 0x71448))
   goto Fehler_Close;
  
  //Die Klassendefinition überprüfen
  cStream[0] = 0x68; cStream[1] = 0xD2; cStream[2] = 0x46; cStream[3] = 0x00;
  if(!CheckStream(hDatei, cStream, 4, 0x6C61C))
   goto Fehler_Close;
  
  //Entspricht: JMP DWORD[004DXXXX]
  cStream[0] = 0xFF; cStream[1] = 0x25; cStream[4] = 0x4D; cStream[5] = 0x00;

  //LoadLibraryA überprüfen
  cStream[2] = 0xDC; cStream[3] = 0x32;
  if(!CheckStream(hDatei, cStream, 6, 0x6014))
   goto Fehler_Close;
   
  //GetProcAddress überprüfen
  cStream[2] = 0x38; cStream[3] = 0x33;
  if(!CheckStream(hDatei, cStream, 6, 0x5F5C))
   goto Fehler_Close;
   
  //FreeLibrary überprüfen
  cStream[2] = 0x78; cStream[3] = 0x33;
  if(!CheckStream(hDatei, cStream, 6, 0x5EDC))
   goto Fehler_Close;
   
  //MessageBoxA überprüfen
  cStream[2] = 0x1C; cStream[3] = 0x32;
  if(!CheckStream(hDatei, cStream, 6, 0x6DC))
   goto Fehler_Close;
   
  //BSS-Segment überprüfen
  if(!CheckStream(hDatei, "BSS", 4, 0x248))
   goto Fehler_Close;
   
  /*
   Die Datei scheint eine bisher ungepatchte
   RPG_RT.exe (2003) Version 1.08 zu sein!
  */
  
  fclose(hDatei);
  return true;
  
Fehler_Close:
  fclose(hDatei);
 }
 return false;
}

void PatchFile_1_08(const char szDateiname[], long lSprache)
{
 LPFILE hDatei;
 long lEntryPoint;
 long lBSS;
 long lTemp;
 
 if((hDatei = fopen(szDateiname, "r+")) != NULL)
 {
  //Den bisherigen Programmstartpunkt einlesen
  fseek(hDatei, 0x128, SEEK_SET);
  fread(&lEntryPoint, sizeof(long), 1, hDatei);
  
  //Die Größfe des BSS-Segments einlesen
  fseek(hDatei, 0x250, SEEK_SET);
  fread(&lBSS, sizeof(long), 1, hDatei);
  //Die Größe des BSS-Segments anpassen
  lTemp = lBSS + 80;
  fseek(hDatei, 0x250, SEEK_SET);
  fwrite(&lTemp, sizeof(long), 1, hDatei);
  
  //Die Adresse des BSS-Segments einlesen
  fread(&lTemp, sizeof(long), 1, hDatei);
  lBSS += lTemp;
  
  //Den neuen Programmstartpunkt schreiben
  fseek(hDatei, 0x128, SEEK_SET);
  lTemp = 0x6C61C + 0xC00;
  fwrite(&lTemp, sizeof(long), 1, hDatei);
  
  //Strings
  *((long*) &cInitCode[1]) = (0x6C61C - 0x400 + 0x401000) + 373;   //"HARMONY.DLL"
  *((long*) &cInitCode[26]) = (0x6C61C - 0x400 + 0x401000) + 385;  //"HarmonyCreate"
  *((long*) &cInitCode[42]) = (0x6C61C - 0x400 + 0x401000) + 399;  //"HarmonyRelease"
  *((long*) &cInitCode[58]) = (0x6C61C - 0x400 + 0x401000) + 414;  //"HarmonyInitMidi"
  *((long*) &cInitCode[74]) = (0x6C61C - 0x400 + 0x401000) + 430;  //"HarmonyInitWave"
  *((long*) &cInitCode[90]) = (0x6C61C - 0x400 + 0x401000) + 446;  //"HarmonyTermWave"
  *((long*) &cInitCode[106]) = (0x6C61C - 0x400 + 0x401000) + 462; //"HarmonyFadeInMusic"
  *((long*) &cInitCode[122]) = (0x6C61C - 0x400 + 0x401000) + 481; //"HarmonyFadeOutMusic"
  *((long*) &cInitCode[138]) = (0x6C61C - 0x400 + 0x401000) + 501; //"HarmonySetMusicVolume"
  *((long*) &cInitCode[154]) = (0x6C61C - 0x400 + 0x401000) + 523; //"HarmonySetMusicSpeed"
  *((long*) &cInitCode[170]) = (0x6C61C - 0x400 + 0x401000) + 544; //"HarmonySetMusicPanpot"
  *((long*) &cInitCode[186]) = (0x6C61C - 0x400 + 0x401000) + 566; //"HarmonyPlayMusic"
  *((long*) &cInitCode[202]) = (0x6C61C - 0x400 + 0x401000) + 583; //"HarmonyStopMusic"
  *((long*) &cInitCode[218]) = (0x6C61C - 0x400 + 0x401000) + 600; //"HarmonyGetMusicPlaying"
  *((long*) &cInitCode[234]) = (0x6C61C - 0x400 + 0x401000) + 623; //"HarmonyGetMusicLooping"
  *((long*) &cInitCode[250]) = (0x6C61C - 0x400 + 0x401000) + 646; //"HarmonyPlaySoundEx"
  *((long*) &cInitCode[266]) = (0x6C61C - 0x400 + 0x401000) + 665; //"HarmonyStopSound"
  *((long*) &cInitCode[282]) = (0x6C61C - 0x400 + 0x401000) + 682; //"HarmonyReserveSound"
  *((long*) &cInitCode[298]) = (0x6C61C - 0x400 + 0x401000) + 702; //"HarmonyCancelSound"
  *((long*) &cInitCode[314]) = (0x6C61C - 0x400 + 0x401000) + 721; //"HarmonyGetMidiTick"
  *((long*) &cInitCode[356]) = (0x6C61C - 0x400 + 0x401000) + 740; //Fehler-String
  
  //Funktionsaufrufe
  *((long*) &cInitCode[6]) = 0x6014 - (0x6C61C + 10); //LoadLibraryA
  for(lTemp = 0; lTemp < 19; lTemp++)
   *((long*) &cInitCode[25+lTemp*16+7]) = 0x5F5C - (0x6C61C + 25+lTemp*16+11); //GetProcAddress
  *((long*) &cInitCode[342]) = 0x5EDC - (0x6C61C + 346); //FreeLibrary
  *((long*) &cInitCode[363]) = 0x6DC - (0x6C61C + 367); //MessageBoxA
  *((long*) &cInitCode[330]) = (lEntryPoint - 0xC00) - (0x6C61C + 334); //RPG_RT
  
  //Variablen
  *((long*) &cInitCode[19]) = lBSS + 0x400000; //hHarmony
  for(lTemp = 0; lTemp < 19; lTemp++)
   *((long*) &cInitCode[25+lTemp*16+12]) = lBSS+lTemp*4+4 + 0x400000; //lpHarmony...
  *((long*) &cInitCode[337]) = lBSS + 0x400000; //hHarmony
  
  //Den Initialisierungscode schreiben
  fseek(hDatei, 0x6C61C, SEEK_SET);
  fwrite(cInitCode, INITCODESIZE, 1, hDatei);
  if(lSprache == 0)
   fwrite(szFehlermeldungDeutsch, FMD_LAENGE, 1, hDatei);
  else
   fwrite(szFehlermeldungEnglisch, FME_LAENGE, 1, hDatei);
  
  //HarmonyCreate patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 4;
  fseek(hDatei, 0x710E4, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyRelease patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 8;
  fseek(hDatei, 0x71108, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyInitMidi patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 12;
  fseek(hDatei, 0x7112C, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyInitWave patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 16;
  fseek(hDatei, 0x71150, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyTermWave patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 20;
  fseek(hDatei, 0x71174, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyFadeInMusic patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 24;
  fseek(hDatei, 0x71200, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyFadeOutMusic patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 28;
  fseek(hDatei, 0x7122C, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonySetMusicVolume patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 32;
  fseek(hDatei, 0x71258, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonySetMusicSpeed patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 36;
  fseek(hDatei, 0x71284, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonySetMusicPanpot patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 40;
  fseek(hDatei, 0x712B0, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyPlayMusic patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 44;
  fseek(hDatei, 0x71198, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyStopMusic patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 48;
  fseek(hDatei, 0x712DC, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyGetMusicPlaying patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 52;
  fseek(hDatei, 0x71300, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyGetMusicLooping patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 56;
  fseek(hDatei, 0x71324, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyPlaySoundEx patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 60;
  fseek(hDatei, 0x71348, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyStopSound patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 64;
  fseek(hDatei, 0x713BC, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyReserveSound patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 68;
  fseek(hDatei, 0x713E0, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyCancelSound patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 72;
  fseek(hDatei, 0x71448, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  //HarmonyGetMidiTick patchen
  *((long*) &cJumpCode[2]) = lBSS + 0x400000 + 76;
  fseek(hDatei, 0x714B0, SEEK_SET);
  fwrite(cJumpCode, JUMPCODESIZE, 1, hDatei);
  
  fclose(hDatei);
 }
}