Welcome to SHS!
#1
Posted 06 October 2008 - 10:28 PM
Unfortunately my own monitor doesn't support 1280x800, but I'm sure the mod will be extremely appreciated to those who have! It looks fantastic--big cheers to ghostdog and Taplonaplo for putting it together, and I wish you the best of luck with future versions (and any future mods, as well)!
- Liam/K'aeloree
- Liam
Modding Projects
Complete:
Arath NPC - Nephele NPC - Xulaye NPC - Iylos NPC - Ninde NPC - Darian NPC - Yeslick NPC - Adrian NPC - Dace NPC - Valerie NPC - Isra NPC
Viconia Friendship - Mazzy Friendship - Imoen Friendship - Yoshimo Friendship - Sarevok Friendship - Neera Expansion
IEP Extended Banter
Sarevok Romance
Haer'Dalis Romance
In Progress:
Khadion NPC - Delainy NPC - Sarine NPC
#2
Posted 06 October 2008 - 10:38 PM
Icen
#3
Posted 07 October 2008 - 05:19 AM
Very happy to see this done... my new monitor does support 1200x800, but I couldn't get into using it precisely because of the issues addressed by this mod. Good luck with those remaining issues!
Wish you'd let me know you were this far along, actually... did you do a lot of engine patching? If so, I have a pretty nice mechanism for doing those set up. Let me know if that would still be useful to you.
Qwinn
#4
Posted 07 October 2008 - 05:47 AM
@Qwinn:
I'm glad to hear this mod will be useful to someone
For this mod, I've edited CHU and MOS files related to the UI , I've changed many offsets of the exe with the help of weidu and also a couple of .BAM and BMP files related to spells. Taplonaplo's storefix patches some DLG files and the transparency fix patches some mos files. What does your mechanism do? I could really use a fast way to edit BMP files, something like EXTEND_MOS but for bmp files, in order to edit the journal pics on the fly. Something like that would reduce dramatically the size of the mod. Taplonaplo has found a way but it takes a lot of time and makes the installation last about 10 minutes and I'd like to avoid such a big installation time.
#5
Posted 07 October 2008 - 06:04 AM
Here's the macros:
DEFINE_PATCH_MACRO ~Q_Engine_Patcher~ BEGIN SET i = 0 SET Q_SaveLoop = Q_Loop WHILE (i < 0x10001) BEGIN //search 0x10000 bytes from the starting point for our search pattern. SET offset = "Q_Starting_Offset" + "%i%" READ_ASCII "%offset%" pattern_current (%searchlength%) PATCH_IF ("%pattern_current%" STRING_EQUAL "%searchpattern%") THEN BEGIN INNER_PATCH_SAVE hexoffsetstring ~0x000000~ BEGIN SET hexoffset = offset + Q_Replace_Offset SET byte = hexoffset / 1048576 PATCH_IF byte < 10 BEGIN WRITE_BYTE 0x2 byte + 48 END PATCH_IF byte > 9 BEGIN WRITE_BYTE 0x2 byte + 55 END SET hexoffset = hexoffset - (byte * 1048576) SET byte = hexoffset / 65536 PATCH_IF byte < 10 BEGIN WRITE_BYTE 0x3 byte + 48 END PATCH_IF byte > 9 BEGIN WRITE_BYTE 0x3 byte + 55 END SET hexoffset = hexoffset - (byte * 65536) SET byte = hexoffset / 4096 PATCH_IF byte < 10 BEGIN WRITE_BYTE 0x4 byte + 48 END PATCH_IF byte > 9 BEGIN WRITE_BYTE 0x4 byte + 55 END SET hexoffset = hexoffset - (byte * 4096) SET byte = hexoffset / 256 PATCH_IF byte < 10 BEGIN WRITE_BYTE 0x5 byte + 48 END PATCH_IF byte > 9 BEGIN WRITE_BYTE 0x5 byte + 55 END SET hexoffset = hexoffset - (byte * 256) SET byte = hexoffset / 16 PATCH_IF byte < 10 BEGIN WRITE_BYTE 0x6 byte + 48 END PATCH_IF byte > 9 BEGIN WRITE_BYTE 0x6 byte + 55 END SET byte = hexoffset - (byte * 16) PATCH_IF byte < 10 BEGIN WRITE_BYTE 0x7 byte + 48 END PATCH_IF byte > 9 BEGIN WRITE_BYTE 0x7 byte + 55 END END WRITE_EVALUATED_ASCII ("%offset%" + "Q_Replace_Offset") "%replacepattern%" (%replacelength%) PATCH_IF Q_Loop = 0 BEGIN SET i = 0x10001 END ELSE BEGIN SET Q_Loop = Q_Loop - 1 END PATCH_PRINT ~%Q_Patch_Name%~ PATCH_PRINT ~Engine Patched at Offset: %hexoffsetstring%~ END SET i += 1 PATCH_IF ("%i%" = 0x10001) AND ( Q_SaveLoop = 0 OR Q_Loop > 0 ) BEGIN INNER_ACTION BEGIN FAIL ~No pattern for %Q_Patch_Name% found.~ END END END END DEFINE_PATCH_MACRO ~Q_Pattern_Maker~ BEGIN PATCH_IF searchlength > 0 BEGIN FOR (i = 0; i < searchlength; i += 1) BEGIN INNER_PATCH ~%searchbytes%~ BEGIN READ_BYTE ((i * 3) + 0) byte1 READ_BYTE ((i * 3) + 1) byte2 END INNER_PATCH_SAVE searchpattern ~%searchpattern%~ BEGIN PATCH_IF byte1 >= 48 AND byte1 <= 57 THEN BEGIN SET byte1 = (byte1 - 48) * 16 END ELSE BEGIN SET byte1 =(byte1 - 55) * 16 END PATCH_IF byte2 >= 48 AND byte2 <= 57 THEN BEGIN SET byte2 = (byte2 - 48) END ELSE BEGIN SET byte2 =(byte2 - 55) END SET byte = byte1 + byte2 WRITE_BYTE i byte END END END PATCH_IF replacelength > 0 BEGIN FOR (i = 0; i < replacelength; i += 1) BEGIN INNER_PATCH ~%replacebytes%~ BEGIN READ_BYTE ((i * 3) + 0) byte1 READ_BYTE ((i * 3) + 1) byte2 END INNER_PATCH_SAVE replacepattern ~%replacepattern%~ BEGIN PATCH_IF byte1 >= 48 AND byte1 <= 57 THEN BEGIN SET byte1 = (byte1 - 48) * 16 END ELSE BEGIN SET byte1 =(byte1 - 55) * 16 END PATCH_IF byte2 >= 48 AND byte2 <= 57 THEN BEGIN SET byte2 = (byte2 - 48) END ELSE BEGIN SET byte2 =(byte2 - 55) END SET byte = byte1 + byte2 WRITE_BYTE i byte END END END END
(Note that a big chunk of that first macro does nothing more than convert a decimal offset to hexadecimal for printout in the weidu log).
And here's a sample call to the macros:
SPRINT "Q_Patch_Name" ~4d. Make Morale functions use Maximum Morale + roll over fixes. Patch 9.~ // search: 88 82 27 07 00 00 8B 45 08 33 C9 8A 88 27 07 00 00 // replace: ?? ?? 5C 05 ?? ?? ?? ?? ?? 0F BE 88 5C 05 00 ?? 90 SET Q_Starting_Offset = 0xB9D00 SET Q_Replace_Offset = 2 SET searchlength = 17 SPRINT searchpattern ~12345678901234567~ SPRINT searchbytes ~88 82 27 07 00 00 8B 45 08 33 C9 8A 88 27 07 00 00~ SET replacelength = 15 SPRINT replacepattern ~123456789012345~ SPRINT replacebytes ~5C 05 00 00 8B 45 08 0F BE 88 5C 05 00 00 90~ LAUNCH_PATCH_MACRO Q_Pattern_Maker LAUNCH_PATCH_MACRO Q_Engine_Patcher
Note that the searchpattern and replacepattern are just strings of searchlength and replacelength lengths, respectively.
Q_ReplaceOffset is how many bytes (positive or negative) from where the searchbytes are found to place the replacebytes.
Q_StartingOffset is what byte location to start looking for the searchpattern in, so you don't have to search the whole file every time.
Summary: The Q_Pattern_Maker macro takes the searchbytes and replacebytes strings, and converts them to an actual sequence of the bytes in question (by replacing the bytes of searchpattern and replacepattern one byte at a time). Q_Engine_Patcher then looks for the searchpattern starting at the Q_StartingOffset, and writes the replacepattern at the offset where it found the searchpattern, plus the value of Q_Replace_Offset (which can be and often is negative).
Very simple to make it do different patterns based on whether you're using the 2CD or 4CD executable (which -are- different).
Qwinn
Edited by Qwinn, 07 October 2008 - 06:05 AM.
#6
Posted 07 October 2008 - 07:27 AM
You'd only want to use that feature if the 4 instances were relatively close together, otherwise it could take a long while to search from one occurrence to the next. If they -are- quite far apart, you'd probably be better off with a separate call with a Q_Starting_Offset closer to the location of the second occurrence. In my own Fixpack 3.0, there's two strings that need to be replaced 4 times each, and another 2 that need to be replaced 3 times each. They're close enough together - it takes about 6 seconds to do each set - but if they were much further apart than that I would've foregone the Q_Loop and just done 'em as separate replaces.
Qwinn
Edited by Qwinn, 07 October 2008 - 07:31 AM.
#7
Posted 07 October 2008 - 10:59 AM
Also, this is the script for resizing the journal .bmp pics, is there a way tweak it and make it faster?
COPY_EXISTING_REGEXP ~jr.*bmp~ ~override~ COPY_EXISTING ~default.bmp~ ~override~ ~image.bmp~ ~override~ ////////////// //replace here ////////////// SET xNew = "1280" SET yNew = "800" READ_LONG "0x02" FileSize READ_LONG "0x0a" DataOffset READ_LONG "0x12" Width READ_LONG "0x16" Height READ_SHORT "0x1c" BitCount READ_LONG "0x1e" Compression SET nWidth = (xNew - 640) / 2 + Width SET nHeight = (yNew - 480) / 2 + Height SET dWidth = nWidth - Width SET dHeight = nHeight - Height SET PixelStart = DataOffset PATCH_IF Compression = "0" AND BitCount= "24" AND dWidth >= "0" AND dHeight >= "0" THEN BEGIN //check if file is ok WRITE_LONG "0x02" FileSize + nWidth * nHeight * 3 - Width * Height * 3 WRITE_LONG "0x12" nWidth WRITE_LONG "0x16" nHeight FOR (k = 0; k < Height; k += 1) BEGIN INSERT_BYTES PixelStart dWidth * 3 FOR (l = 0; l < dWidth * 3; l +=3) BEGIN WRITE_BYTE (PixelStart + l + 1) "255" END SET PixelStart = PixelStart + nWidth * 3 + 1 END FOR (m = 0; m < dHeight; m +=1) BEGIN INSERT_BYTES PixelStart nWidth * 3 + 1 FOR (n = 0; n < nWidth * 3; n +=3) BEGIN WRITE_BYTE (PixelStart + n + 1) "255" END SET PixelStart = PixelStart + nWidth * 3 + 1 END END
Edited by ghostdog, 07 October 2008 - 11:01 AM.
#8
Posted 07 October 2008 - 11:29 AM
I get the impression it's something like this:
Original data:
01 02 03 04 05 06 07 08 09
New data;
01 02 FF 03 04 FF 05 06 FF 07 08 FF 09
Am I anywhere near the mark?
I do think I can figure out a way to streamline that once I grok what it's doing, yes. What's taking the time is those hundreds of file resizes via INSERT_BYTES, and I'm thinking there should be a way to just insert bytes once.
Qwinn
P.S. How many bytes per pixel? Sorry, I haven't worked with .bmp's much before.
Edited by Qwinn, 07 October 2008 - 11:31 AM.
#9
Posted 07 October 2008 - 12:50 PM
You seem to be creating a large section of "00 FF 00 00 FF 00 00 FF 00 etc." to the side of each image, yes? That's what the first loop seems to be doing, not sure what the second one is doing - is it creating the same above and below?
I can figure this all out, but pointing me in the right direction would save me a lot of time.
Qwinn
#10
Posted 07 October 2008 - 01:11 PM
#11
Posted 07 October 2008 - 01:50 PM
I can't use this mod
My display driver doesn't support 1280x800. I can only do these:
1360x768
1280x768
1280x720
1024x768
And a couple of lower resolutions.
Bummer It looked really good, and I would've liked to use it during my test run for Fixpack 3.0.
Qwinn
#12
Posted 07 October 2008 - 03:02 PM
anyway, about the bmp resize script:
If you still need some clarification:
You have to understand the bmp file format so the script can make sense (http://iesdp.gibberl...formats/bmp.htm). Note that this one ONLY work when extends top left, however other directions can be created easily too(right, bottom). I don't really understand how the pst bmps work as each pixel is written into 24 bits, from bottom left to right and iesdp has no such format, but this code seems to work (trial and error):SET xNew = "1280" //resolution set SET yNew = "800" READ_LONG "0x02" FileSize //reading some needed info READ_LONG "0x0a" DataOffset READ_LONG "0x12" Width READ_LONG "0x16" Height READ_SHORT "0x1c" BitCount READ_LONG "0x1e" Compression SET nWidth = (xNew - 640) / 2 + Width //flexible new dimensions SET nHeight = (yNew - 480) / 2 + Height SET dWidth = nWidth - Width //little helpers SET dHeight = nHeight - Height SET PixelStart = DataOffset PATCH_IF Compression = "0" AND BitCount= "24" AND dWidth >= "0" AND dHeight >= "0" THEN BEGIN //check if file is ok WRITE_LONG "0x02" FileSize + nWidth * nHeight * 3 - Width * Height * 3 //overwriting old file size to new (file size already contains the 441x281 image so it has to be substracted) WRITE_LONG "0x12" nWidth //writing new width/height WRITE_LONG "0x16" nHeight //begin extend left FOR (k = 0; k < Height; k += 1) BEGIN //for every row INSERT_BYTES PixelStart dWidth * 3 //extending bmp with black FOR (l = 0; l < dWidth * 3; l +=3) BEGIN //for every pixel created WRITE_BYTE (PixelStart + l + 1) "255" //rewriting 2nd value (green) to 255 END SET PixelStart = PixelStart + nWidth * 3 + 1 //getting to new line END //begin extend top FOR (m = 0; m < dHeight; m +=1) BEGIN //for every new row INSERT_BYTES PixelStart nWidth * 3 + 1 //insert bytes (i think this might be faulty here needs some testing with other resolutions) FOR (n = 0; n < nWidth * 3; n +=3) BEGIN //for every pixel created WRITE_BYTE (PixelStart + n + 1) "255" //set 2nd value (green) to 255 END SET PixelStart = PixelStart + nWidth * 3 + 1 //getting to new line END END
#13
Posted 07 October 2008 - 03:13 PM
That is correct. The first part extends left (data starts from bottom left corner). The second loop extends top with the new width.Okay, no, that's not what you were doing.
You seem to be creating a large section of "00 FF 00 00 FF 00 00 FF 00 etc." to the side of each image, yes? That's what the first loop seems to be doing, not sure what the second one is doing - is it creating the same above and below?
I can figure this all out, but pointing me in the right direction would save me a lot of time.
Qwinn
I used the bigg's area extending script (widescreen/libsmall/patch_bmp.tpa) as reference so you might want to check that out. I should have added that this only works when extending left and then top as it uses the first part to set the new starting place (it was only made for journal pics). The images seem to use 3byte/pixel as BGR(or RGB?).
Oh and another thing. it runs through the script even if dimensions are not changed...which should be fixed.
Edited by taplonaplo, 07 October 2008 - 03:19 PM.
#14
Posted 07 October 2008 - 03:17 PM
*shrug* *sigh*
Qwinn
#15
Posted 07 October 2008 - 03:27 PM
One possibility that may help - since all the journal pics should be the same size, shouldn't they all be being grown by the same amount? Picking out 3 at random, I note they're all 364k. They're probably all perfectly standardized in that respect. The approach I'd probably try is to read in a .bmp, read the data (all in one block, if it can handle one that size, smaller blocks if not), then write it all back out in intervals. Perhaps have a template expanded destination .bmp with all the data zeroed out except for your "00 FF 00" blocks already in place, and then copy the picture data from the source .BMP row by row into the blank areas in your destination template. No file resizing at all that way.
That make sense at all?
Qwinn
Edited by Qwinn, 07 October 2008 - 03:28 PM.
#16
Posted 07 October 2008 - 04:17 PM
If i understand it right, maybe. The file size is the same as theres no compression. Unfortunately i have no idea how it could be implemented in weidu, as my knowledge is rather lacking in that. A minor thing, the template should be created by the script so it may work on any resolution.Cool, thanks for the clarification. I'll look into the scripts and see if I can puzzle out a way to do it where you don't need to do so many file resizes. Will be tricky though.
One possibility that may help - since all the journal pics should be the same size, shouldn't they all be being grown by the same amount? Picking out 3 at random, I note they're all 364k. They're probably all perfectly standardized in that respect. The approach I'd probably try is to read in a .bmp, read the data (all in one block, if it can handle one that size, smaller blocks if not), then write it all back out in intervals. Perhaps have a template expanded destination .bmp with all the data zeroed out except for your "00 FF 00" blocks already in place, and then copy the picture data from the source .BMP row by row into the blank areas in your destination template. No file resizing at all that way.
That make sense at all?
Qwinn
#17
Posted 07 October 2008 - 04:44 PM
#18
Posted 07 October 2008 - 05:08 PM
- Liam
Modding Projects
Complete:
Arath NPC - Nephele NPC - Xulaye NPC - Iylos NPC - Ninde NPC - Darian NPC - Yeslick NPC - Adrian NPC - Dace NPC - Valerie NPC - Isra NPC
Viconia Friendship - Mazzy Friendship - Imoen Friendship - Yoshimo Friendship - Sarevok Friendship - Neera Expansion
IEP Extended Banter
Sarevok Romance
Haer'Dalis Romance
In Progress:
Khadion NPC - Delainy NPC - Sarine NPC
#19
Posted 08 October 2008 - 01:37 AM
If i understand it right, maybe. The file size is the same as theres no compression. Unfortunately i have no idea how it could be implemented in weidu, as my knowledge is rather lacking in that. A minor thing, the template should be created by the script so it may work on any resolution.
Hmmm. Give me a couple of days and I'll see if I can't whip up some weidu code that could do what I'm suggesting. Or at least enough of a template suggesting which weidu commands to use that you could take it from there.
Qwinn
#20
Posted 08 October 2008 - 06:10 AM
I am using 1440*900, which is one step higher on the resolution scale if I'm correct. I have no idea if this mod will work, but it should, only my screen will do a rescaling or show black borders. Not that that is a big issue, but still; the question remains.
Nice work though! A replay of PS:T is now more a question of when instead of if.