/// Music.zh /// A series of FFCs, and utility functions for playing MIDIs, Enhanced Music, and Sound Effects /// v1.0 import "std.zh" import "string.zh" const int MIDI_DEFEATBOSS = 0; //Set to default midi to play for Victory Music. //ZC will use this if enhanced Victory music is not available. const int DEFAULT_BOSS_MUSIC = 0; //Sets a default boss music file to play. /////////////// /// SCRIPTS /// /////////////// ///////////////////// /// Sound Effects /// ///////////////////// // Ties SFX to an item, that is otherwise normally hardcoded. used for the Sonic Wand in LoE. item script playSound{ void run(int sfx){ Game->PlaySound(sfx); } } ///////////////// /// MIDI Only /// ///////////////// //Plays MIDI specified at D0. Place on a screen, to change the MIDI for that screen, only. //Plays at all times on that screen, and uses no conditions. ffc script playMIDI{ void run(int midiNumber){ Game->PlayMIDI(midiNumber); } } ///////////////////////// /// Conditional MIDIs /// ///////////////////////// // These scripts will play MIDI files based on conditions set in the script args. // D0: MIDI file to play while boss is on the screen. // D1: The Screen Register (Screen->D[reg]) to use. // D2: Victory MIDI to play when boss is defeated. If set to 0, the MIDI set by constant MIDI_DEFEATBOSS plays. // D3: The duration of the victory music. // // If set to 0, the track will not play. // If set to greater than 0, the track will play for a specific duration, as follows: // To set using minutes, and seconds, set up minutes as the integer portion of the arg, and seconds as the decimal portion: // e.g. 00005.0260 is 5 mins, 26 seconds. // This works to a fineness of 1/10 second, so 00010.0136 is 10 minutes, 13.6 seconds. // If you wish to specify the duration in frames, set the ten-thousands place to '1', and the rest of the value to the number of frames. // e.g. 10526.1023 = 5,261,023 frames. // e.g. 10001.3591 = 13,591 frames. // // D4: The enemy ID of the 'boss': // // A value of zero here, instructs the FFC not to change the Screen->D[reg] value. Leave this at zero, if the enemy does this. // Otherwise, set this to -1 (negative one) if you want the Victory music to play when all screen NPCs are dead...or... // a positive value matching an enemy ID that is on the screen, if you want to play the Victory music when all enemies with that ID are dead. ffc script BossMusic{ void run(int bossMIDI, int reg, int victoryMIDI, int vict_dur, int enem){ Waitframes(6); int curScreen = Game->GetCurScreen(); int dat = Game->GetScreenD(curScreen,reg); if ( dat == 0 ) { if ( bossMIDI > 0 ) { Game->PlayMIDI(bossMIDI); } else { Game->PlayMIDI(DEFAULT_BOSS_MUSIC); } } int curDMap = Game->GetCurDMap(); int stdMIDI = Game->DMapMIDI[curDMap]; int VictoryClockMethod = _GetDigit(vict_dur, 4); int dur; if ( VictoryClockMethod == 0 ) { dur = MusicFrames(vict_dur); //Convert victory music into frames. } if ( VictoryClockMethod > 0 ) { dur = _GetPartialArg(vict_dur,3,8); //Use the full value of loopBossMusic as frame in int. } while(true){ dat = Game->GetScreenD(curScreen,reg); if ( enem == -1 && !Screen->NumNPCs() ) { Game->SetScreenD(curScreen,reg,1); } if ( enem == 0 ) { //Should we do anything special? //A zero value is intended to be used if we don;t want the FFC to set Screen->D to 1. //-1 if we do it based on all enemies being dead. //A positive value trips it if there are no enemies of that ID on the screen. } if ( enem > 0 && !NumNPCsOf(enem) ){ Game->SetScreenD(curScreen,reg,1); } dat = Game->GetScreenD(curScreen,reg); if ( dat > 0 ) { if ( dur > 0 ) { if ( victoryMIDI > 0 ) { Game->PlayMIDI(MIDI_DEFEATBOSS); } else { Game->PlayMIDI(MIDI_DEFEATBOSS); } for ( int q = 0; q <= dur; q++ ) { Waitframe(); } } Game->PlayMIDI(stdMIDI); } Waitframe(); } } } ////////////////////// /// Enhanced Music /// ////////////////////// /// These scripts will play 'enhanced music', using values set in script args. /// If an enhanced music file is not available (e.g. the player does not have it, or elects /// not to use it, then they will play a back-up MIDI file, also set by script args. // D0: MIDI number to default to for this boss, if no enhanced music is available. // Split argument, high and low at decimal point: // #####.xxxx -> Backup MIDI file to play if enhanced BOSS music is not available. // xxxxx.#### -> Backup MIDI file to play if enhanced VICTORY music is not available. // D1: Screen->D reg to set/check. // D2: The duration of the victory music. // If set to 0, the track will not play. // If set to greater than 0, the track will play for a specific duration, as follows: // To set using minutes, and seconds, set up minutes as the integer portion of the arg, and seconds as the decimal portion: // e.g. 00005.0260 is 5 mins, 26 seconds. // This works to a fineness of 1/10 second, so 00010.0136 is 10 minutes, 13.6 seconds. // If you wish to specify the duration in frames, set the ten-thousands place to '1', and the rest of the value to the number of frames. // e.g. 10526.1023 = 5,261,023 frames. // e.g. 10001.3591 = 13,591 frames. // // D3: Sets file type for both enhanced music tracks. Split argument, high and low at decimal point: // xxx##.xxxx -> Type for Boss Music file // xxxxx.xx## -> Type for Victory Music file // D4: The STRING number, and track number, for Boss Music. Split arg, high and low at decimal point: // #####.xxxx -> The file number. // xxxxx.#### -> The track number to play. // Uses string ID from internal strings table. // D5: The STRING number, and track number, for Victory Music. Split arg, high and low at decimal point: // #####.xxxx -> The file number. // xxxxx.#### -> The track number to play. // Uses string ID from internal strings table. // D6: The point in the track to pause, then loop // // If set to 0, the track with loop only when it ends. // If set to greater than 0, the track will loop befor eit ends, as follows: // To loop by setting minutes, and seconds, set up minutes as the integer portion of the arg, and seconds as the decimal portion: // e.g. 00005.0260 is 5 mins, 26 seconds. // This works to a fineness of 1/10 second, so 00010.0136 is 10 minutes, 13.6 seconds. // If you wish to specify the loop in frames, set the ten-thousands place to '1', and the rest of the value to the number of frames. // e.g. 10526.1023 = 5,261,023 frames. // e.g. 10001.3591 = 13,591 frames. // // D7: This value instructs the FFC to set Screen->D[reg] = 1 when enemies are dead. // A value of zero here, instructs the FFC not to change the Screen->D[reg] value. Leave this at zero, if the enemy does this. // Otherwise, set this to -1 (negative one) if you want the Victory music to play when all screen NPCs are dead...or... // a positive value matching an enemy ID that is on the screen, if you want to play the Victory music when all enemies with that ID are dead. //Version 0.44 - Strings set by String Table (ZQuest String Editor, not hardcoded) ffc script BossMusicEnhanced_InternalStrings{ //Credit Moosh for reminding me that reading internal strings in the string table is a thing. void run(int midiNumber_victoryMidiNumber, int reg, int vict_dur, float musicType_musicTypeVictory, float musicBoss_trkBoss, float musicVictory_trkVictory, float loopBossMusic, int enem){ int curScreen = Game->GetCurScreen(); int curDMAP = Game->GetCurDMap(); int curDmap = Game->GetCurDMap(); int dat = Game->GetScreenD(curScreen,reg); int stdMIDI = Game->DMapMIDI[curDMAP]; int dmapMusicBuffer[512]=" "; Game->GetDMapMusicFilename(curDMAP, dmapMusicBuffer); int midiNumber = _GetHighArgument(midiNumber_victoryMidiNumber); //#####.xxxx int victoryMIDI = _GetLowArgument(midiNumber_victoryMidiNumber); //xxxxx.#### int musicType = _GetHighArgument(musicType_musicTypeVictory); //xxx##.xxxx int musicType_Victory = _GetLowArgument(musicType_musicTypeVictory); //xxxxx.xx## int musicBoss = _GetHighArgument(musicBoss_trkBoss); //#####.xxxx int trkBoss = _GetLowArgument(musicBoss_trkBoss); //xxxxx.#### int musicVictory = _GetHighArgument(musicVictory_trkVictory); int trkVictory = _GetLowArgument(musicVictory_trkVictory); //xxxxx.#### int dmapTrack = Game->GetDMapMusicTrack(curDMAP); int boss_buffer[255]=" "; //two-digit number, plus four-digit extension, plus NULL. int victory_buffer[255]=" "; //Buffer for Victory Music Filename. Game->GetMessage(musicVictory, victory_buffer); Game->GetMessage(musicBoss, boss_buffer); //Print filenames to allegro.log. int loading[]="Attempting to load file: "; TraceNL(); TraceS(loading); TraceNL(); TraceS(boss_buffer); TraceNL(); TraceS(loading); TraceNL(); TraceS(victory_buffer); TraceNL(); int playingBoss[]="Playing Boss Music"; int playingVictory[]="Playing Victory Music"; int errLoading[]="Error loading track."; int LoopClockMethod = _GetDigit(loopBossMusic, 4); //Convert mins and seconds. int BossMusicDuration; if ( LoopClockMethod == 0 ) { BossMusicDuration = MusicFrames(loopBossMusic); //Convert loopBossMusic into time. } if ( LoopClockMethod > 0 ) { BossMusicDuration = _GetPartialArg(loopBossMusic,3,8); //Use the full value of loopBossMusic as frame in int. } int VictoryClockMethod = _GetDigit(vict_dur, 4); int dur; if ( VictoryClockMethod == 0 ) { dur = MusicFrames(vict_dur); //Convert victory music into frames. } if ( VictoryClockMethod > 0 ) { dur = _GetPartialArg(vict_dur,3,8); //Use the full value of loopBossMusic as frame in int. } bool playing = false; while(true){ dat = Game->GetScreenD(curScreen,reg); Waitframes(6); //Wait for enemies to spawn. //Set Screen->D[reg] = 1 if the enemy is dead. if ( enem == -1 && !Screen->NumNPCs() ) { Game->SetScreenD(curScreen,reg,1); } if ( enem == 0 ) { //Should we do anything special? //A zero value is intended to be used if we don't want the FFC to set Screen->D to 1. //-1 if we do it based on all enemies being dead. //A positive value trips it if there are no enemies of that ID on the screen. } if ( enem > 0 && !NumNPCsOf(enem) ){ Game->SetScreenD(curScreen,reg,1); } dat = Game->GetScreenD(curScreen,reg); if ( dat == 0 && loopBossMusic == 0 && !playing ){ Game->PlayEnhancedMusic(boss_buffer, trkBoss); TraceS(playingBoss); if ( ! Game->PlayEnhancedMusic(boss_buffer, trkBoss) ) { TraceS(errLoading); if ( midiNumber > 0 ) { Game->PlayMIDI(midiNumber); //Play MIDI if enhanced music is not available. } else { Game->PlayMIDI(DEFAULT_BOSS_MUSIC); //Play default music if midiNumber is set to '0'. } } playing = true; } if ( dat == 0 && loopBossMusic > 0 ){ //set up music loop for ( int q = BossMusicDuration; q >=0; q-- ){ if ( q == BossMusicDuration && dat == 0 ) { Game->PlayEnhancedMusic(boss_buffer, trkBoss); TraceS(playingBoss); if ( ! Game->PlayEnhancedMusic(boss_buffer, trkBoss) ) { TraceS(errLoading); Game->PlayMIDI(midiNumber); //Play MIDI if enhanced music is not available. } } if ( enem == -1 && !Screen->NumNPCs() ) { Game->SetScreenD(curScreen,reg,1); } if ( enem == 0 ) { //Should we do anything special? //A zero value is intended to be used if we don;t want the FFC to set Screen->D to 1. //-1 if we do it based on all enemies being dead. //A positive value trips it if there are no enemies of that ID on the screen. } if ( enem > 0 && !NumNPCsOf(enem) ){ Game->SetScreenD(curScreen,reg,1); } dat = Game->GetScreenD(curScreen,reg); if ( dat > 0 ) { break; } Waitframe(); } } if ( dat == 0 && loopBossMusic == 0 && !playing ){ Game->PlayEnhancedMusic(boss_buffer, trkBoss); TraceS(playingBoss); if ( ! Game->PlayEnhancedMusic(boss_buffer, trkBoss) ) { TraceS(errLoading); if ( midiNumber > 0 ) { Game->PlayMIDI(midiNumber); //Play MIDI if enhanced music is not available. } else { Game->PlayMIDI(DEFAULT_BOSS_MUSIC); //Plays default if not specified. } } playing = true; } dat = Game->GetScreenD(curScreen,reg); if ( dat > 0 ) { if ( dur > 0 ) { Game->PlayEnhancedMusic(victory_buffer, trkVictory); TraceS(playingVictory); if ( ! Game->PlayEnhancedMusic(victory_buffer, trkVictory) ) { TraceS(errLoading); if ( victoryMIDI > 0 ) { Game->PlayMIDI(victoryMIDI); } else { Game->PlayMIDI(MIDI_DEFEATBOSS); //Plays default if Victory MIDI not specified. } } for ( int q = 0; q <= dur; q++ ) { Waitframe(); //Pause for duration of victory music. } } Game->PlayEnhancedMusic(dmapMusicBuffer, dmapTrack); if ( ! Game->PlayEnhancedMusic(dmapMusicBuffer, dmapTrack) ) { Game->PlayMIDI(stdMIDI); } Quit(); } Waitframe(); } } } // D0: MIDI number to default to for this boss, if no enhanced music is available. // Split argument, high and low at decimal point: // #####.xxxx -> Backup MIDI file to play if enhanced BOSS music is not available. // xxxxx.#### -> Backup MIDI file to play if enhanced VICTORY music is not available. // D1: Screen->D reg to set/check. // D2: Set to a value of '1' or higher, to use durations. // D3: Sets file type for both enhanced music tracks. Split argument, high and low at decimal point: // xxx##.xxxx -> Type for Boss Music file // xxxxx.xx## -> Type for Victory Music file // D4: The file number, and track number, for Boss Music. Split arg, high and low at decimal point: // #####.xxxx -> The file number. // xxxxx.#### -> The track number to play. // D5: The file number, and track number, for Victory Music. Split arg, high and low at decimal point: // #####.xxxx -> The file number. // xxxxx.#### -> The track number to play. // D6: The point in the track to pause, then loop. // // If set to 0, the track with loop only when it ends. // If set to greater than 0, the track will loop befor eit ends, as follows: // To loop by setting minutes, and seconds, set up minutes as the integer portion of the arg, and seconds as the decimal portion: // e.g. 00005.0260 is 5 mins, 26 seconds. // This works to a fineness of 1/10 second, so 00010.0136 is 10 minutes, 13.6 seconds. // If you wish to specify the loop in frames, set the ten-thousands place to '1', and the rest of the value to the number of frames. // e.g. 10526.1023 = 5,261,023 frames. // e.g. 10001.3591 = 13,591 frames. // // D7: This value instructs the FFC to set Screen->D[reg] = 1 when enemies are dead. // A value of zero here, instructs the FFC not to change the Screen->D[reg] value. Leave this at zero, if the enemy does this. // Otherwise, set this to -1 (negative one) if you want the Victory music to play when all screen NPCs are dead...or... // a positive value matching an enemy ID that is on the screen, if you want to play the Victory music when all enemies with that ID are dead. //Version 0.44 (Numbered Files) ffc script BossMusicEnhanced{ void run(int midiNumber_victoryMidiNumber, int reg, int victoryDur, float musicType_musicTypeVictory, float musicBoss_trkBoss, float musicVictory_trkVictory, float loopBossMusic, int enem){ int curScreen = Game->GetCurScreen(); int curDMAP = Game->GetCurDMap(); int curDmap = Game->GetCurDMap(); int dat = Game->GetScreenD(curScreen,reg); int stdMIDI = Game->DMapMIDI[curDMAP]; int dmapMusicBuffer[512]=" "; Game->GetDMapMusicFilename(curDMAP, dmapMusicBuffer); int midiNumber = _GetHighArgument(midiNumber_victoryMidiNumber); //#####.xxxx int victoryMIDI = _GetLowArgument(midiNumber_victoryMidiNumber); //xxxxx.#### int musicType = _GetHighArgument(musicType_musicTypeVictory); //xxx##.xxxx int musicType_Victory = _GetLowArgument(musicType_musicTypeVictory); //xxxxx.xx## int musicBoss = _GetHighArgument(musicBoss_trkBoss); //#####.xxxx int trkBoss = _GetLowArgument(musicBoss_trkBoss); //xxxxx.#### int musicVictory = _GetHighArgument(musicVictory_trkVictory); //#####.xxxx int trkVictory = _GetLowArgument(musicVictory_trkVictory); //xxxxx.#### int dmapTrack = Game->GetDMapMusicTrack(curDMAP); int mp3[]=".mp3"; int vgm[]=".vgm"; int nsf[]=".nsf"; int ogg[]=".ogg"; int s3m[]=".s3m"; int mod[]=".mod"; int spc[]=".spc"; int gym[]=".gym"; int gbs[]=".gbs"; int it_format[]=".it"; int xm[]=".xm"; int boss_buffer[7]=" "; //two-digit number, plus four-digit extension, plus NULL. int victory_buffer[7]=" "; //Buffer for Victory Music Filename. int strBoss[2]=" "; //The two digit value of musicBoss arg. int strVictory[2]=" "; //The two digit value of musicVictory is stored here. //int bossMusic[]=" "; //Must read value from enhBoss, append .mp3 to it, and ///Set up Boss Music Filename String itoa(strBoss, musicBoss); //Copy the value of arg musicBoss into string strBoss. strncpy(boss_buffer, strBoss, 2); //Copy filename (two-digit number) to buffer. if ( musicType == 0 ) strcat(boss_buffer, mp3); //Append datatype to buffer (MP3) else if ( musicType == 1 ) strcat(boss_buffer, vgm); //Append datatype to buffer ( Video Game Music format) else if ( musicType == 2 ) strcat(boss_buffer, nsf); //Append datatype to buffer ( NES Sound File ) else if ( musicType == 3 ) strcat(boss_buffer, ogg); //Append datatype to buffer ( The Xiph.org open music format ) else if ( musicType == 4 ) strcat(boss_buffer, s3m); //Append datatype to buffer ( ScreamTracker 3 module file ) else if ( musicType == 5 ) strcat(boss_buffer, mod); //Append datatype to buffer ( Tracker Module file ) else if ( musicType == 6 ) strcat(boss_buffer, spc); //Append datatype to buffer ( Super NES / SuFami soound file ) else if ( musicType == 7 ) strcat(boss_buffer, gym); //Append datatype to buffer ( Genesis / Megadrive sound file ) else if ( musicType == 8 ) strcat(boss_buffer, gbs); //Append datatype to buffer ( Gameboy sound file ) else if ( musicType == 9 ) strcat(boss_buffer, it_format); //Append datatype to buffer ( Impulse Tracker audio file ) else if ( musicType == 10 ) strcat(boss_buffer, xm); //Append datatype to buffer ( Triton FastTracker 2 'Extended Module' format } ///Other formats. //Set up Victory Music Filename String itoa(strVictory, musicVictory); //Copy the value of arg musicVictory into string strVictory. strncpy(victory_buffer, strVictory, 2); //Copy filename (two-digit number) to buffer. if ( musicType_Victory == 0 ) strcat(victory_buffer, mp3); //Append datatype to buffer (MP3) else if ( musicType_Victory == 1 ) strcat(victory_buffer, vgm); //Append datatype to buffer ( Video Game Music format) else if ( musicType_Victory == 2 ) strcat(victory_buffer, nsf); //Append datatype to buffer ( NES Sound File ) else if ( musicType_Victory == 3 ) strcat(victory_buffer, ogg); //Append datatype to buffer ( The Xiph.org open music format ) else if ( musicType_Victory == 4 ) strcat(victory_buffer, s3m); //Append datatype to buffer ( ScreamTracker 3 module file ) else if ( musicType_Victory == 5 ) strcat(victory_buffer, mod); //Append datatype to buffer ( Tracker Module file ) else if ( musicType_Victory == 6 ) strcat(victory_buffer, spc); //Append datatype to buffer ( Super NES / SuFami soound file ) else if ( musicType_Victory == 7 ) strcat(victory_buffer, gym); //Append datatype to buffer ( Genesis / Megadrive sound file ) else if ( musicType_Victory == 8 ) strcat(victory_buffer, gbs); //Append datatype to buffer ( Gameboy sound file ) else if ( musicType_Victory == 9 ) strcat(victory_buffer, it_format); //Append datatype to buffer ( Impulse Tracker audio file ) else if ( musicType_Victory == 10 ) strcat(victory_buffer, xm); //Append datatype to buffer ( Triton FastTracker 2 'Extended Module' format } ///Other formats. //Print filenames to allegro.log. int loading[]="Attempting to load file: "; TraceNL(); TraceS(loading); TraceNL(); TraceS(boss_buffer); TraceNL(); TraceS(loading); TraceNL(); TraceS(victory_buffer); TraceNL(); int playingBoss[]="Playing Boss Music"; int playingVictory[]="Playing Victory Music"; int errLoading[]="Error loading track."; int LoopClockMethod = _GetDigit(loopBossMusic, 4); //Convert mins and seconds. int BossMusicDuration; if ( LoopClockMethod == 0 ) { BossMusicDuration = MusicFrames(loopBossMusic); //Convert loopBossMusic into time. } if ( LoopClockMethod > 0 ) { BossMusicDuration = _GetPartialArg(loopBossMusic,3,8); //Use the full value of loopBossMusic as frame in int. } int VictoryDuration; int VictoryDurMethod = _GetDigit(victoryDur, 4); if ( VictoryDurMethod == 0 ) { VictoryDuration = MusicFrames(victoryDur); //Convert loopBossMusic into time. } if ( VictoryDurMethod > 0 ) { VictoryDuration = _GetPartialArg(victoryDur,3,8); //Use the full value of loopBossMusic as frame in int. } bool playing = false; while(true){ dat = Game->GetScreenD(curScreen,reg); Waitframes(6); //Wait for enemies to spawn. //Set Screen->D[reg] = 1 if the enemy is dead. if ( enem == -1 && !Screen->NumNPCs() ) { Game->SetScreenD(curScreen,reg,1); } if ( enem == 0 ) { //Should we do anything special? //A zero value is intended to be used if we don;t want the FFC to set Screen->D to 1. //-1 if we do it based on all enemies being dead. //A positive value trips it if there are no enemies of that ID on the screen. } if ( enem > 0 && !NumNPCsOf(enem) ){ Game->SetScreenD(curScreen,reg,1); } dat = Game->GetScreenD(curScreen,reg); if ( dat == 0 && loopBossMusic == 0 && !playing ){ Game->PlayEnhancedMusic(boss_buffer, trkBoss); TraceS(playingBoss); if ( ! Game->PlayEnhancedMusic(boss_buffer, trkBoss) ) { TraceS(errLoading); if ( midiNumber > 0 ) { Game->PlayMIDI(midiNumber); //Play MIDI if enhanced music is not available. } else { Game->PlayMIDI(DEFAULT_BOSS_MUSIC); //Play default if not assigned. } } playing = true; } if ( dat == 0 && loopBossMusic > 0 ){ //set up music loop for ( int q = BossMusicDuration; q >=0; q-- ){ if ( q == BossMusicDuration && dat == 0 ) { Game->PlayEnhancedMusic(boss_buffer, trkBoss); TraceS(playingBoss); if ( ! Game->PlayEnhancedMusic(boss_buffer, trkBoss) ) { TraceS(errLoading); if ( midiNumber > 0 ) { Game->PlayMIDI(midiNumber); //Play MIDI if enhanced music is not available. } else { Game->PlayMIDI(DEFAULT_BOSS_MUSIC); //Play default if not assigned. } } } if ( enem == -1 && !Screen->NumNPCs() ) { Game->SetScreenD(curScreen,reg,1); } if ( enem == 0 ) { //Should we do anything special? //A zero value is intended to be used if we don;t want the FFC to set Screen->D to 1. //-1 if we do it based on all enemies being dead. //A positive value trips it if there are no enemies of that ID on the screen. } if ( enem > 0 && !NumNPCsOf(enem) ){ Game->SetScreenD(curScreen,reg,1); } dat = Game->GetScreenD(curScreen,reg); if ( dat > 0 ) { break; } Waitframe(); } } if ( dat == 0 && loopBossMusic == 0 && !playing ){ Game->PlayEnhancedMusic(boss_buffer, trkBoss); TraceS(playingBoss); if ( ! Game->PlayEnhancedMusic(boss_buffer, trkBoss) ) { TraceS(errLoading); if ( midiNumber > 0 ) { Game->PlayMIDI(midiNumber); //Play MIDI if enhanced music is not available. } else { Game->PlayMIDI(DEFAULT_BOSS_MUSIC); //Play default if not assigned. } } playing = true; } dat = Game->GetScreenD(curScreen,reg); if ( dat > 0 ) { if ( VictoryDuration > 0 ) { Game->PlayEnhancedMusic(victory_buffer, trkVictory); TraceS(playingVictory); if ( ! Game->PlayEnhancedMusic(victory_buffer, trkVictory) ) { TraceS(errLoading); if ( victoryMIDI > 0 ) { Game->PlayMIDI(victoryMIDI); } else { Game->PlayMIDI(MIDI_DEFEATBOSS); } } for ( int q = 0; q <= VictoryDuration; q++ ) { Waitframe(); //Pause for duration of victory music. } } Game->PlayEnhancedMusic(dmapMusicBuffer, dmapTrack); if ( ! Game->PlayEnhancedMusic(dmapMusicBuffer, dmapTrack) ) { Game->PlayMIDI(stdMIDI); } Quit(); } Waitframe(); } } } ///////////////// /// FUNCTIONS /// ///////////////// //Pass a float to either of these, to convert raw float into mins and seconds as: // #####.xxxx = # mins x seconds. Example: // 00003.0050 = 3 mins, 5 seconds. // 00001.0012 = 1 minute, 5.2 seconds. //Timers are functional to a total clock of 3579 seconds (59 mins, 39 seconds). int MusicSeconds(float seconds){ int music_seconds = _GetLowArgument(seconds); return music_seconds * 6; } int MusicMinutes(float mins){ int music_minutes = _GetHighArgument(mins); return music_minutes * 360; } //Returns total time in frames, so that ZC understands it. int MusicFrames(float val){ int mins = MusicMinutes(val); int seconds = MusicSeconds(val); return mins+seconds; } int _GetRemainderAsInt(int v) { int r = (v - (v << 0)) * 10000; return r; } // This function breaks up the value of an argument into individual digits. It is combined with the function GetDigit below. int _GetDigit(int n, int place){ //GetDigit and related functions by Gleeok place = Clamp(place, -4, 4); if(place < 0){ n = _GetRemainderAsInt(n); place += 4; } int r = ((n / Pow(10, place)) % 10) << 0; return r; } int _GetHighArgument(int arg) { return arg >> 0; } int _GetLowArgument(int arg) { return (arg - (arg >> 0)) * 10000; } int _GetPartialArg(int arg, int place, int num){ place = Clamp(place, -4, 4); int r; int adj = 1; for(int i = num-1; i > -1; i--){ if(place - i < -4) continue; r += _GetDigit(arg, place - i) * adj; adj *= 10; } return r; }