Page 1 of 2

[3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sat Feb 09, 2019 11:11 pm
by wildweasel
Mod download can be found in this thread: viewtopic.php?f=19&t=25836

While it can be argued that GZDoom has adopted features that render most of the methods in the mod obsolete, Project MSX hasn't been updated in a very long time - long enough that the changes to video scaling and screen resolution have broken its HUD. Meters and numbers still work, so the mod is at least playable, however, the (ACS-based) HUD cannot properly detect screen resolution, so the counter for hand grenades appears in a bunch of seemingly random places (dependent on how HUD Message scaling is set in the HUD Options), and any time the screen flashes for hits etc., errors appear on the message line, and the (also ACS-based) flashes do not cover the screen correctly.

I understand it may not be GZDoom's business to cater to this, since the methods used in the mod are old and outmoded. It could be argued that ACS HUDs never should have worked in the first place, to borrow a phrase that I'm sure some folks are tired of seeing. But since the original author isn't around to fix the mod...what do we do?

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 2:47 am
by Graf Zahl
Behold:

Code: Select all

//Widescreen code
//Original code by CommanderZ (from the RGA mod)
function bool is4to3(void){
   int w = GetScreenWidth();
   int h = GetScreenHeight();
   
   if(
      (w == 320 &&  h == 240) ||
      (w == 400 &&  h == 300) ||
      (w == 512 &&  h == 384) ||
      (w == 576 &&  h == 432) ||
      (w == 640 &&  h == 480) ||
       (w == 800 &&  h == 600) ||
       (w == 1024 &&  h == 768) ||
       (w == 1152 &&  h == 1280) ||
       (w == 1280 &&  h == 960) ||
       (w == 1400 &&  h == 1050) ||
	   (w == 1280 &&  h == 600) ||
	   (w == 640 &&  h == 400) ||
	   (w == 1152 &&  h == 864) ||
	   (w == 1280 &&  h == 1024) ||
	   //
	   (w == 320 &&  h == 200) ||
	   (w == 350 &&  h == 262) ||
	   (w == 400 &&  h == 640) ||
	   (w == 600 &&  h == 1280) ||
	   (w == 768 &&  h == 1280) ||
	   (w == 900 &&  h == 1440) ||
	   (w == 1050 &&  h == 1680) ||
	   (w == 384 &&  h == 512) ||
	   (w == 480 &&  h == 640) ||
	   (w == 600 &&  h == 800) ||
	   (w == 640 &&  h == 300) ||
	   (w == 720 &&  h == 1280) ||
	   (w == 900 &&  h == 1600) ||
	   (w == 1024 &&  h == 1280) ||
	   (w == 1080 &&  h == 1920) ||
	   (w == 320 &&  h == 256) ||
	   (w == 600 &&  h == 960) ||
	   (w == 640 &&  h == 400) ||
	   (w == 768 &&  h == 1024) ||
	   (w == 864 &&  h == 1152) ||
	   (w == 960 &&  h == 1280) ||
	   (w == 1050 &&  h == 1400)
   ){
      return true;
   }   
   return false;   
}

function bool is5to4(void){
   int w = GetScreenWidth();
   int h = GetScreenHeight();
   
   if(
      (w == 320 &&  h == 256) ||
      (w == 360 &&  h == 288) ||      
      (w == 720 &&  h == 576) ||
       (w == 1280 &&  h == 1024)
   ){
      return true;
   }   
   return false;   
}

function bool is16to9(void){
   int w = GetScreenWidth();
   int h = GetScreenHeight();
   
   if(                    
      (w == 1280 &&  h == 720) ||
       (w == 1024 &&  h == 576) ||
       (w == 1600 &&  h == 900) ||
       (w == 640 &&  h == 360) ||
       (w == 800 &&  h == 450) ||
       (w == 848 &&  h == 480) ||
       (w == 1024 &&  h == 576) ||
       (w == 1152 &&  h == 648) ||
       (w == 1280 &&  h == 720) ||
       (w == 1400 &&  h == 787) ||
       (w == 1769 &&  h == 992) ||
       (w == 1920 &&  h == 1080) ||
	   (w == 512 &&  h == 288) ||
	   (w == 1360 &&  h == 768) ||
	   (w == 1366 &&  h == 768) ||
	   (w == 400  &&  h == 225) ||
	   (w == 480  &&  h == 270) ||
	   (w == 576  &&  h == 324)
   ){
      return true;
   }   
   return false;   
}

function bool is16to10(void){
   int w = GetScreenWidth();
   int h = GetScreenHeight();
   
   if(
      (w == 360 &&  h == 240) ||
      (w == 400 &&  h == 256) ||
      (w == 720 &&  h == 480) ||
       (w == 1600 &&  h == 1024) ||
       (w == 1680 &&  h == 1050) ||
       (w == 1280 &&  h == 800) ||
       (w == 800 &&  h == 500) ||
       (w == 1024 &&  h == 640) ||
       (w == 1152 &&  h == 720) ||
       (w == 1280 &&  h == 768) ||
       (w == 1400 &&  h == 875) ||
       (w == 1920 && h == 1200) ||
	   (w == 1440 && h == 900) ||
	   (w == 1152 && h == 720) ||
	   (w == 360 && h == 225) ||
	   (w == 640 && h == 384) ||
	   (w == 420 && h == 262) ||
	   (w == 480 && h == 300) ||
	   (w == 960&& h == 600)
   ){
      return true;
   }   
   return false;   
}
Sorry, but how am I supposed to fix such shortsighted coding?

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 2:51 am
by Rachael
How is GetScreenWidth() and GetScreenHeight() even accessible from any mod?

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 2:53 am
by Graf Zahl
You have to ask Randi for that. This has been in ACS for a looooong time.

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 6:56 am
by Korell
As an idea, and only really a custom fix to the mod itself, you could strip out all of those screen resolution checks from that ACS and simply return true for the aspect ratio you are using and false for all the others, basically hardcoding the aspect ratio. I suppose you could then take it a step further and store a custom menu item variable for the aspect ratio for the mod and check the value of it. This might fix the positioning issue, though I don't know if this would also fix the messages and screen flashing.

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 7:02 am
by Graf Zahl
Surely this can be fixed in the mod. But WW was asking for an engine side fix - which with all these and probably more such checks is pretty much hopeless.
This thing was basically broken by design, the only reason that nobody noticed is that its maker explicitly checked for all screen sizes that were in use as of its making. Just too bad that such lists rarely remain static. This would even have broken on some more recent displays without the changes to the screen size handling.

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 5:38 pm
by Korell
For me, as I'm using a 1920x1080 monitor I don't get the issues that wildweasel has described as my resolution is catered for within that ACS code. Looking at the rest of the script, the HUD flashes all call the function "drawStretchedImage" which has checks for the aspect ratio defined in the code extract above, and if it isn't a screen resolution that it caters for then it gives an error message. So it all seems to be due to this check. I don't know the correct way to rework the ACS code (I've extremely little experience in Doom modding, having only done some basic fixes to a couple of mods here and there) but being as it is able to capture the width and height into variables w and h, I could try stripping out all of those isXtoY functions and replacing them with something that just stores the values of w and h, then all other calls to the isXtoY functions would need the calls stripping out and the hardcoded values for each instance replaced with w and h. I believe that this would then scale the images to the full screen regardless of the aspect ratio, but ultrawidescreen resolutions would give very stretched images. Would the scaling factor also work if it was played windowed, though? Do the values of GetScreenWidth() and GetScreenHeight() change if played in a window? This way it could still be played windowed for users of ultrawidescreen monitors or multiple screens.

On another note, I did notice that the standard enemy marines (Grunts) cannot shoot downards. Also, the MSX Hellknights also have one particular attack (named Tripleshot) that goes upwards instead of downwards.It appears to be due to the use of CMF_OFFSETPITCH, which after a quick search appears to be a known and now closed bug with 3.7.2, so hopefully will be fixed in the next GZDoom release: viewtopic.php?f=7&t=63439

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 5:49 pm
by Rachael
To get the aspect ratio it's very simple: For all aspect ratios other than 21:9 (which is actually something else, I don't remember completely) it's a simple w/h division. So 1920x1080 is 1920/1080 which reduced equals 16/9 - matching the 16:9 aspect ratio. 1024x768 is 1024/768 which reduces down to 4/3. See where I am going with this?

A small exception is 1360x768, which is technically a 16:9 aspect ratio but is not a perfect division.

Still - the mod should not care what screen resolution you have. Instead, it should just dynamically account for the screen resolution no matter what it is, and simply apply stretching dynamically based on that.

If it really matters to this mod that much you can always do a simple "vid_setscale 1920 1080" to at least get the mod to run.

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 6:04 pm
by Korell
Rachael wrote:To get the aspect ratio it's very simple: For all aspect ratios other than 21:9 (which is actually something else, I don't remember completely) it's a simple w/h division. So 1920x1080 is 1920/1080 which reduced equals 16/9 - matching the 16:9 aspect ratio. 1024x768 is 1024/768 which reduces down to 4/3. See where I am going with this?
Yep, this is what I was trying to explain (badly) by using the values of w and h instead of the hardcoded ones for each case.
Rachael wrote:Still - the mod should not care what screen resolution you have. Instead, it should just dynamically account for the screen resolution no matter what it is, and simply apply stretching dynamically based on that.
Agreed, which is why I'm hoping a fix can be put together. However, whilst I've carried out the first part of the fix, which is all the image stretching, there is something that I don't understand in the rest of the code. He uses a function named gethudratiodiff that stores a different value for diff based on the aspect ratio. I can't see how the values have been ascertained, however. 4:3 and 5:4 have diff = 0, 16:9 has diff = 117 and 16:10 has diff = 67. From where this function is called it seems to be something to do with the sizes or positions of the HUD elements such as the health and shield bars as it passes the value through to hdif which is used in the code of these HUD elements, but some subtract it and others add it. So I may not be able to fix this after all.
Rachael wrote:If it really matters to this mod that much you can always do a simple "vid_setscale 1920 1080" to at least get the mod to run.
This may have to be the case.

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 6:09 pm
by Rachael
My guess is diff is calculated this way:

