Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Crimson Wizard

#481
Well, I'd like to see if this script solution would work for @Mehrdad. Also afaik @Wesley wanted to try Arabic translations in his game.

I wrote an experimental change for the engine already (found here), but I will postpone merging until it is more clear whether scripting solution works conveniently.
#482
How do you display these images exactly, in AGS terms? Why cannot you check whether *some* image is already displayed and remove it before displaying another one?
#483
Quote from: Snarky on Fri 14/04/2023 13:36:10
Quote from: Crimson Wizard on Fri 14/04/2023 12:43:52I guess you may try that, except you will have to then apply this everywhere throughout the game, for each existing string that may be wrapped:

Easily done with a few helper functions: DisplayRtl, SayRtl, DrawStringWrappedRtl, Label.SetTextRtl...
Yes, you might have to implement custom dialog options rendering, but again, this seems like an edge-case of an edge-case.

Well, then someone will have to help with these script functions, or write a module...

At least in case of a speech one would have to comply to the undocumented width calculations of the speech overlays. Or write completely custom speech to not depend on that.

Another thing to consider is that you will have to add these in your game if you even guess that it might have Arabic/Persian translation, because you cannot add these helper functions through the translation file itself. If the game was already done when you realized that you want such translation, then you'll have to edit all the text assignments and Say calls in script.
#484
Quote from: Snarky on Fri 14/04/2023 12:37:23
Quote from: Crimson Wizard on Fri 14/04/2023 12:30:42Afaik this is what Mehrdad is currently doing: he puts linebreaks himself, everywhere where necessary.

Right, that's the simple solution, but what I meant was that you could also just write a "reversed-pRTL" (pseudo-left-to-right) linebreak algorithm in script (measuring line widths from the end of the string, and reordering the lines so that the end of the string is at the top), rather than implement it in the engine.

I guess you may try that, except you will have to then apply this everywhere throughout the game, for each existing string that may be wrapped:
- when assigning a string to gui labels;
- when calling Display (and variants);
- when calling DrawingSurface.DrawTextWrapped.
- when displaying a speech (so have to write custom speech function);
- when displaying dialog options (so have to write custom dialog option rendering)

This will also make adding e.g. Arabic / Persian translations to existing games quite difficult.

Implementing this as an option to text wrapping algorithm would likely cover this case for the time being (again, I cannot tell when is the new font render estimate, and which new problems that would bring).

