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

#3021
Quote from: Pajama Sam on Sat 23/04/2022 05:57:37
About return;. I'm new to it and the manual confuses me on that part.
To be clear.Return can make it go back to the beginning of the function.Am I
right?

Not to the beginning, but to outside. It returns to the place where you called it from and continues from there. It's the way to return some value, or skip the rest of the function and exit early.
#3022
Hmm, non-blocking functions are more complicated, because in this case whole animation simply cannot happen inside this function. Instead, you need to call it from "repeatedly_execute" using some timer between calls and condition that tells you that animation is going on. Also you have to store all parameters somewhere, in global variables, while overlay is animating.

To clarify:
1) if the animation is blocking, then whole animation, and its loop, may happen inside one function.
2) if the animation is non-blocking, then the function should only do one step, but be called repeatedly from somewhere else (for example, "repeatedly_execute" or other similar function).

The example of a blocking animation:
Spoiler

Code: ags

Overlay* animateoverlay_blocking(Overlay* selectedoverlay, int Xposition, int Yposition, int startsprite, int endsprite, int transparent, int delay)
{
    // loop while startsprite have not reached endsprite
    while (startsprite != endsprite)
    {
        // destroy previous and create new overlay with a new sprite
        if (selectedoverlay != null)
            selectedoverlay.Remove();
        selectedoverlay = Overlay.CreateGraphical(Xposition, Yposition, startsprite, transparent);
        Wait(delay); // wait some time
        startsprite++; // choose next sprite
    }
    return selectedoverlay;
}


This function may be used like:
Code: ags

    someoverlay = animateoverlay_blocking(someoverlay, 100 /*x*/, 50 /*y*/, 1 /*start sprite*/, 10 /*end sprite*/, true /*transparent*/, 5 /*delay*/);

[close]



For non-blocking animation you need to save the animation's information somewhere first, because it's going to be used repeatedly. If you have only 1 overlay animated at a time, then you just need few global vars to store these, but if you want to have a number of them animating simultaneously, then you need array of those vars. I also suggest creating a custom struct to group these variables.

Following is an example of single animated overlay, but it may be relatively easy expanded into multiple simultaneous overlays:
Code: ags

struct AnimatedOverlay
{
    Overlay *over;
    int x, y;
    int startsprite, endsprite;
    int delay;
    int timer;
    int transparent;
};

AnimatedOverlay animover; // single animated overlay

// This functions starts animation and save parameters
function animateoverlay_begin(int x, int y, int startsprite, int endsprite, int transparent, int delay)
{
    animover.x = x;
    animover.y = y;
    animover.startsprite = startsprite;
    animover.endsprite = endsprite;
    animover.transparent = transparent;
    animover.delay = delay;
    animover.timer = delay; // set timer to delay value
    
    if (animover.over != null)
        animover.over.Remove();
    animover.over = Overlay.CreateGraphical(x, y, startsprite, transparent);
}

// This function continues existing animation (or ends it)
function animateoverlay_step()
{
    if (animover.over == null)
        return; // not active
    
    animover.timer--; // countdown timer
    if (animover.timer > 0)
        return; // delay not finished yet

    // choose next sprite
    animover.startsprite++;
    if (animover.startsprite != animover.endsprite)
    {
        // destroy previous and create new overlay with a new sprite
        animover.over.Remove();
        animover.over = Overlay.CreateGraphical(Xposition, Yposition, startsprite, transparent);
        // start the delay again
        animover.timer = animover.delay;
    }
    else
    {
        // we're done here
        animover.over.Remove(); // optionally remove overlay...
        // if you like to keep it, then remove this command
    }
}


