ZScript Statusbar: draw a box centered on screen

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!)
User avatar
JPL
 
 
Posts: 523
Joined: Mon Apr 09, 2012 12:27 pm

ZScript Statusbar: draw a box centered on screen

Post by JPL »

Hi, I'm working on a mod with a Quests screen and some RPG/VN-style dialog boxes, and want to draw a box centered (with a margin) in the screen, that looks the same regardless of screen aspect or resolution. See the attached mockup images for an example (original and annotated) of what I'm going for.
Spoiler:
As a simplifying assumption, I'm restricting everything in the UI to a 4:3 subset of the window, so that I don't have to do anything different for wider aspects.
Most of my attempts have involved using flags like DI_SCREEN_CENTER, DI_SCREEN_LEFT_TOP etc. But any numbers I give it for offsets/scales from those points/corners drift into bogusness when I change resolutions and/or aspect. And yes I have played with the different Scaling Options, and am using the GZDoom defaults just for simplicity.
I can't think of a statusbar mod (including the one I made) that doesn't just draw everything anchored to a screen edge or corner, as opposed to centered in the screen. Has this been done in ZScript before? If so can anyone point me to existing examples?
You do not have the required permissions to view the files attached to this post.
User avatar
gwHero
Posts: 360
Joined: Mon May 08, 2017 3:23 am
Graphics Processor: Intel with Vulkan/Metal Support
Location: The Netherlands

Re: ZScript Statusbar: draw a box centered on screen

Post by gwHero »

Maybe this is what you could use to get started (I guess it's not the only way, but this is what I use):

Code: Select all

class ZEvents : EventHandler 
{	
	bool picloaded;
	TextureID pic;
	int w,h;

	override void WorldTick()	// PLAY scope
	{	
		if (!picloaded)
		{
			pic = TexMan.CheckForTexture ("PICTURE1", TexMan.Type_Any);
			picloaded = true;
		}		
			
		[w,h] = TexMan.GetSize(pic);	
	}

	// UI Scope: you cannot alter data here
	override void renderOverlay(RenderEvent e) 	// UI scope
	{	
		if (picloaded)
			Screen.DrawTexture(pic, false, 640 - w/2, 400 - h/2,
				DTA_VirtualWidth, 1280, DTA_VirtualHeight, 800);
	}
}
To hook on the events in this Zscript example class you have to declare this in Mapinfo:

gameinfo
{
AddEventHandlers = "ZEvents"
}

If this is not exactly what you want, Screen.DrawTexture has a lot of flags to change the behaviour (see GZDoom.pk3)
User avatar
JPL
 
 
Posts: 523
Joined: Mon Apr 09, 2012 12:27 pm

Re: ZScript Statusbar: draw a box centered on screen

Post by JPL »

I should've described my earlier attempts in greater detail; I started off using an EventHandler much like the one above, then moved things to a Statusbar to see if that gave me access to any extra drawing features (not really). I was familiar with the Screen API but it didn't seem as complete, and some folks on discord warned me off it. But I see you're using the DTA_VirtualWidth/Height arguments, which I didn't know about and that does exactly what I'm looking for (at the cost of ignoring the user's UI scaling settings and messily resampling everything that isn't an even multiple of the virtual resolution... damn). Why isn't there something like that for Statusbar?

One thing I notice is the Screen.DrawText function (different naming convention from Statusbar.DrawString, why?) doesn't allow a "wrapwidth" parameter, and I will definitely want to wrap text in this. Any idea how a Screen.DrawText-based UI would do this?
User avatar
gwHero
Posts: 360
Joined: Mon May 08, 2017 3:23 am
Graphics Processor: Intel with Vulkan/Metal Support
Location: The Netherlands

Re: ZScript Statusbar: draw a box centered on screen

Post by gwHero »

Now for me the situation is a bit different, since I'm mainly busy with a TC that's not a Doom mod, where a Doom statusbar is completely left away.

The main advantages of the Screen object is that it's total freedom; messing up with the gameplay is secured because of being restricted to UI scope. It's possible to comply to screen ratio's as well as not, it's all possible. In the end, the engine itself also uses the Screen object. The only thing that I miss at the moment is blending options for text, but maybe even that is possible, I'm not quite sure yet.

For text wrapping, just use the Breaklines function from the font:

Code: Select all

const MESSAGELINE_MAXPIXEL = 100;
BrokenLines lines = smallfont.BreakLines("message example if this text is too long it will be word wrapped", MESSAGELINE_MAXPIXEL);
for (int n = 0; n < lines.Count(); n++)
    Screen.drawText(smallfont, Font.CR_WHITE, 1, 1, lines[n]);
User avatar
JPL
 
 
Posts: 523
Joined: Mon Apr 09, 2012 12:27 pm

Re: ZScript Statusbar: draw a box centered on screen

Post by JPL »

gwHero wrote: For text wrapping, just use the Breaklines function from the font:

Code: Select all

const MESSAGELINE_MAXPIXEL = 100;
BrokenLines lines = smallfont.BreakLines("message example if this text is too long it will be word wrapped", MESSAGELINE_MAXPIXEL);
for (int n = 0; n < lines.Count(); n++)
    Screen.drawText(smallfont, Font.CR_WHITE, 1, 1, lines[n]);
Ahh, perfect, thank you. Wish I'd noticed this when I was reading through base.txt.

Return to “Scripting”