Jump to content


Photo

Welcome to SHS!


  • Please log in to reply
32 replies to this topic

#1 Kaeloree

Kaeloree

    Head Molder

  • Administrator
  • 9198 posts

Posted 06 October 2008 - 10:28 PM

:cheers:

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

#2 Icendoan

Icendoan

    "An Infinite Deal of Nothing"

  • Member
  • 1723 posts

Posted 06 October 2008 - 10:38 PM

Congratulations!

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

Mods in development: Keeping Yoshimo

#3 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 07 October 2008 - 05:19 AM

Welcome!

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 ghostdog

ghostdog
  • Modder
  • 556 posts

Posted 07 October 2008 - 05:47 AM

Thanks guys !

@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 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 07 October 2008 - 06:04 AM

Are you modifying those on a byte-by-byte level? If so, and you're doing replacing rather than inserting, then my macros could work for you. However, they don't allow for insertion (because that would break the executable by messing up later offsets). But you could probably tweak it slightly to do that if you need it to.

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 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 07 October 2008 - 07:27 AM

Oh, forgot to mention, the Q_Loop business means that after it finds the search string and replaces it, it will continue searching from that point and keep replacing until it has done so Q_Loop number of times. So if you need to find and replace the -same- string 4 separate times, you set Q_Loop to 4. You do -need- to set Q_Loop to 0 if you're not using that feature (i.e. just doing a single replace).

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 ghostdog

ghostdog
  • Modder
  • 556 posts

Posted 07 October 2008 - 10:59 AM

Thanks Qwinn , that search pattern trick is really neat. It could make the tp2 much more compact, but I think I also want to know for what element each offset is, so I'm not sure if I'll try to implement it. (Nevermind the fact I'm a newbie with weidu)


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 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 07 October 2008 - 11:29 AM

Urf... okay, I'm trying to puzzle it out... can you give me an idea what it's doing in plain english?

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 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 07 October 2008 - 12:50 PM

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

#10 ghostdog

ghostdog
  • Modder
  • 556 posts

Posted 07 October 2008 - 01:11 PM

Actually I'm not really sure what the script does, it's made by taplonaplo. As soon as he gets my message I'm sure he'll come here and clarify this a bit.

#11 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 07 October 2008 - 01:50 PM

Oh, yikes.

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 ghostdog

ghostdog
  • Modder
  • 556 posts

Posted 07 October 2008 - 03:02 PM

Strange resolutions, are you using a laptop? Is there absolutely no resolution with a y-parameter at least 800 pixels?

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 taplonaplo

taplonaplo
  • Member
  • 90 posts

Posted 07 October 2008 - 03:13 PM

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

That is correct. The first part extends left (data starts from bottom left corner). The second loop extends top with the new width.
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 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 07 October 2008 - 03:17 PM

I'm using a Desktop NVidia 7600 GS video card with a Sharp LCDTV monitor. One of the really wide monitors, so not surprised it doesn't have a Y dimension over 800.

*shrug* *sigh*

Qwinn

#15 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 07 October 2008 - 03:27 PM

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

Edited by Qwinn, 07 October 2008 - 03:28 PM.


#16 taplonaplo

taplonaplo
  • Member
  • 90 posts

Posted 07 October 2008 - 04:17 PM

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

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.

#17 ghostdog

ghostdog
  • Modder
  • 556 posts

Posted 07 October 2008 - 04:44 PM

I'll put into my todo list a 1280x720 (16:9) version, it won't be that difficult to make.

#18 Kaeloree

Kaeloree

    Head Molder

  • Administrator
  • 9198 posts

Posted 07 October 2008 - 05:08 PM

Heh :D The closest my monitor supports is 1280x768. It's a bit ridiculous how close it is, and yet it won't work. More standardised screens would be nice. *grins*

#19 Qwinn

Qwinn
  • Modder
  • 3092 posts

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 Gelrof

Gelrof
  • Member
  • 31 posts

Posted 08 October 2008 - 06:10 AM

Is it possible to make it work with dimensions you put in during the install? (Like with the Widescreen Mod?)
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.