Jump to content


Photo

songlist.2da limit


  • Please log in to reply
48 replies to this topic

#1 Taimon

Taimon
  • Member
  • 387 posts

Posted 24 May 2009 - 02:51 PM

I've made an exe patch to increase the songlist limit to 500 entries.
Definitely needs some more testing, I only verified that the game loads with 100+ entries, the menu music plays and that I can PlaySound an 100+ entry.
It's very possible that it crashes your game under certain circumstances.

The patch works by skipping the numSongs > 100 test, increasing the stack of the function and patching all the local variable references to account for the stack changes.

/Edit: Works only with the patched ToB executable (Windows).

/Edit2: Updated to remove byte restrictions when using song references in area files.

Attached Files


Edited by Taimon, 02 June 2009 - 07:46 AM.


#2 Kaeloree

Kaeloree

    Head Molder

  • Administrator
  • 9198 posts

Posted 25 May 2009 - 12:04 AM

That's pretty exciting, I have to say.

#3 Jarno Mikkola

Jarno Mikkola

    The Imp in his pink raincoat.

  • Member
  • 10911 posts

Posted 25 May 2009 - 12:51 AM

Now, if someone could just add this as a useful part for the BGTMusic.exe so most of the custom songs are used... :devil:

Deactivated account. The user today is known as The Imp.


#4 Chevalier

Chevalier

    Knight of the Realms

  • Modder
  • 2405 posts

Posted 25 May 2009 - 01:12 AM

Hey Taimon the Code Mage,

Can you do something about only being able to have 6 members in the party? They used to say it was hardcoded, but with your magic you might be able change the limit. Maybe make it 8 or 9 party members??

I Ride for the King!


a.k.a. Chev


#5 GeN1e

GeN1e

    A very GAR character

  • Modder
  • 1604 posts

Posted 25 May 2009 - 02:36 AM

I have a request too - to alter the Stone Skin opcode, so it doesn't turn caster's clothes and hair gray. I tried to something about it long ago but softcode methods proved to be useless.

Retired from modding.


#6 Taimon

Taimon
  • Member
  • 387 posts

Posted 25 May 2009 - 03:17 AM

Can you do something about only being able to have 6 members in the party? They used to say it was hardcoded, but with your magic you might be able change the limit. Maybe make it 8 or 9 party members??

No way. At least not with patching.
Maybe Asc64 can conjure something out of his hat with the injection technique, but my best bet is with gemrb.

I have a request too - to alter the Stone Skin opcode, so it doesn't turn caster's clothes and hair gray. I tried to something about it long ago but softcode methods proved to be useless.

But then you don't have any visual indication that a character is under the stoneskin effect.
(/Edit: At 0x001399D5 change 0x0f,0x8d,0x8c,0x00,0x00,0x00 into 0xe9,0x8d,0x00,0x00,0x00,0x90)

Anyway, back on topic please. Did it work for you?

Edited by Taimon, 25 May 2009 - 04:27 AM.


#7 Creepin

Creepin
  • Administrator
  • 1676 posts

Posted 25 May 2009 - 05:38 AM

You all are forgetting most important hardcoded thing that needed implementation for a long time: slider bars for mage and cleric spellbooks! :)

P.S. Or did I missed it being implemented already? :rolleyes:

The Old Gold - v0.2 WIP (mod for BGT/BWP/BWS)


#8 Icendoan

Icendoan

    "An Infinite Deal of Nothing"

  • Member
  • 1723 posts

Posted 25 May 2009 - 05:41 AM

That does happen to be in GemRB, at least, someone has made one for it. I don't know if it is bug-free. :)

Icen
Proud member of the 'I HATE Elminster!' Club!

Mods in development: Keeping Yoshimo

#9 AnnabelleRose

AnnabelleRose

    The great pretender... of modding!

  • Modder
  • 2083 posts

Posted 25 May 2009 - 04:07 PM

I've made an exe patch to increase the songlist limit to 500 entries.
Definitely needs some more testing, I only verified that the game loads with 100+ entries, the menu music plays and that I can PlaySound an 100+ entry.
It's very possible that it crashes your game under certain circumstances.

The patch works by skipping the numSongs > 100 test, increasing the stack of the function and patching all the local variable references to account for the stack changes.

/Edit: Works only with the patched ToB executable (Windows).


I think this is one of the best mods that has been created in a very long time.

AWESOME work.

- The transitioned former modder once known as MTS.


#10 Daulmakan

Daulmakan

    Comfortably numb

  • Member
  • 1065 posts

Posted 26 May 2009 - 01:38 AM

Yeah, we need more praise for Taimon in here. Posted Image

You rock, man! :clap:

item_pack.jpg   Drows.jpg

 


#11 Taimon

Taimon
  • Member
  • 387 posts

Posted 26 May 2009 - 04:08 AM

You all are forgetting most important hardcoded thing that needed implementation for a long time: slider bars for mage and cleric spellbooks! :)