diff = ((w/h) - (320/240)) * 320

Not positive about that, but give it a shot and see what happens.

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 6:15 pm
by Rachael
If it doesn't work because of the calculation being integral, as I suspect with ACS, try converting the formula to fixed point:

diff = (((w * 65536)/h) - (320 * 65536/240)) * 320 / 65536

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 6:18 pm
by Korell
Rachael wrote:My guess is diff is calculated this way:

diff = ((w/h) - (320/240)) * 320

Not positive about that, but give it a shot and see what happens.
1920x1080 screen resolution would then give:
((1920/1080) - (320/240)) * 320 = 1280/9, so this doesn't give the value he's using for this aspect ratio. I just can't see what he's doing here.

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 6:32 pm
by Rachael
Hmm.. try this...

diff = w * 240 / h - 320

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Sun Feb 10, 2019 7:44 pm
by rollingcrow
I modified CommanderZ's code to support more resolutions in a slightly less hardcoded way awhile back, though I don't know how easily this could be adapted into something usable by Project MSX. It should support any(?) 4:3, 16:9, 16:10, or 17:10 resolution.

Code: Select all

/*
	Heavily modified version of CommanderZ's old widescreen HUDMessage script.
	Now supports any supported aspect ratio rather than hardcoded resolutions.
*/ 

