slserpent
Junior Member
 
Posts: 11
Joined: Feb 2010
|
RE: Anyway to add or remove certain music?
(06-02-2010 05:28 AM)FordGT90Concept Wrote: It will take a lot of work to decompile it.
I did it. I decompiled 37 unique operations out of the 126 in total. My results from that follow. Since I had to do this manually (none of the decompilers work apparently), the format is a little peculiar. But it basically reads as follows: BinaryCode: (Operation A B C) Assembler; // Psuedocode
Code:
Offset 20 -> Op:000101 A:00000000 B:000000000000000000: (GetGlobal 0 0) Register_A = Global(Constant_0); // "namespace"
Op:000001 A:00000001 B:000000000000000001: (LoadK 1 1) Register_B = Constant_1; // "Playlists"
Op:011100 A:00000000 C:000000001 B:000000010: (Call 0 2 1) Call Func_A(Register_B); // namespace(Playlists)
Op:000001 A:00000000 B:000000000000000011: (LoadK 0 3) Register_A = Constant_3; // 25
Op:000111 A:00000000 B:000000000000000010: (SetGlobal 0 2) Global(Constant_2) = Register_A; // Global(DefaultSilenceChance) = 25
Op:000001 A:00000000 B:000000000000000101: (LoadK 0 5) Register_A = Constant_5; // 15000
Op:000111 A:00000000 B:000000000000000100: (SetGlobal 0 4) Global(Constant_4) = Register_A; // Global(DefaultSilenceDuration) = 15000
Op:000001 A:00000000 B:000000000000000111: (LoadK 0 7) Register_A = Constant_7; // 3000
Op:000111 A:00000000 B:000000000000000110: (SetGlobal 0 6) Global(Constant_6) = Register_A; // Global(DefaultCrossfadeTime) = 3000
Op:000001 A:00000000 B:000000000000001001: (LoadK 0 9) Register_A = Constant_9; // 60000
Op:000111 A:00000000 B:000000000000001000: (SetGlobal 0 8) Global(Constant_8) = Register_A; // Global(BattleMusicTimeout) = 60000
Offset 4C -> Op:001010 A:00000000 C:000000000 B:000001111: (NewTable 0 15 0) Register_A = Array[15];
Op:001010 A:00000001 C:000000100 B:000000000: (NewTable 1 0 4) Register_B = Array[0][4];
Op:001001 A:00000001 C:1-00001100 B:1-00001011: (SetTable 1 11 12) Register_B[Constant_11] = Constant_12; // B["path"] = "Music/Track1.ogg"
Op:001001 A:00000001 C:1-00001110 B:1-00001101: (SetTable 1 13 14) Register_B[Constant_13] = Constant_14; // B["frequency"] = 100
Op:001001 A:00000001 C:1-00000101 B:1-00001111: (SetTable 1 15 5) Register_B[Constant_15] = Constant_5; // B["SilenceDuration"] = 15000
Op:001001 A:00000001 C:1-00000011 B:1-00010000: (SetTable 1 16 3) Register_B[Constant_16] = Constant_3; // B["SilenceChance"] = 25
Op:001010 A:00000010 C:000000100 B:000000000: (NewTable 2 0 4) Register_C = Array[0][4];
Op:001001 A:00000010 C:1-00010001 B:1-00001011: (SetTable 2 11 17) Register_C[Constant_11] = Constant_17; // B["path"] = "Music/Track2.ogg"
Last 5 operations repeat 14 times
Offset 17C -> Op:100010 A:00000000 C:000000001 B:000001111: (SetList 0 15 1) Register_A[i] = Register_B..P; // for (int i = 0; i < 15; i++) A[i] = *B + i
Op:000111 A:00000000 B:000000000000001010: (SetGlobal 0 10) Global(Constant_10) = Register_A; // Global(AllTracks) = Register_A
Op:001010 A:00000000 C:000000000 B:000000101: (NewTable 0 5 0) Register_A = Array[5];
Repeats as before, loading the array structure except this time with the following tracks loaded for path:
Constant_11, Constant_27, Constant_28, Constant_29, Constant_30
"Music/Track1.ogg", Music/Track12.ogg, Music/Track13.ogg, Music/Track14.ogg, Music/Track15.ogg
Offset 1EC -> Op:100010 A:00000000 C:000000001 B:000000101: (SetList 0 5 1) Register_A[i] = Register_B..G; // for (int i = 0; i < 5; i++) A[i] = *B + i
Op:000111 A:00000000 B:000000000000011111: (SetGlobal 0 31) Global(Constant_31) = Register_A; // Global(Tutorial) = Register_A
Op:000101 A:00000000 B:000000000000100000: (GetGlobal 0 32) Register_A = Global(Constant_32); // "IsDemo"
Op:011100 A:00000000 C:000000010 B:000000001: (Call 0 1 2) Register_A = Func_A(); // Register_A = IsDemo()
Op:011010 A:00000000 C:000000000 B:000000000: (Test 0 0) if not Register_A == 0 then //takes the next jump
Op:010110 A:00000000 B:100000000000000001: (Jump +1) // goto instruction after next
Op:000101 A:00000000 B:000000000000011111: (GetGlobal 0 0) Register_A = Global(Constant_31); // "Tutorial"
Op:000111 A:00000000 B:000000000000001010: (SetGlobal 0 10) Global(Constant_10) = Register_A; // Global(AllTracks) = Register_A
Op:001010 A:00000000 C:000000000 B:000000000: (NewTable 0 0 0) Register_A = Array[0];
Op:000111 A:00000000 B:000000000000100001: (SetGlobal 0 33) Global(Constant_33) = Register_A; // Global(Empty) = Register_A
Here's what that would look like in psuedocode:
Code:
call namespace(Playlists)
global DefaultSilenceChance = 25;
global DefaultSilenceDuration = 15000;
global DefaultCrossfadeTime = 3000;
global BattleMusicTimeout = 60000;
global AllTracks = New Array(15);
for (i = 0; i < 15; i++) {
AllTracks[i].path = "Music/Track" + (i+1) + ".ogg";
AllTracks[i].frequency = 100;
AllTracks[i].SilenceDuration = DefaultSilenceDuration;
AllTracks[i].SilenceChance = DefaultSilenceChance;
}
global Tutorial = New Array(5);
for (i = 0; i < 5; i++) {
AllTracks[i].path = "Music/Track" + (i+1) + ".ogg";
AllTracks[i].frequency = 100;
AllTracks[i].SilenceDuration = DefaultSilenceDuration;
AllTracks[i].SilenceChance = DefaultSilenceChance;
}
if (IsDemo() == 1) {
AllTracks = Tutorial;
}
What you'll notice is that the global variable AllTracks holds all the track filenames. Also, the last two blocks of code aren't needed for the full version of the game and the randomization must be done in the calling function. So basically, as long as you create a global array called AllTracks with as many elements as tracks you want, the game will take your new track listing.
Each element in the AllTracks array needs to be an array with the following keys:
- path - the path to the track relative to the tropico 3 directory. may also take absolute paths?
- frequency - guessing this is a weight for how likely it is that the track is to be picked, but i haven't tested it
- SilenceDuration - length of time in milliseconds of silence after the track has played?
- SilenceChance - chance that there will be silence after the track is played?
You can use the following LUA script to get you started (it includes Tropico 1 filenames for if you converted those to OGG):
Code:
namespace("Playlists")
DefaultSilenceChance = 25
DefaultSilenceDuration = 15000
DefaultCrossfadeTime = 3000
BattleMusicTimeout = 60000
AllTracks = {}
AllTracks[1] = {path="Music/ADAT01.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[2] = {path="Music/Track1.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[3] = {path="Music/Track10.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[4] = {path="Music/Track11.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[5] = {path="Music/Track12.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[6] = {path="Music/Track13.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[7] = {path="Music/Track14.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[8] = {path="Music/Track15.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[9] = {path="Music/Track2.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[10] = {path="Music/Track3.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[11] = {path="Music/Track4.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[12] = {path="Music/Track5.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[13] = {path="Music/Track6.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[14] = {path="Music/Track7.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[15] = {path="Music/Track8.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[16] = {path="Music/Track9.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[17] = {path="Music/XDAT02.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[18] = {path="Music/XDAT03.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[19] = {path="Music/XDAT04.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[20] = {path="Music/XDAT05.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[21] = {path="Music/XDAT06.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[22] = {path="Music/XDAT07.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[23] = {path="Music/XDAT08.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[24] = {path="Music/XDAT09.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[25] = {path="Music/XDAT10.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[26] = {path="Music/XDAT12.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[27] = {path="Music/XDAT13.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[28] = {path="Music/XDAT14.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[29] = {path="Music/XDAT15.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[30] = {path="Music/XDAT16.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[31] = {path="Music/XDAT17.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[32] = {path="Music/Xdat18.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[33] = {path="Music/Xdat19.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[34] = {path="Music/Xdat20.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[35] = {path="Music/Xdat21.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[36] = {path="Music/Xdat22.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[37] = {path="Music/Xdat23.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[38] = {path="Music/Xdat25.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[39] = {path="Music/Xdat26.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[40] = {path="Music/Xdat27.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[41] = {path="Music/Xdat28.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[42] = {path="Music/Xdat29.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[43] = {path="Music/Xdat30.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[44] = {path="Music/Xdat31.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[45] = {path="Music/Xdat32.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[46] = {path="Music/Xdat33.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[47] = {path="Music/Xdat36.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[48] = {path="Music/Xdat37.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
AllTracks[49] = {path="Music/Xdat39.ogg", frequency=100, SilenceDuration=DefaultSilenceDuration, SilenceChance=DefaultSilenceChance}
After you've edited the above script, adding or removing whatever tracks you want, you'll need to save and compile it so the game can read it. Unfortunately, the default LUA compiler won't work because it uses doubles for number data where Tropico 3 uses integers. So you'll have to download my special LUA compiler with that modification made. Extract the luac.exe file to wherever you saved your script to (desktop in the example below). Then to compile, run "cmd" and follow this procedure, making sure to substitute appropriate drive letters, directories, and filenames where underlined:
- D:\Documents and Settings\User>C: #change current drive
- C:\>cd Documents and Settings\User\Desktop #change current directory
- C:\Documents and Settings\User\Desktop>luac -o "C:\Program Files\Valve\Steam\SteamApps\common\tropico 3\Data\Sounds\Playlists\Playlists.lua" Playlists.lua #compile the script and put the output in the correct directory
Then you should be all set. If you get a compile error, go back and check your syntax in the script. If you compile okay but get no music when starting a game, double check your script (it may have compiled okay, but the game still had troubles reading the array it output) and make sure your music files exist in the right place.
Good luck and happy modding!
(This post was last modified: 08-02-2010 02:28 AM by slserpent.)
|
|