[ZScript] Apply offset automatically

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
User avatar
NightFright
Spotlight Team
Posts: 1382
Joined: Fri May 02, 2008 12:29 pm
Location: Germany

[ZScript] Apply offset automatically

Post by NightFright »

I'm looking for a more flexible option to be used in the Fullscreen Statusbar Mod in order to properly process widescreen statusbars.

Right now, one would have to manually add MD5 hashes of STBAR lumps wider than 320p in order to use a predefined set of graphics lumps which cut the statusbar accordingly. It would be much easier if the game did this dynamically. Therefore, I am wondering if the following can be realized via ZScript:

1) Check STBAR lump within a loaded wad for its dimensions (width, height)
2) Conditions for detected STBAR lump to be processed:
- Width must be > 320 (obviously)
- Height must be 32 (since there are also highres bars, e.g. in the Neural Upscale Pack, which need to be handled differently)
- Offset must be 0, 0 (otherwise it will be handled by the existing system for 320p images)
3) Calculate offset: (STBAR width - 320) / 2
4) Apply calculated offset to the STBAR lump (e.g.: 426x32 --> offset 53, 0)

Any insights would be highly appreciated.
Jarewill
 
 
Posts: 1853
Joined: Sun Jul 21, 2019 8:54 am

Re: [ZScript] Apply offset automatically

Post by Jarewill »

TexMan will help here:

Code: Select all

TextureID bar = TexMan.CheckForTexture("STBAR"); //Retrieve a pointer to the STBAR's TextureID
Vector2 barsize = TexMan.GetScaledSize(bar); //Get the size of STBAR
//Vector2 baroff = TexMan.GetScaledOffset(bar); //For some reason the 426x32 bar doesn't have an offset of (0,0) in game
If(barsize.x>320 && barsize.y==32){
	double xoff = (barsize.x-320)/2;
	DrawImage("STBAR", (xoff, -32), DI_ITEM_OFFSETS);
}
Now for whatever reason checking baroff==(0,0) didn't work with a 426x32 STBAR despite it having that offset, but it did work with a 320x32 one.
I have no clue what's going on behind the scenes with GetScaledOffset, so you might want to do a little bit more digging with it.
User avatar
NightFright
Spotlight Team
Posts: 1382
Joined: Fri May 02, 2008 12:29 pm
Location: Germany

Re: [ZScript] Apply offset automatically

Post by NightFright »

That's a start. Thing is, the STBAR lump isn't supposed to be drawn to the screen directly. It needs to be internally processed as a part of a composite texture (since transparency can be applied which will look bad if the STARMS lump is added later on).

We use textures such as HUD_DM (no STARMS) and HUD_SMP (STARMS added):

Code: Select all

Graphic "HUD_SMP", 320, 32
{
    	Patch "STBAR", 0, 0 { UseOffsets }
    	Patch "STARMS", 104, 0 { UseOffsets }
}
Graphic "HUD_DM", 320, 32 
{
    	Patch "STBAR", 0, 0 { UseOffsets }
}
In the non-split bar for example, they are utilized like this (from filter\game-doomchex\zscript\statusbars\unsplit.zs):

Code: Select all

if(deathmatch || teamplay)
	DrawImage(addArms(HUD_DM), (0, 0), DI_SCREEN_CENTER_BOTTOM, alphaFloat);
else
	DrawImage(addArms(HUD_SMP), (0, 0), DI_SCREEN_CENTER_BOTTOM, alphaFloat);
if(multiplayer)
	DrawImage("STFBANY", (-17, -32), DI_SCREEN_CENTER_BOTTOM|DI_ITEM_OFFSETS|DI_TRANSLATABLE, alphaFloat);
	
Any widescreen STBAR lump would need to have its offset set before these images are drawn - basically by the time the custom graphics lumps (HUD_DM/HUD_SMP and any others which utilize STBAR) are created.
User avatar
NightFright
Spotlight Team
Posts: 1382
Joined: Fri May 02, 2008 12:29 pm
Location: Germany

Re: [ZScript] Apply offset automatically

Post by NightFright »

So it seems I found a way to get it working. Offset checks were not needed in the end, as if've determined after some testing.
The coding may not be too elegant, but it's getting the job done. If you guys see a way to make this more efficient and shorter, don't hesitate to point it out...

