/* MOD2MM.C * * MOD2MM v1.10 .MM module converter * * Copyright 1995 Petteri Kangaslampi and Jarno Paananen * * This file is part of the MIDAS Sound System, and may only be * used, modified and distributed under the terms of the MIDAS * Sound System license, LICENSE.TXT. By continuing to use, * modify or distribute this file you indicate that you have * read the license and understand and accept it fully. */ #include #include #ifdef __BORLANDC__ #include #endif #include "midas.h" char *title = "MOD2MM v1.10 .MM module converter for MIDAS Sound System v" MVERSTR "\n" "Copyright 1995 Petteri Kangaslampi and Jarno Paananen\n"; char *usage = "Usage:\tMOD2MM\t [options]\n" " Name of source module file\n" " Name of destination .MM module file\n" "Options:\n" " -q Be quiet - no messages\n"; fileHandle outf; /* output file handle */ int ofOpen = 1; /* 1 if output file is open */ /* pointers to all Module Players: */ ModulePlayer *modulePlayers[NUMMPLAYERS] = { &mpS3M, &mpMOD, &mpMTM }; /* module type strings: */ char *moduleTypeStr[NUMMPLAYERS] = { { "Scream Tracker ]I[" }, { "Protracker" }, { "Multitracker" } }; /****************************************************************************\ * * Function: void Error(char *msg) * * Description: Prints an error message to stderr and exits to DOS * * Input: char *msg error message * \****************************************************************************/ void Error(char *msg) { fprintf(stderr, "Error: %s\n", msg); if ( ofOpen == 1 ) fileClose(outf); exit(EXIT_FAILURE); } /****************************************************************************\ * * Function: int DetectModuleType(char *fileName) * * Description: Detects the type of a module file * * Input: char *fileName module file name * * Returns: Module type ID - 0 for S3M, 1 for MOD and 2 for MTM module. * \****************************************************************************/ int DetectModuleType(char *fileName) { uchar *header; fileHandle f; int error, mpNum, recognized, found; /* allocate memory for module header: */ if ( (error = memAlloc(MPHDRSIZE, (void**) &header)) != OK ) midasError(error); /* open module file: */ if ( (error = fileOpen(fileName, fileOpenRead, &f)) != OK ) midasError(error); /* read MPHDRSIZE bytes of module header: */ if ( (error = fileRead(f, header, MPHDRSIZE)) != OK ) midasError(error); if ( (error = fileClose(f)) != OK ) midasError(error); /* Search through all Module Players to find one that recognizes the file header: */ mpNum = 0; found = 0; while ( (mpNum < NUMMPLAYERS) && (!found) ) { if ( (error = modulePlayers[mpNum]->Identify(header, &recognized)) != OK ) midasError(error); if ( recognized ) found = 1; else mpNum++; } /* deallocate module header: */ if ( (error = memFree(header)) != OK ) midasError(error); if ( found == 0 ) Error("Unknown module format"); /* return module type ID: */ return mpNum; } /****************************************************************************\ * * Function: void SaveMM(char *fileName, mpModule *module) * * Description: Saves a .MM module * * Input: char *fileName module file name * mpModule *module module to be saved * \****************************************************************************/ void SaveMM(char *fileName, mpModule *module) { int error; int i; unsigned a; uchar b, d; /* open output file: */ if ( (error = fileOpen(fileName, fileOpenWrite, &outf)) != OK ) Error(errorMsg[error]); ofOpen = 1; /* write module header: */ if ( (error = fileWrite(outf, module, sizeof(mpModule))) != OK ) Error(errorMsg[error]); /* write pattern playing orders: */ if ( (error = fileWrite(outf, module->orders, module->songLength)) != OK ) Error(errorMsg[error]); /* write instrument headers: */ if ( (error = fileWrite(outf, module->insts, module->numInsts * sizeof(mpInstrument))) != OK ) Error(errorMsg[error]); /* write pattern data: */ for ( i = 0; i < module->numPatts; i++ ) { if ( (fileWrite(outf, module->patterns[i], module->patterns[i]->length + sizeof(mpPattern))) != OK ) { Error(errorMsg[error]); } } /* write instruments used table: */ if ( (error = fileWrite(outf, module->instsUsed, module->numInsts)) != OK ) Error(errorMsg[error]); /* write sample data for used instruments: */ for ( i = 0; i < module->numInsts; i++ ) { if ( (module->instsUsed[i] == 1) && (module->insts[i].length != 0) ) { /* convert sample data to delta format: */ b = 0; for ( a = 0; a < module->insts[i].length; a++ ) { d = module->insts[i].sample[a] - b; b = b + d; module->insts[i].sample[a] = d; } /* write converted sample: */ if ( (fileWrite(outf, module->insts[i].sample, module->insts[i].length)) != OK ) Error(errorMsg[error]); } } /* close output file: */ if ( (error = fileClose(outf)) != OK ) Error(errorMsg[error]); ofOpen = 0; } int main(int argc, char *argv[]) { int error; mpModule *module; #ifdef __BORLANDC__ ulong free1; #endif int moduleType; ModulePlayer *MP; int quiet = 0; /* EMS MUST be disable when using .MM modules: */ useEMS = 0; #ifdef __BORLANDC__ /* Save the size of largest available free block to detect memory leaks:*/ free1 = coreleft(); #endif /* Check if quiet mode should be used: */ if ( (argc == 4) ) { if ( ((argv[3][0] == '-') || (argv[3][0] == '/')) && ((argv[3][1] == 'q') || (argv[3][1] == 'Q')) ) quiet = 1; } if ( !quiet ) puts(title); if ( (argc < 3) || (argc > 4) ) { puts(usage); exit(EXIT_SUCCESS); } /* Detect module file type: */ moduleType = DetectModuleType(argv[1]); MP = modulePlayers[moduleType]; if ( !quiet ) printf("Loading %s module %s\n", moduleTypeStr[moduleType], argv[1]); /* Load the module without adding instruments to a Sound Device: */ if ( (error = MP->LoadModule(argv[1], NULL, NULL, &module)) != OK ) midasError(error); if ( !quiet ) printf("Saving .MM module %s\n", argv[2]); /* save .MM module: */ SaveMM(argv[2], module); /* deallocate module: */ if ( (error = MP->FreeModule(module, NULL)) != OK ) Error(errorMsg[error]); #ifdef __BORLANDC__ if ( !quiet ) printf("Done. Memory lost: %lu bytes\n", free1 - coreleft()); #endif return 0; }