int res4to3 = 1.33333333333;
//int res5to4 = 1.25;
int res16to9a = 1.77777777778;
int res16to9b = 1.77864583; // For 1366x768
int res16to10 = 1.6;
int res17to10 = 1.7;

function void HudMessageStr(int type, int id, int imageWidth, int imageHeight, int time, int fadeTime, int alpha)
{ 
	int hudScreenWidth = imageHeight * 4 / 3 * imageWidth / imageHeight;
	int hudScreenHeight = imageHeight;

	if ((FixedDiv(GetScreenWidth(), GetScreenHeight())) == res4to3)
	{
		hudScreenWidth = hudScreenWidth / 4 * 3;
	}

	/*
	if ((FixedDiv(GetScreenWidth(), GetScreenHeight())) == res5to4)
	{
		hudScreenWidth = hudScreenWidth / 5 * 4;
		Log(s:"Sorry, unsupported resolution!");
	}
	*/

	else if ((FixedDiv(GetScreenWidth(), GetScreenHeight())) == res16to9a)
	{
		hudScreenWidth = hudScreenWidth / 16 * 9;
	}
	
	else if ((FixedDiv(GetScreenWidth(), GetScreenHeight())) == res16to9b)
	{
		hudScreenWidth = hudScreenWidth / 16 * 9;
	}

	else if ((FixedDiv(GetScreenWidth(), GetScreenHeight())) == res16to10)
	{
		hudScreenWidth = hudScreenWidth / 16 * 10;
	}

	else if ((FixedDiv(GetScreenWidth(), GetScreenHeight())) == res17to10)
	{
		hudScreenWidth = hudScreenWidth / 17 * 10;
	}

	else
	{
		Log(s:"Sorry, unsupported resolution!");
	}	

	// ---
   
	SetHudSize(hudScreenWidth, hudScreenHeight, 1);
	HudMessage(s:"a"; type, id, CR_Untranslated, (hudScreenWidth / 2) * 65536, (hudScreenHeight / 2) * 65536, time, fadeTime, alpha);
}
Sample use:

Code: Select all

Script "PlayerFatigue" ENTER
{
	SetFont("BlkVig");
	
	if (CheckInventory("Fatigue") <= 10000)
	{
		HudMessageStr(HUDMSG_ALPHA | HUDMSG_FADEOUT | HUDMSG_LAYER_UNDERHUD | HUDMSG_NOTWITHFULLMAP, 101, 1920, 1080, 0.0, 1.0, 1.0);
	}

   // snip
}

Re: [3.7.2] Video scaling/res refactor broke Project MSX

Posted: Mon Feb 11, 2019 1:29 am
by Graf Zahl
Se7eNytes wrote:I modified CommanderZ's code to support more resolutions in a slightly less hardcoded way awhile back, though I don't know how easily this could be adapted into something usable by Project MSX. It should support any(?) 4:3, 16:9, 16:10, or 17:10 resolution.

The main problem here still is that with arbitrary window sizes any assumption about aspect ratios is bogus by default.
Of course with ACS providing little to no help with placing content it will be a bit hard to do this right.