Adding functionality is something that's very difficult to do with patching, because of the size limitations.
(Basically, you can only change existing instructions, not add new ones. If you find unused parts in the executable you might be able to hack something in, but that's really hard.)

#12 Creepin

Creepin
  • Administrator
  • 1676 posts

Posted 26 May 2009 - 06:41 AM

Adding functionality is something that's very difficult to do with patching, because of the size limitations.
(Basically, you can only change existing instructions, not add new ones. If you find unused parts in the executable you might be able to hack something in, but that's really hard.)

I see. Well, can't blame for asking :)
You've done incredible job with songlist in any case! I just hope it will work correctly with no-cd'ed exe :)

Edited by Creepin, 26 May 2009 - 08:47 PM.

The Old Gold - v0.2 WIP (mod for BGT/BWP/BWS)


#13 Icendoan

Icendoan

    "An Infinite Deal of Nothing"

  • Member
  • 1723 posts

Posted 26 May 2009 - 07:01 AM

[ ]

Icen
Proud member of the 'I HATE Elminster!' Club!

Mods in development: Keeping Yoshimo

#14 Kaeloree

Kaeloree

    Head Molder

  • Administrator
  • 9198 posts

Posted 26 May 2009 - 12:35 PM

I hate to keep reminding people, but it's against the rules to discuss methods of pirating games. Thank you.

#15 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 27 May 2009 - 01:12 AM

I already tested this using different code, but the same patching method, and it does work perfectly in-game.
There is one issue to make it perfectly compatible with scripting: the PlaySong() function only allows a unsigned word for specifying the songlist entry. You'll need to adjust that, otherwise PlaySong(128) will wrap over to PlaySong(-127), which won't crash the game, but will have no effect for entry #128 in sognlist.2da.

Edited by Ascension64, 27 May 2009 - 01:14 AM.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#16 Taimon

Taimon
  • Member
  • 387 posts

Posted 27 May 2009 - 01:46 AM

I already tested this using different code, but the same patching method, and it does work perfectly in-game.

Why didn't you release this?
It makes me feel bad, that I unintentionally stole your idea/work ...

There is one issue to make it perfectly compatible with scripting: the PlaySong() function only allows a unsigned word for specifying the songlist entry. You'll need to adjust that, otherwise PlaySong(128) will wrap over to PlaySong(-127), which won't crash the game, but will have no effect for entry #128 in sognlist.2da.

I don't understand this.
The script compiler should store this value as an dword in the bcs. The PlaySong() action extracts the lower word and passes it to the relevant function in CSoundMixer. So the upper boundary should be 2^15 = 32767. (which is an non-issue for a songlist with max. 500 entries)

#17 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 27 May 2009 - 05:58 AM

I already tested this using different code, but the same patching method, and it does work perfectly in-game.

Why didn't you release this?
It makes me feel bad, that I unintentionally stole your idea/work ...

Nah, it's all cool. It's part of the TobEx utility still in development. So really, "you got there first".

There is one issue to make it perfectly compatible with scripting: the PlaySong() function only allows a unsigned word for specifying the songlist entry. You'll need to adjust that, otherwise PlaySong(128) will wrap over to PlaySong(-127), which won't crash the game, but will have no effect for entry #128 in sognlist.2da.

I don't understand this.
The script compiler should store this value as an dword in the bcs. The PlaySong() action extracts the lower word and passes it to the relevant function in CSoundMixer. So the upper boundary should be 2^15 = 32767. (which is an non-issue for a songlist with max. 500 entries)

Here's a snippet of the code I used to implement the patches (very messy, and uses collections). Looks like I got confused and what I meant was the engine functions for starting and stopping a song takes the lower byte, which is treated as signed (look at the fifth test patch part near the bottom).

//make a fourth test patch
	char oldChar2[] = {0x3C, 0x67};
	char newChar2[] = {0x60, 0xCE};
  dataList.push_back( Data(0x009E20B4, 2, oldChar2, newChar2) ); //stack size for local vars (673C)

	oldChar2[0] = 0xB8;	oldChar2[1] = 0x98;
	newChar2[0] = 0x94;	newChar2[1] = 0x31;
  dataList.push_back( Data(0x009E20BF, 2, oldChar2, newChar2) ); //this pointer (98B8)
  dataList.push_back( Data(0x009E20C5, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E20DB, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E212A, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E2140, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E216F, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E21D3, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E2221, 2, oldChar2, newChar2) );

	char oldChar5[] = {0xE8, 0x49, 0xCF, 0xFC, 0xFF};
	char newChar5[] = {0x90, 0x90, 0x90, 0x90, 0x90};
  dataList.push_back( Data(0x009E211E, 5, oldChar5, newChar5) ); //assertion error call

	oldChar2[0] = 0x50;	oldChar2[1] = 0x9A;
	newChar2[0] = 0xBC;	newChar2[1] = 0x34;
	dataList.push_back( Data(0x009E214A, 2, oldChar2, newChar2) ); //object pointer (9A50)
  dataList.push_back( Data(0x009E2216, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E2241, 2, oldChar2, newChar2) );

	oldChar2[0] = 0x5C;	oldChar2[1] = 0x9A;
	newChar2[0] = 0xC8;	newChar2[1] = 0x34;
  dataList.push_back( Data(0x009E2180, 2, oldChar2, newChar2) ); //for loop count (9A5C)
  dataList.push_back( Data(0x009E218C, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E2195, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E219B, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E21A6, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E21B9, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E21C6, 2, oldChar2, newChar2) );
  dataList.push_back( Data(0x009E21E5, 2, oldChar2, newChar2) );

	oldChar2[0] = 0x60;	oldChar2[1] = 0x9A;
	newChar2[0] = 0xCC;	newChar2[1] = 0x34;
  dataList.push_back( Data(0x009E21B3, 2, oldChar2, newChar2) ); //area for CString musName (9A60)
  dataList.push_back( Data(0x009E21F2, 2, oldChar2, newChar2) );

	oldChar2[0] = 0xC0;	oldChar2[1] = 0x98;
	newChar2[0] = 0x9C;	newChar2[1] = 0x31;
  dataList.push_back( Data(0x009E21C0, 2, oldChar2, newChar2) ); //area for CString* (98C0)
  dataList.push_back( Data(0x009E2207, 2, oldChar2, newChar2) );

	oldChar2[0] = 0xBC;	oldChar2[1] = 0x98;
	newChar2[0] = 0x98;	newChar2[1] = 0x31;
  dataList.push_back( Data(0x009E2230, 2, oldChar2, newChar2) ); //returnVal (98BC)
  dataList.push_back( Data(0x009E224C, 2, oldChar2, newChar2) );

  patchList.push_back( Patch("Double size limit of SONGLIST.2DA (entry treated as signed byte, so 128+ won't play)", dataList) );
  dataList.clear();

	//make a fifth test patch
	//section that stops the music
	oldChar[0] = 0x88;
	newChar[0] = 0x89;
  dataList.push_back( Data(0x004CC6F7, 1, oldChar, newChar) );
	char oldChar15[] = {0xA8, 0x8A, 0x4D, 0xA8, 0x88, 0x4D, 0xF4, 0x0F, 0xBE, 0x55, 0xFC, 0x0F, 0xBE, 0x45, 0xF4};
	char newChar15[] = {0xF4, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x8B, 0x55, 0xFC, 0x90, 0x8B, 0x45, 0xF4, 0x90};
	dataList.push_back( Data(0x004CC708, 15, oldChar15, newChar15) );
	char oldChar4[] = {0x0F, 0xBE, 0x45, 0xF4};
	char newChar4[] = {0x8B, 0x45, 0xF4, 0x90};
  dataList.push_back( Data(0x004CC735, 4, oldChar4, newChar4) );

	//section that starts the music
	oldChar[0] = 0x88;
	newChar[0] = 0x89;
  dataList.push_back( Data(0x004D4892, 1, oldChar, newChar) );
	oldChar4[0] = 0x0F; oldChar4[1] = 0xBE; oldChar4[2] = 0x45; oldChar4[3] = 0xF8;
	newChar4[0] = 0x8B; newChar4[1] = 0x45; newChar4[2] = 0xF8; newChar4[3] = 0x90;
  dataList.push_back( Data(0x004D489D, 4, oldChar4, newChar4) );

  patchList.push_back( Patch("Treat song entries as DWORD instead of BYTE", dataList) );
  dataList.clear();

Edited by Ascension64, 27 May 2009 - 06:02 AM.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#18 Taimon

Taimon
  • Member
  • 387 posts

Posted 27 May 2009 - 10:13 AM

Looks like I got confused and what I meant was the engine functions for starting and stopping a song takes the lower byte, which is treated as signed (look at the fifth test patch part near the bottom).

I see now. It's in the function where the area gets queried for the (combat?) song. Good catch.
(Really bad programming from the developers perspective. The maximum number of songs was a #define, and this would have cause a silent bug when they went over 127.)
I checked the rest of the function references and it seems like this is the only place where it's treated as a byte.

Nah, it's all cool. It's part of the TobEx utility still in development. So really, "you got there first".

I don't really care about those things. As you said elsewhere, it's all about solving problems. And now we solved it twice. :)
Let me know if you need some help with your tool. (With respect to reversing things.)

#19 Leomar

Leomar
  • Member
  • 1720 posts

Posted 28 May 2009 - 12:23 AM

Taimon, thanks a lot for your songlist.2da with 500 entries. Wow. :Bow:


Now, if someone could just add this as a useful part for the BGTMusic.exe so most of the custom songs are used...

Yes and it would be very nice, if we don't need to uninstall BGT-Music after the transition anymore.

Greetings Leomar

Edited by Leomar, 28 May 2009 - 12:23 AM.

A Megamod does not mean that you can play all of the mods or all of their content,
but you have more choices or paths through the game.
- Chevalier

BiG World Project - Big Baldur's Gate World

#20 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 28 May 2009 - 05:39 AM

I don't really care about those things. As you said elsewhere, it's all about solving problems. And now we solved it twice. :)
Let me know if you need some help with your tool. (With respect to reversing things.)

Just for kicks. :)
I'm sure I could use your help for a whole bunch of things. Two heads are better than one. But I haven't touched the thing for months.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)