Code: Select all

		// Determine which widescreen graphics to use
		TextureID bar   = TexMan.CheckForTexture("STBAR"); // Retrieve pointer to STBAR TextureID
		Vector2 barsize = TexMan.GetScaledSize(bar);       // Get STBAR size
		if (barsize.x > 320 && barsize.y == 32)
		{
    			switch(barsize.x)
			{
				case 426:
					HUD_SMP   = "HUD_SMP_WIDE426P";
					HUD_DM    = "HUD_DM_WIDE426P";
					HUD_LEFT  = "HUD_LEFT_WIDE426P";
					HUD_RIGHT = "HUD_RIGHT_WIDE426P";
					break;
				case 428:
					HUD_SMP   = "HUD_SMP_WIDE428P";
					HUD_DM    = "HUD_DM_WIDE428P";
					HUD_LEFT  = "HUD_LEFT_WIDE428P";
					HUD_RIGHT = "HUD_RIGHT_WIDE428P";
					break;
				case 430:
					HUD_SMP   = "HUD_SMP_WIDE430P";
					HUD_DM    = "HUD_DM_WIDE430P";
					HUD_LEFT  = "HUD_LEFT_WIDE430P";
					HUD_RIGHT = "HUD_RIGHT_WIDE430P";
					break;
				case 486:
					HUD_SMP   = "HUD_SMP_WIDE486P";
					HUD_DM    = "HUD_DM_WIDE486P";
					HUD_LEFT  = "HUD_LEFT_WIDE486P";
					HUD_RIGHT = "HUD_RIGHT_WIDE486P";
					break;
				case 574:
					HUD_SMP   = "HUD_SMP_WIDE574P";
					HUD_DM    = "HUD_DM_WIDE574P";
					HUD_LEFT  = "HUD_LEFT_WIDE574P";
					HUD_RIGHT = "HUD_RIGHT_WIDE574P";
					break;
				case 576:
					HUD_SMP   = "HUD_SMP_WIDE576P";
					HUD_DM    = "HUD_DM_WIDE576P";
					HUD_LEFT  = "HUD_LEFT_WIDE576P";
					HUD_RIGHT = "HUD_RIGHT_WIDE576P";
					break;
				case 900:
					HUD_SMP   = "HUD_SMP_WIDE900P";
					HUD_DM    = "HUD_DM_WIDE900P";
					HUD_LEFT  = "HUD_LEFT_WIDE900P";
					HUD_RIGHT = "HUD_RIGHT_WIDE900P";
					break;
				case 960:
					HUD_SMP   = "HUD_SMP_WIDE960P";
					HUD_DM    = "HUD_DM_WIDE960P";
					HUD_LEFT  = "HUD_LEFT_WIDE960P";
					HUD_RIGHT = "HUD_RIGHT_WIDE960P";
					break;
				case 1000:
					HUD_SMP   = "HUD_SMP_WIDE1000P";
					HUD_DM    = "HUD_DM_WIDE1000P";
					HUD_LEFT  = "HUD_LEFT_WIDE1000P";
					HUD_RIGHT = "HUD_RIGHT_WIDE1000P";
					break;
				case 1600:
					HUD_SMP   = "HUD_SMP_WIDE1600P";
					HUD_DM    = "HUD_DM_WIDE1600P";
					HUD_LEFT  = "HUD_LEFT_WIDE1600P";
					HUD_RIGHT = "HUD_RIGHT_WIDE1600P";
					break;
			}
		}
Jarewill
 
 
Posts: 1853
Joined: Sun Jul 21, 2019 8:54 am

Re: [ZScript] Apply offset automatically

Post by Jarewill »

What are HUD_X variables? Are they strings?
If so, you can combine strings to shorten the code:
HUD_SMP = "HUD_SMP_WIDE"..barsize.x.."P";
The end result of this will be "HUD_SMP_WIDE426P" if the X size is 426.
Of course it can also return invalid names if you don't have a texture with a specified size.
User avatar
NightFright
Spotlight Team
Posts: 1382
Joined: Fri May 02, 2008 12:29 pm
Location: Germany

Re: [ZScript] Apply offset automatically

Post by NightFright »

Yes, they are strings for the STBAR components.
I have tried this now, but apparently something's wrong since no graphics are used ingame:

Code: Select all

TextureID bar   = TexMan.CheckForTexture("STBAR");
vector2 barsize = TexMan.GetScaledSize(bar);
switch(barsize.x)
{
	case 426:
	case 428:
	case 430:
	case 486:
	case 574:
	case 576:
	case 900:
	case 960:
	case 1000:
	case 1600:
		HUD_SMP   = "HUD_SMP_WIDE"..barsize.x.."P";
		HUD_DM    = "HUD_DM_WIDE"..barsize.x.."P";
		HUD_LEFT  = "HUD_LEFT_WIDE"..barsize.x.."P";
		HUD_RIGHT = "HUD_RIGHT_WIDE"..barsize.x.."P";
		break;
	default:
		HUD_SMP   = "HUD_SMP";
		HUD_DM    = "HUD_DM";
		HUD_LEFT  = "HUD_LEFT";
		HUD_RIGHT = "HUD_RIGHT";
		break;
}
However, if I save barsize.x as an integer before and use that to connect the strings instead, it works:

Code: Select all

TextureID bar   = TexMan.CheckForTexture("STBAR");
vector2 barsize = TexMan.GetScaledSize(bar);
int barwidth    = barsize.x;
switch(barsize.x)
{
	case 426:
	[...]
	case 1600:
		HUD_SMP   = "HUD_SMP_WIDE"..barwidth.."P";
		HUD_DM    = "HUD_DM_WIDE"..barwidth.."P";
		HUD_LEFT  = "HUD_LEFT_WIDE"..barwidth.."P";
		HUD_RIGHT = "HUD_RIGHT_WIDE"..barwidth.."P";
		break;
	[...]
}
Post Reply

Return to “Scripting”