Then you need to place a call to animateoverlay_step() into "repeatedly_execute" (or room's RepExec event).
Code: ags

function repeatedly_execute()
{
    // if animated overlay exists, then do the step
    if (animover.over != null)
        animateoverlay_step();
}


The animation starts like
Code: ags

    animateoverlay_begin(100 /*x*/, 50 /*y*/, 1 /*start sprite*/, 10 /*end sprite*/, true /*transparent*/, 5 /*delay*/);
#3023
Quote from: Pajama Sam on Sat 23/04/2022 01:20:51
I was assuming that custom functions don't automatically loop.Do they?I haven't actually tested this yet where it gets past the errors so I don't know.I was trying to get it to loop until its finished animating from startsprite to endsprite.So I want the function to loop until a set condition.I did loop a function before but it was only one without any parameters.

Ah, okay, that explains your intent.

May you tell, why do you use Overlays for animation? Overlays have to be animated manually in script, but there's also GUI buttons that have Animate command that does everything for you.

If you're positive that you really must animate an overlay, first of all you got to decide if this function will be blocking or non-blocking as they have to be dealt with differently. Are you intending to call this function repeatedly from somewhere, or want the whole animation to happen inside the function, and then return to whatever place you called it?
Why do you pass Overlay pointer in it, does it have any meaning? Problem is, this pointer "selectedoverlay" will be considered a local variable in this function, and any changes to it will be lost as soon as the function ends.
#3024
What is it you are trying to do with CallRoomScript here, how is it related to animating the overlay?

CallRoomScript is called with 1 parameter: an integer number. You are placing a function call there instead, or so it seems. Are you trying to pass a return value from function animateoverlay into CallRoomScript? Or are you trying to call this function from within the room script?.... I am puzzled.

Also, I think you need to fix the order of the first two lines, like this:
Code: ags

if (selectedoverlay != null)
     selectedoverlay.Remove(); // remove previous overlay if it exists
selectedoverlay=Overlay.CreateGraphical(Xposition, Yposition, startsprite,transparent);


Otherwise your overlay will be removed right after creation.
#3025
Quote from: eri0o on Fri 22/04/2022 15:57:49But I don't know any library with similar functionality that is also cross platform, easy to port and has a license that is friendly to apple devices and consoles.

This functionality may be written by the engine developers too, if it becomes necessary.

My point was not to say the mojoAL is bad overall, my intent was to voice my concerns about openal's interface may not be ideal for the purposes of this engine and its possible future features.
It's not like we're using alot of openal api at the moment. MojoAL is reusing SDL2 audio, as you mentioned yourself, so it may be seen as a wrapper over SDL2 audio component with buffering and certain sound effects algorithms. I believe that in theory it is feasible to recreate this functionality in a different form.

It also could be that there are ways to solve the mentioned issue within OpenAL as well. I believe that it's worth investigating this question.
#3026
Quote from: eri0o on Fri 22/04/2022 15:21:55
I was answering CW, your approach of identifying HRTF in OpenAL spec is what I meant as the correct approach towards getting the feature in MojoAL.

Summary: there are no perfect libraries.

Sigh, I was in doubts to whom you were answering, so deleted my next reply.

The reply was this:

---

Quote from: eri0o on Fri 22/04/2022 10:38:44
About MojoAL it's better to not think of what it does and does not support, but if OpenAL supports it in some standard, and then notify the developer and figure how to support that if needed.

In my previous post I specifically mentioned "using OpenAL interface in general", not MojoAL. MojoAl's own problems is an issue on its own, but I was talking about using the OpenAL interface. I'm questioning the convenience of that interface in the context of AGS engine.
#3027
TBH I'm starting having doubts that using OpenAL interface in general is a good idea for AGS project. It came as a part of the SDL port done by Nick Sonneveld, and which we decided to use, and I trusted this choice; but the more i looked into it on my own, the more potential problems I saw. I think the biggest is that it's another layer of complexity which we cannot fully control. Good example is playback "Speed" property: it appeared OpenAL does not have a direct equivalent for it, so I had to implement it on top by resampling the sound data. The sound is "sped up" before passing into openal, but because we must buffer at least couple chunks of data there all time, there's a delay at which the "speed" parameter is applied to the output sound, and that delay depends on the size of this buffering. In Allegro4 it was applied for the very next played chunk perhaps at the very end of the data chain before it goes out to the sound driver, so almost immediately. I'm having concerns that situation may become worse if we decide to implement more sophisticated sound system in AGS script, with mixers, and so on.

Note that mojoAL uses SDL2 internally, which we also use directly in the engine, so the question to ponder is, what use is OpenAL for us, and how it will work in perspective.
If it's actually useful, perhaps there's a proper way to "extend" it ourselves and let us control the sound closer to the final output.

Personally, i used ffmpeg before and liked its "filter" design, where sound transformations may be applied freely at any stage of the data processing. Compared to that, OpenAL is a "black box" with everything which connects directly to the output.
#3028
Since 3.6.0 manual is not ready yet, there's another bit of information:

Historically, there were 2 kinds of overlays: those which were always above GUI (normal speech, Display() messages) and thise always below GUI (background speech and overlays created in script).
For compatibility reasons, in 3.6.0 overlays created in script have a very large negative ZOrder (-2 billion...). This should not be relied upon, as it's just the way to put them below any GUIs and keep original behavior. If you are arranging overlays among gui or among themselves, it's better to ignore initial value, and set explicit zorder yourself to all of them.
#3029
Quote from: vga256 on Thu 21/04/2022 23:47:17Although I spent some time browsing the ags github repo, I am not clear as to the progress made with the transition to SDL2 and OpenAL with 3.6.0. It *appears* from a glance that 3.6.0 is now using mojoAL for interfacing with OpenAL.

3.6.0 has fully transition to SDL2 and is using mojoAL for audio playback, which is an OpenAL interface and SDL2-based implementation.
The parts of Allegro library are embedded into the engine code now; these are parts related to bitmap manipulation (pixel drawing) and utf-8 handling.

Quote from: vga256 on Thu 21/04/2022 23:47:17
Question: Is it possible to write a plug-in for AGS that would enable some basic positional/3D audio functions that would allow run-time changes to audio during gameplay? I am working on a first-person adventure that would greatly benefit from this feature, and I'm willing to put in the wrench time to make it happen, if it is possible at all.

I don't think that's possible without changes in both engine and plugin API. Playback settings afaik are not exposed to plugin API in any way. Internally, in the engine playback does not have 3D settings. So even though the backend allows it, engine does not have this logic implemented anywhere.

AFAIK AGS supports sound stereo panning between left & right (see AudioChannel.Panning).
#3030
It has since 3.6.0 and it is called ZOrder, just like with GUI, and overlays are sorted among guis.
#3031
You have an option set in General Settings called "Override built-in inventory clicks in script", and it's enabled. But your script does have anything for inventory clicks in "on_mouse_click".

EDIT: you changed this setting few commits ago, in commit called "wheel o fortune".
#3032
In the above example you are importing a 32-bit sprite into 16-bit game, so it has to be converted to 16-bit, but you also choose "Leave as is", so the question is what would become to the transparency layer in this situation. I'd need to make a test myself to find out.
EDIT: I think it simply strips the alpha channel, so these transparent parts become solid color. For example, if you used color ARGB (0,0,0,0) in the paint program, then this becomes simply black.

For 16-bit games you should not be using transparency layers, but rather have a simple background of some color, which you would set as a transparent during import using "Top left"/"bottom left"/etc pixels.
#3033
Following code caught my eye:
Quote from: AndreasBlack on Wed 20/04/2022 21:02:39
Code: ags

//GlobalScript.ash

Timer *CharacterTimer;
Timer *Timers[100]; 


This is a classic mistake of placing variables in header without "import" keyword, and it makes variables to duplicate in every other script you have. Basically, you will have duplicates of variables, although with same name, in each script, and they will act separate from each other.

Correct global variable declaration
Code: ags

//GlobalScript.ash

import Timer *CharacterTimer;
import Timer *Timers[100];

Code: ags

//GlobalScript.asc

Timer *CharacterTimer;
Timer *Timers[100];
export CharacterTimer, Timers;


For more information please see:
https://github.com/adventuregamestudio/ags-manual/wiki/TheScriptHeader
https://github.com/adventuregamestudio/ags-manual/wiki/ImportingFunctionsAndVariables
#3034
Quote from: Cassiebsg on Wed 20/04/2022 16:52:14
Like CW said, set the import options to"use alpha channel" and "leave as is" and try again.

If the game is 16-bit, then importing with alpha channel does not make a lot of sense. For 16-bit it's best to use mask (transparent) color on source images.

I'm also not certain if "remap colors" option would work on non-8-bit images, i thought it should not make any difference.
#3035
Last time I checked couple of years ago, MonoAGS did not have a ready editor, and you had to program your games in C# in Visual Studio anyway.
#3036
Quote from: Hobbes on Wed 20/04/2022 02:56:48
I was wondering if there was a way in AGS to combine multiple views?

Usually this is done by combining multiple objects or characters together. See Character.FollowCharacter, alternative is to update positions of other "parts" in repeatedly_execute (or similar) to follow the main "body" character.

Quote from: Hobbes on Wed 20/04/2022 02:56:48
Or dynamically generate a sprite? Or recolour a given RGB value from a sprite/view?

Yes, see DynamicSprite and DrawingSurface articles:
https://github.com/adventuregamestudio/ags-manual/wiki/DynamicSprite
https://github.com/adventuregamestudio/ags-manual/wiki/DrawingSurface


EDIT: also, forgot to mention previously: it's not possible to generate Views, but it's possible to replace the frames:
Code: ags

ViewFrame* vf = Game.GetViewFrame(view, loop, frame);
vf.Graphic = NEW_SPRITE_NUM;
#3037
tilapisha, please tell:
* what is your game's color depth
* what are the sprite import settings that you use?

I think, if you have a 32-bit game and you load pngs with transparency layer, you should be having "use alpha channel" and "leave as is" as options.
Black color is a default transparent color in 8-bit palette games, I think, but idk if that is related.
#3038
Quote from: tilapisha on Wed 20/04/2022 01:30:56
So, Say command not SayBackground?

They do different things, Say is blocking, stops the character, and displayed in the chosen "speech style", SayBackground is non-blocking and is displayed always above the character as plain text (if i remember correctly). So they are not directly replaceable.

If you want a non-blocking speech that is displayed above GUI, then you need some custom solution that does not use these functions. One of them is showing a GUI with a label.

If blocking speech is fine, then of course simply use Say.
#3039
Quote from: tilapisha on Wed 20/04/2022 00:42:29
I'm using Sierra-style and Character.SayBackground, which from my understanding makes the character able to move while speaking and has nothing to do with actual back to front properties.

SayBackground creates a normal Overlay object, which by default is displayed behind all GUIs. The only overlays that are displayed above GUI are normal speech when using Say command and messages created with Display command.

If you're using AGS 3.6.0, you may write a custom function that creates background speech and adjusts it's ZOrder property to get on top of certain GUI (or all of them).

If not, or this looks like a bad solution, perhaps change something in GUI or speech design. For example: use GUI with a label for background speech, as you may arrange GUIs among themselves.


EDIT: on a separate note, is that a default status line from the template? It may be removed or moved elsewhere (to the bottom, etc).
#3040
Quote from: Pajama Sam on Wed 20/04/2022 01:03:47
Do the room backgrounds use the original file type or something else?

No, they are also converted to AGS internal format (it's a LZW compressed bitmap now).
SMF spam blocked by CleanTalk