Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

How to make a line break in Hexen ACS

Recommended Posts

I’m working with the author of Russian Doom to implement a Russian voiceover for Korax in Hexen with corresponding text when he appears at the start of each hub. Our translation of Korax’s first phrase in MAP27 (“ПРЕКЛОНИСЬ ПРЕДО МНОЙ И, МОЖЕТ БЫТЬ, Я БУДУ МИЛОСЕРДЕН”) is quite long, and we’d like to use a line break to make it fit nicely on-screen.


I tested this ingame. The problem arises here:


Hexen doesn’t seem to support


—it gives a “Bad V_DrawPatch” error when the text is supposed to appear ingame. How do we use a line break ingame without causing a crash? Or is there a better solution?

Edited by Nemrtvi

Share this post

Link to post
34 minutes ago, Kappes Buur said:

Which port and format are you mapping for?



Technically, I’m working with Russian Doom, which is based on Chocolate Doom and Crispy Doom. But it would be ideal for this to work on vanilla. I work on the vanilla Hexen ACS format.

Edited by Nemrtvi

Share this post

Link to post

Ah, vanilla Hexen, then try this



#include "common.acs"

//  =============================   1  ===

script 1 OPEN

//  =============================   END  ===




Share this post

Link to post

Does this help?

--- a/src/hexen/mn_menu.c
+++ b/src/hexen/mn_menu.c
@@ -348,9 +348,19 @@ void MN_DrTextA(const char *text, int x, int y)
     char c;
     patch_t *p;
+    short lineheight = -1;

     while ((c = *text++) != 0)
+        // [crispy] support line breaks
+        if (c == '\n')
+        {
+            y += lineheight + 1;
+            lineheight = -1;
+            x = 160 - MN_TextAWidth(text) / 2;
+        }
+        else
         if (c < 33)
             x += 5;
@@ -360,6 +370,12 @@ void MN_DrTextA(const char *text, int x, int y)
             p = W_CacheLumpNum(FontABaseLump + c - 33, PU_CACHE);
             V_DrawPatch(x, y, p);
             x += SHORT(p->width) - 1;
+            // [crispy] find the heighest character in the current text line
+            if (SHORT(p->height) > lineheight)
+            {
+                lineheight = SHORT(p->height);
+            }
@@ -405,7 +421,7 @@ int MN_TextAWidth(const char *text)
     patch_t *p;

     width = 0;
-    while ((c = *text++) != 0)
+    while ((c = *text++) != 0 && c != '\n') // [crispy] line ends at line break
         if (c < 33)


Share this post

Link to post

An alternative approach could be to separate both "lines" into two different print messages. Vanilla ACS does have the delay() instruction, right?

So a first print to display ПРЕКЛОНИСЬ ПРЕДО МНОЙ И, then a delay() that's timed to last about as long as the soundclip takes to say that, and then the print to display МОЖЕТ БЫТЬ, Я БУДУ МИЛОСЕРДЕН.

Share this post

Link to post

My example above was played with GZDoom Hexen (Hexen format). After all, who these days uses Hexen.exe?


I checked the original Hexen scripts, they used one liners separated by a delay of 2 seconds, just like Gez suggested. For example



ambientsound("KoraxVoiceGreetings", 127);
print(s:"ARE YOU READY TO DIE?");
ambientsound("KoraxVoiceReady", 127);


Depending on the screen resolution used, the text can be very small and hard to read.


My suggestion is to use GZDoom, either Hexen format or UDMF, where one can use HudMessage, a custom font and SetHudSize to tailor the text as needed




#include "zcommon.acs"

script 1 OPEN
SetFont (const:"LIQ");

//  void SetHudSize(int width, int height, bool statusbar);
SetHudSize(1280, 720, 0);

//  void HudMessage (text; HUDMSG_FADEOUT, int id, int color, fixed x, fixed y, fixed holdTime, fixed fadetime [, fixed alpha]);
HudMessage(s:"\cARealm of the \cDGreen\cA Soul\n";
HUDMSG_FADEOUT, 0, CR_TAN, 640.0, 375.0, 15.0, 3.0);

//  void HudMessage (text; HUDMSG_TYPEON, int id, int color, fixed x, fixed y, fixed holdTime, fixed typetime, fixed fadetime [, fixed alpha]);
hudmessage (s:"\n\n
You wake up in a strange place.\n
you have no idea where you are\n
or how you got there.\n\n
You want answers,\n\n
but it looks like that the only\n
way to find them is to go\n
thru this place.";
HUDMSG_TYPEON, 0, CR_TAN, 640.0, 475.0, 2.0, 0.05, 20.0);





just an example




But, in any case, good luck with your mod.

Share this post

Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now