Quote from: Snarky on Fri 14/04/2023 12:37:23(Right-alignment as an option in more GUI Controls would be useful, but shouldn't be tied to a RTL setting.)

Controls have alignment setting, but it's not that, they do not reverse text, ever. I don't know why; this is either a regression in the new 3.* engine, or that RTL feature was never complete.
This won't be an issue with this converter solution though, as it does not need text reverse.

Actually, if we have the font render that can account for direction control chars, as eri0o mentioned, maybe we won't need RTL setting in the engine at all (rather than for backwards compatibility).
#485
Quote from: Snarky on Fri 14/04/2023 09:29:05So is it really worth it, or would it be better to devote that energy to a proper solution down the road?

Indeed, it would be better to aim a proper solution. The thing is, I don't know when this will be done, in which version etc, and at least few users already asked for this to work (and some been asking for years prior).

Before this whole conversation I was not fully aware of how RTL is stored internally normally, so I needed to test this out anyway.

In regards to the quick solution that I've been testing, so far it is this:
* expand the existing "Right to left mode", adding a new choice (Right-to-left reversed);
* if this option is on, then when doing text splitting scan the text from right to left.
* also set "alignment to right" as with normal RTL.
* everything else stays the same.

I spent 3-4 hours yesterday adding this option and testing things, but got stuck at the line splitting, because the algorithm is hardcoded for left-to-right scanning. So I wanted to look if I will be able to write a "generic" one instead.

Meanwhile, I also found and fixed 2 actual bugs in 3.6.0, so that was not a fully wasted time...


Quote from: Snarky on Fri 14/04/2023 09:29:05Is it possible that some of the inconveniences can even be solved in script without any engine changes, simply by reversing the strings, doing any manipulations on them (including, potentially, finding the linebreak points, reordering the lines and inserting explicit linebreaks), and re-reversing them? (Or not re-reversing them, in the case of some GUI Controls apparently.)

Afaik this is what Mehrdad is currently doing: he puts linebreaks himself, everywhere where necessary.

Another workaround, which I mentioned above, is to keep using this converter program, but turn off the option to "reverse" text during conversion. In this case it works in the game (with normal RTL setting), but it makes all the texts look reverse in script and translation file, obviously making it inconvenient to the user (I am unaware if human can normally read Arabic and Persian in reverse same way as e.g. English can be read in reverse).
#486
Quote from: eri0o on Fri 14/04/2023 01:23:14Just to try to understand, all the context of what you are talking here is ags3?

Yes, because it needs enhancing unicode feature to let use these certain languages properly; and because other solutions require major changes to the font rendering, to which we do not have any estimate yet.

Quote from: eri0o on Fri 14/04/2023 01:23:14Because on ags4 (we are unicode only there, right?) we could use a bidi library

The case I'm trying to resolve is the "incorrect" unicode RTL text, which is stored in memory in reverse way compared to what it should normally be (it does not have these direction control characters). Because of that it has to be drawn as if it were LTR, but wrapped differently.

The reason why this kind of text data is used is because our font renderer does not have a correct Arabic, Persian etc ligature support. So user is relying on special converter that generates a text represented by a different kind of data, meant to be displayed with very particular fonts (I mentioned this  in a comment above).
If the font renderer was drawing these languages correctly, with proper ligatures, then this converter hack would likely not even be necessary. The proper solution would require at least a replacement of a font renderer to something modern (I guess that's "Harfbuzz" that you mentioned). But until then users of these languages have to resolve to this hack, whether that is ags3 or ags4.

Currently I'm looking for the minimalistic solution to the problem, with as little changes as possible.
#487
The preliminary (unoptimized) version of "reverse RTL" solution code may be found here:
https://github.com/ivan-mogilko/ags-refactoring/tree/361--reversertl

It's unoptimized, because it does double text reverse when splitting (once before the split, and then second time after). I would have to somehow rewrite the splitting algorithm and make it capable of reading forwards and backwards...
#488
Also, I found something weird again; apparently there are gui controls that never reverse the text in RTL mode: Buttons and ListBoxes.

Basically, only text that supports wrapping does this: Labels, speech, display boxes.

I'm not sure if dialog options or drawing text on drawing surface does this... DrawTextWrapped probably does, since it wraps.

This is like that at least since AGS 3.2.1.
#489
Quote from: actaria on Thu 13/04/2023 22:34:37Perfectly working thank you didn"t know about the "always" thing

There's some information about these, and explains the difference:
https://adventuregamestudio.github.io/ags-manual/RepExec.html
#490
"Enter room before fade-in" is a correct event for initializing anything inside the room.

If there's a similar initialization or action that has to be done for a number of rooms, then use "on_event" with eEventEnterRoomBeforeFadein in the GlobalScript:
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_Event.html#on_event
#491
If you are going to have a lot of items picked up like that, I may also suggest to write a global function that does most things. This way you will be able to reduce code duplication - that is write the basic algorithm once, and then just call it with some parameters.

For example:
in GlobalScript.asc
Code: ags
function PickupObject(Object *obj, InventoryItem *itemToAdd, eDirection dirToFace)
{
    player.FaceDirection(dirToFace);
    player.LockView(3);
    player.Animate(0, 0, eOnce, eNoBlock);
    while (player.Animating)
    {
        if (player.Frame == SOME_FRAME)
            obj.Visible=false;
        Wait(1); // Wait lets engine to update and redraw the scene
    }
    player.UnlockView();
    player.AddInventory(itemToAdd);
}

in GlobalScript.ash (header)
Code: ags
import function PickupObject(Object *obj, InventoryItem *itemToAdd, eDirection dirToFace);

Then in the room script you may do this:
Code: ags
function oCacerolas_PickUp()
{
    player.Walk(1037, 938, eBlock, eWalkableAreas);
    PickupObject(oCacerolas, iCacerolas, eDirectionUpRight);
    player.Say("I've the pans with me!!!.");
}

function oAnotherObject_PickUp()
{
    player.Walk(1037, 938, eBlock, eWalkableAreas);
    PickupObject(oAnotherObject, iAnotherObject, eDirectionDown);
    player.Say("I got AnotherObject!");
}

You may add more parameters to this, or reuse existing ones for other purposes. For example, you may use dirToFace parameter to select an animation loop: this will let you to play different animations depending on which direction the character is facing.
#492
The solution is to run animation non-blocking and then wait until it finishes right in the same function.
If you will additionally check for the current frame, you will know when to do object changes.

Code: ags
cPerxeo.LockView(3);
cPerxeo.Animate(0, 0, eOnce, eNoBlock); // notice eNoBlock
while (cPerxeo.Animating)
{
    if (cPerxeo.Frame == SOME_FRAME)
        oCacerolas.Visible=false;
    Wait(1); // Wait lets engine to update and redraw the scene
}
cPerxeo.UnlockView();
player.AddInventory(iCacerolas);
cPerxeo.Say("I've the pans with me!!!.");

I also removed unnecessary LockView(1), and moved UnlockView right to where animation completes.

Note that if cPerxeo is a player character, you could just write player everywhere. This is recommended to do, in case something changes about the character, or you will have a game where player character may be switched for any reason.
#493
From the engine's perspective it will of course be desired that there's a minimal amount of settings and "types" of data, and most conversions were done by compilers. For example, if compiler could inverse the "reversed" RTL text before packaging the game.

But in our case this will either be impossible or difficult to achieve, as the game script is allowed to have strings in multiple languages, and scripting language allows to switch Text Direction at runtime (see SetGameOption(OPT_RIGHTTOLEFT)). This assumes that script strings may contain text of all kinds.

Resolving this at game compilation time would likely require a new preprocessor feature, using some kind of annotations added to the string literals. And that would definitely bring more issues with texts loaded from custom files.

Considering the above, the easiest option at the moment is to add a new mode to OPT_RIGHTTOLEFT, and fix all places where OPT_RIGHTTOLEFT has a meaning, accounting for this new mode.

I.e, OPT_RIGHTTOLEFT will be:
0 - normal LTR;
1 - normal RTL (that is - characters stored in the order of natural reading);
2 - pre-reversed RTL (that is - characters stored against the order of natural reading, and in order of how they are displayed left-to-right).

How the engine handles the new mode 2 is purely internal to the engine. If new font libraries are added later, which may somehow affect the situation, this behavior may be adjusted accordingly.
#495
I think what could work is another, thicker, object with Transparency set to 100.

According to AGS logic, Transparency does not affect interactivity, so even fully transparent objects will be clickable.
#496
Quote from: biverix on Tue 11/04/2023 19:47:30I'm running it on AGS 3.5.0 and everything seems to work fine, except the dialogues are broken.

Hello. The dialog API had changed since AGS 3.4.0 (which probably was after this template release), you need to either update the script to the new rules, or enable Backwards compatible mode called "Use old-style custom dialog options API".

More information may be found in the manual:
https://adventuregamestudio.github.io/ags-manual/CustomDialogOptions.html
check out where it sais "COMPATIBILITY NOTE"
#497
@Snarky, I did more actual tests and you are correct. When I copy a "proper" unicode RTL text into the editor, it's saved LTR, in other words, first "syntactical" character appears in Char[0], and rest follow. In other words, it only looks RTL when drawn in the application, but the data is LTR.

I did the test by simply printing Char[0] on a separate label.

What this means is, that if you print a "proper unicode" RTL text, then everything just works, so long as you set "Right-to-left" mode in the settings.

There's still a letter-linking problem, but that's an issue on its own.



The letter linking may be solved by a program called "Parsi Negar" that comes with its own fonts, suited for this particular purpose.
https://leomoon.com/downloads/desktop-apps/leomoon-parsinegar/
This is pointed out by @Mehrdad.

This program somehow converts the text. I am not 100% certain, but I think that it merges the linking letters into a single glyph with special number, and in combination with the special fonts it allows the Persian (and maybe Arabic?) text to be drawn visually correctly in AGS.

The problem with ParsiNegar is that by default it actually stores the text RTL, meaning its already reversed. This does not work with AGS linewrapping, neither LTR not RTL one.

I found that it's possible to workaround by disabling the "reverse" option in this program. If you do, then it seemingly works well in combination with AGS's RTL mode.
The nuance is that the text possibly looks "weird" in the script & translation file. I suspect that it will probably be hard to read by the native language speakers (as it looks literally reversed).

I am currently in the process of checking this out with Mehrdad on Discord. If he thinks that the workaround I found is not convenient for him, then the only option for us would be to introduce a 3rd selection to the "text direction" option, that would assume the text is only reverted in data.
#498
Updated again. There's a working solution. Can't tell if most optimal one, but it formally works.
Technical details are here: https://github.com/adventuregamestudio/ags/pull/1923#issuecomment-1502145700

May be downloaded and tested with this build (UPDATED 17th april):
https://cirrus-ci.com/task/4872943738552320

WARNING:
* Changes compiled game format and save format;
* Based on AGS 4 experimental version, which means that it will irreversibly update your game project too if you are coming from AGS 3.*. Better test on a project's copy.
* If you are already a AGS 4 user, this does NOT change the AGS 4 project format further, so it's safe to test on your real projects, except you'll have to fully rebuild if changing to a previous AGS 4; also the new engine will produce incompatible saves.
#499
EDIT: scrap this, I need to check something out when I have more spare time.
#500
So, the important question is, how the characters of these strings are positioned in char array.
SMF spam blocked by CleanTalk