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 - Scorpiorus

#41
Hmm... It seems like by painting sprites onto that transparent intermediate helper bitmap we would lose translucency levels of sprites (trans param) specified when calling several IAGSEngine::BlitSpriteTranslucent() for a single screen frame anyway.
And to save translucency info for each painted sprite (fur further blitting by GPU) we'd have to embed translucency (on a per-pixel-basis) into that intermediate bitmap data as alpha values?...
...because getting an alpha channel info from the original sprites won't help much, since it's a static translucency but IAGSEngine::BlitSpriteTranslucent() can be used to draw the same sprite multiple times with different trans values?

I'd like to look into it but I don't have the AGS Engine 3.4.1 build ready at the moment (simple build command doesn't work anymore since the external libs were separated from the AGS branch and I'd have to add them back to build the engine). I'll see if I can do it.
#42
Quote from: Crimson Wizard on Tue 02/05/2017 15:44:38
I found that when the plugin's onEvent callback is called for rendering stage, the first parameter is the event type, and the second parameter is a pointer to IDirect3DDevice9 interface. Unfortunately, the callback argument is 32-bit integer, so that won't work if engine is compiled as 64-bit program.
And another practical issue with using the IDirect3DDevice9 interface directly by plugins is that plugins then may have to create their own texture resources. And since AGS introduces an abstract concept/layer of DriverDependantBitmap where with Direct3D9, for instance, it may actually be represented by several tiled textures of specific format (current internal implementation and hence is always a subject to change), plugins should carefully manage their own textures to be consistent with the engine's strategy and method of drawing. At the very least repeating engine's work on checking video hardware capabilities (like texture size, format, etc...) and, probably, even applying similar workarounds if necessary.
Otherwise, a game may fail to run on certain video hardware because of some Direct3D plugin, but would work perfectly in Direct3D mode without that plugin.
Also, things like AGS FlipScreen()-enabled rendering etc... may be a problem to support at such a low level.

QuoteI researched this a bit more, and plugin callbacks are already structured better than I initially thought.
When AGS creates a drawing list it pushes special items there, which indicate a plugin event. When it does all the rendering, and meets such item, it calls plugin callback instead.
Yeah, and I actually abused that NullSpriteCallback entry from within the plugin as a point from which to make a bunch of extra calls into private D3DGraphicsDriver::_renderSprite() to draw particles.

QuoteI've got results, but messy results, because apparently there is no direct way to know whether plugin has drawn anything on it. I guess we could try to set a flag whenever one of the drawing API functions is called (like GetVirtualScreen, BlitSpriteTranslucent, and so on).

As for the speed, it seems okay. I do not think this will be slower than software drawing anyway.
Would be really great if the speed is acceptable, and yeah some sort of a flag to optimize things seems like a good idea.
#43
The plugin basically starts from the engine API instance and browses through engine internals, like objects' vtables and code, to try and find all the required functions and data needed to perform drawing.
It can stand minor code changes or EXE-image re-basing (like ASLR - Address Space Layout Randomization) to a certain degree but of course will eventually fail as more and more code changes are made.
Again, its main purpose was to support previous set of AGS versions so that I wouldn't have to hardcode it for every single version of the engine that has been released.
My original idea was to only unlock plugin support for each new AGS version after I've thoroughly tested that plugin works with it correctly, and use standard AGS engine API Blit-family functions as a fallback (meaning nothing will actually be drawn until it's fixed).

So, while technically it is possible to keep the plugin working with even newer versions of AGS and still using such tricks, I'd better switch to something officially supported as soon as possible, and I'm really glad you are considering fixing Blit functions for 3.4.1 -- and to be honest that's what I was hopping for, since, yeah, changing graphic modes at run-time is a significant change and I'm sharing your concerns regarding the need to notify plugins somehow (as they may have their own resources allocated separately from the AGS graphics lists/caches, etc).


Oh, and I always wanted to say that before...

Crimson Wizard, I'd like to thank you for all the hard work, time and effort you dedicate to support AGS Community! And of course all other AGS developers contributing to it to keep AGS a wonderful game creation system! You've been doing a great work! Thanks!
#44
Quote from: Crimson Wizard on Sun 23/04/2017 13:40:59
Does it still make sense to implement any of the engine solutions I've mentioned above?
Definitely! The current solution I used is rather tricky and is more meant for previous versions of AGS, but for future AGS versions it would be very important to switch to something native.
To be honest, I'm not even sure how the plugin would work with the upcoming AGS 3.4.1 since there is a lot of graphics handling changes in there. Not to count that the OpenGL mode may become officially supported in the future.

I'd also like to release the plugin source codes, but before I do that, I have to remove all the dirty hacks I used to get to the AGS engine graphics driver!

Quote from: Mehrdad on Sun 23/04/2017 14:53:27
Thanks a lot . I have Win 10 and seems work perfect
Good to know, thanks for testing it out!
I tried running it on Windows XP SP3 32-bit and it seems to work fine there too.


Meanwhile, I've made a couple of small fixes to the current ALPHA. But mainly changed the SnowRainDemo game to run in D3D9 mode by default:
Snow/Rain 3.0.0-ALPHA-2: See first post for DOWNLOAD links!
#45
Sorry guys, so here is the first ***very-ALPHA*** version of the Snow/Rain plugin to hopefully support Direct3D 9 mode to certain extent:

Snow/Rain 3.0.0-ALPHA-1: See first post for DOWNLOAD links!

For now, it runs only with AGS version 3.4.0 - Patch 4 and only in Direct3D 9 mode.
That's deliberate, to focus on testing the EXTREMELY hackish way of accessing the AGS D3D9 Driver.

I only tried running it on Windows 7 SP1 64-bit, so see if it works with other OS versions.

And if the plugin crashes, please let me know your Windows OS version and if it's 32 or 64-bit.

Good-old Snow/Rain Demo included to assist testing.
#46
Ah ok, I see. Thanks for looking into it and clarifying the problem.

Ironically, the snow/rain plugin, for instance, wouldn't work, even if BlitSpriteTranslucent() supported D3D drawing because it calls IAGSEngine::GetVirtualScreen() for no apparent reason (probably a leftover from the original "ags_template.cpp" example file), which triggers the "plugin doesn't support Direct3D driver" error message.

QuoteI was thinking that maybe there could be a way to similarily create a drawing chain entry for Direct3D/OpenGL mode instead of using draw_trans_sprite directly in the BlitSpriteTranslucent. But I need to make sure I am using correct test first. Can you upload your test game somewhere?
Unfortunately, I haven't saved that quick test game. I have a habit deleting them ASAP, otherwise I end up cluttering my AGS folder with "asdasdasds"-kind of projects.
But basically it was a simple AGS 3.4.0 Patch 2 "Default Game" template game with whatever version of the snow/rain plugin and the following code...
Code: ags

srSetSnowDefaultView(int view, int loop); // some roger walking view/loop or whatever
srSetSnowTransparency(50, 50); // ~50% opacity/transparency
srSetSnowAmount(1000); // set max number of flakes

... in room's "after fadein" event.

I actually use snow/rain's SnowDemo bundled with the plugin but that's only for AGS 2.72 tests (http://americangirlscouts.org/agsresources/AGS%20resources/plugins/ags_snowrain202.zip).

QuoteLooking from the engine's viewpoint, I can see two solutions, or rather two ways to improve that may be complementary:
Quote1) Make functions like BlitSpriteTranslucent (and all of their variants) work in Direct3D mode. Plugin can call them from any of its callbacks, which means engine would require a viewport-sized bitmap for each such callback, that would then be transformed into driver-dependent drawing chain entries and inserted into the render chain at corresponding z-orders.
This means, if I get it right, updating D3D texture buffer on-the-fly by uploading large bitmaps with already-"flattened" sprites on them for each callback every game loop into the video hardware?
We have several drawing callbacks, I don't really know how much slower that would be in terms of resulting Frames Per Second, since, yeah, video hardware likes having its resources nearby to perform at its best.

But the good thing with this is that it's a constant number of bitmaps no matter how many sprites/particles we draw and so, we won't hit the drawing-list/scene-graph limits on the max number of entries. This is a specific problem of particle system plugins that draw tons of little images. The snow/rain plugin, for instance, can draw up to 2000 sprites but that is an arbitrary limit.

So if it's not *too* slow, I think that would be the best compromise/compatibility solution for particle system (and other similar effects) plugins for the current moment.

Quote2) Add new plugin API for managing custom "screen sprite entities", that are created by passing bitmap, but internally converted into driver-dependant bitmaps, and could be told to be drawn at certain z-order (sprite layer) in the chain. In such case the transformation of raw bitmap into D3D texture will occur only at sprite creation, and therefore whole process will be much faster.
Yeah, that's more video hardware-friendly but also seems more envolved to implement as it requires some new special entities to add and new engine API functionality to expose and support in the future. TBH I'm not really sure about expanding the current version (AGS_PluginV2) of the engine API at all. And again for particle system plugins it should then support large amounts of objects (though probably sharing most of the graphics).



Ideally, it would be cool to draw and blit inside the video hardware with some special shader program (if possible/supported by HW) where even AGS script raw draw commands (not only for blitting images but also for drawing lines/rectangles/etc) could be passed to the shader program to perform. That's of course a lot of work and testing - I understand - and it's out of the question for the near future.
#47
Ah, I tried BlitSpriteTranslucent() but it didn't work in Direct3D for some reason (nothing was drawn).

That would be ideal solution... I'll look into it further and let you know then, thanks!

EDIT:

Ok, unfortunately I can't download from mediafire but I've just compiled it from: https://github.com/adventuregamestudio/ags/tree/master/Plugins/ags_snowrain
But it didn't work in Direct3D here -- again no particles drawn (setting a quick test game and trying with ACI 3.4.0.14). DirectDraw mode works fine. That's rather odd...

EDIT:

Also, I've just found some strange lines in the master source regarding BlitSpriteTranslucent().

https://github.com/adventuregamestudio/ags/blob/master/Engine/plugin/agsplugin.cpp#L330

Code: ags

void IAGSEngine::BlitSpriteTranslucent(int32 x, int32 y, BITMAP *bmp, int32 trans) {
    set_trans_blender(0, 0, 0, trans);
    Common::Bitmap *ds = ::GetVirtualScreen();
    // FIXME: call corresponding Graphics Blit
	draw_trans_sprite(ds->GetAllegroBitmap(), bmp, x, y);
}


At first glance it seems like it calls some allegro functions at the moment?






EDIT:
btw that's totally ridiculous but I've just found out that I definitely used BlitSpriteTranslucent() even in the original 2.02 version as well! ))))

https://www.adventuregamestudio.co.uk/forums/index.php?topic=10392.msg126247#msg126247
#48
Ok guys, so I did some research on this and have semi-good news at the moment.

I've managed to find the plugin sources but only version 2.00 that requires Allegro DLL.

That's not a big deal to remove the dependency on the external Allegro DLL again. Apart from that the logical behavior of 2.00 vs 2.02 seems almost bit-by-bit identical to each other. That's important as I wanted to support previously released AGS games as well (say AGS engine version 2.72).

And I think Snow/Rain v2.01 was actually a fix to support AGS 2.60 (where some drawing optimizations were introduced aka Dirty Regions)

And 2.02 was a fix to work with AGS 2.71 where I think the internal AGS Allegro library was updated (but I'm not sure) and got in conflict with the external one used by the plugin. At that point the external dll was removed in the original 2.02 version of the plugin.

All in all, now I have the sources and can build a new version of the plugin to be very compatible with the old one! That's good.



Now to the Direct3D problem...

It looks like at the moment there is no support in the AGS Engine Plugin API for drawing operations by means of AGS Direct3D Driver.

So there is no a simple fix...

However... it is possible to use Direct3D directly :) calling low-level Direct3D9 functions from within the plugin to try and draw particles onto the screen.
But such an approach rises a number of serious concerns regarding cooperative use of the Direct3D device by the plugin and AGS.

Also, the AGS Direct3D Driver actually does quite a lot of stuff like checking video hardware capabilities and trying to adapt to specific setups any user may have.
The plugin then have to reproduce that behaviour to be consistent with what AGS D3D Driver already does.

A really fast and dirty trick I could try is just grab the AGS D3D Driver source code and put it inside the plugin to replicate the behavior.
This is not a good solution and may theoretically break the plugin again at any moment in the future versions of AGS.
Also if other video driver modes like OpenGL are introduced the plugin won't work with them and will need a new fix.

Oh well, little we can do as the AGS Engine API is rather old and was build around Allegro (DirectDraw) support from the beginning.
I believe CJ had no plans adding Direct3D support in that times, but the computer industry had its own visions and good-old Direct2D support or whatever started to break when newer kewl video cards and chipsets appeared on the market...



And as for the script module version of the plugin - that's a possibility but I tested the performance of drawing in AGS script and it is unfortunately much lower compared to the plugin. But maybe it's possible to optimize it a bit with prerendering or something. I'll see what I can do...



Ok, I think I'll try fixing the plugin to work in the Direct3D mode and than let you know how it goes.


~Cheers
#49
Hello and...

Blimey! It's been 14 years now since the release of the snow/rain plugin version 2.0...

Can't believe people are still interested in using it in their new projects!

I am sure there is a lot of alternatives right now in a form of script modules or something.

And yep, DLL-plugins are known to have portability issues, effectively binding the game that uses them to "Windows-only".

One funny thing about the snow/rain plugin though, is that it had portability concerns from the very first day of its appearance but over a decade ago it was about not being able to build a DOS-version of the game, lol! Not even a Linux port of AGS was in question those days. Time flies by!

Now having said that I'm actually somewhat interested as to whether people do want a reincarnation of the plugin to support more recent versions of AGS?

Not sure if I still have the source codes of the original version (need to check my backups) but if I do, I could probably mock up a new version as a script module as time permits, unless there are serious technical difficulties to make it work in AGS script fast enough.


As for plugin's not supporting the Direct3D mode, well... if memory serves me right, the last time I checked it (but that was many years ago, I have to say) I remember I had a feeling it was something in AGS itself that prevented the plugin to work in Direct3D out of the box. I think I removed all the direct calls into Allegro library and only relied on the AGS Engine Plugin API instead.

Oh, and about the recreation of the snow/rain plugin by JJS. I'm really sorry that I didn't give him the sources of the original plugin. Could have saved tons of work. He actually asked me if I can share it, but by the time I read his message he had already coded the whole thing on his own...

Anyways, I can probably look into the Direct3D issue again if I can dig up the sources out of tons of backups I have... Of course if anyone is really interested.


~Cheers
#50
Yep, you could just put "return;" in there, but a more practical approach would be to use the "else if" method, to skip the 2nd block of code when the function runs first time:


if      (TalkedGuard2 == 0) {

}
else if (TalkedGuard2 == 1) {

}
#51
I'd go with using characters to simulate bullets so not to complicate things too much for a start.

Check some code from that thread for the basics on how to iterate through characters and test each one for collision with a bullet.

And here is an example of code that allows firing several bullets in a row.

at the top of the main global script
Code: ags

#define MAX_BULLETS 3

Character* bullets[ MAX_BULLETS ]; // array storing characters working as bullets

// this function is "automatically" called when some bullet hits some character;
// here we can actually react to hits and do something useful!
function OnHit( Character *bullet, Character *enemy )
{
    enemy.SayBackground( "Ouch!" );
    //enemy.Animate(...);
}

// this function looks if there are free bullets left in the bullets[] array -
// those characters who reserved as bullets but not used at the moment
// and returns one of them so we could use it to fire another bullet!
Character* GetFreeBullet( )
{
    int i=0;
    while ( i < MAX_BULLETS )
    {
        if ( bullets[i].Room == 0 ) return bullets[i]; // free bullet found, return it!
        i++;
    }
    
    return null; // no free bullet available
}

// fires a bullet (typically should be called from the on_key_press() function);
// this function also returns false if no free bullets available at the moment
bool Fire( )
{
    Character* b = GetFreeBullet( ); // try to get a new bullet
    
    if ( b != null ) // if found, bring it here and fire somewhere (eg. bullet.Move)
    {
        b.ChangeRoom( player.Room, player.x, player.y );
        b.Move( b.x+100, b.y, eNoBlock, eAnywhere ); // can be adjusted to fire somewhere else
        return true;
    }
    
    return false; // no free bullets to fire at the moment
}

// this function checks if any of the bullets hits any of the characters
// it only checks how things are going for the current moment,
// so it must be called repeatedly to keep us informed;
// each time it detects a hit this function calls OnHit() where we can handle the process!
function CheckHitting( )
{
    int i=0;
    while ( i < MAX_BULLETS ) // go through each bullet...
    {
        if ( bullets[i].Room != 0 ) // ...but consider only those which are in use ATM
        {
            int j=0;
            while ( j < Game.CharacterCount ) // with each bullet go through each character
            {
                if (   ( character[j].Name != "bullet"        ) // bullet can't hit another bullet
                    && ( character[j] != player               ) // bullet can't hit player
                    && ( bullets[i].Room == character[j].Room ) // bullet must be in the same room
                    && ( AreThingsOverlapping( bullets[i].ID, character[j].ID ) ) // hit check
                   )
                {
                    bullets[i].StopMoving( );
                    OnHit( bullets[i], character[j] ); // notify us about hit by calling OnHit
                }
                
                j++; // goto next character number from the standart character[] array
            }
        }
        
        if ( bullets[i].Moving == false ) bullets[i].ChangeRoom(0); // mark is as free (move to room 0)
        
        i++; // goto next bullet number from our custom bullets[] array
    }
}


within function game_start()
Code: ags

cBullet1.Name = "bullet"; // we mark each bullet this way to recognize them easier!
cBullet2.Name = "bullet"; // another way would be to write a special function which
cBullet3.Name = "bullet"; // looks if a character is actually a bullet by looking into the bullets[] array
    
bullets[0] = cBullet1; // assign bullet-characters (must assign as many as we have in MAX_BULLETS)
bullets[1] = cBullet2; // assign bullet-characters
bullets[2] = cBullet3; // assign bullet-characters


with function repeatedly_execute()
Code: ags

CheckHitting( ); // put it here to check for hitting repeatedly!


with in function on_key_press()
Code: ags

if ( keycode == eKeySpace ) Fire( ); // try firing another one if space key is pressed!


Initially, each of the bullet-characters must be in Room 0 (means they are free and available to fire one). AGS Editor should automatically put all newly created characters in room 0, though.

Just browse the code to try and see how the logic goes. Iterations in two nested while loops in CheckHitting basically do the thing.

See if it can be of some help :)
#52
I think changing it in a while loop should also work, as long as you don't forget to regularly update the engine state by calling Wait(1) or another blocking command. But having it implemented via RepExec, as RickJ suggested, is much neater as the user interface is not disabled then, and some other things may be running as well.

QuoteIt has to be: if (msgid==1)... Note the two equal signs you need when checking a variable.. RickJ must have missed that in his code but it's a mistake I make way to often myself..

I've been doing some Delphi programming for quite a while. Now I constantly keep writting if(a=1), if(a<>1), a:=1 everywhere... God, that's really terrible to switch back and forth!
#53
Hello!

So, what's the meaning of life? ;)
#54
The thing is, you could still use the method with one bullet character. You can make the bullet invisible (transparent) and increase its moving (walking) speed and just use it for the sake of checking whether or not it hits some enemy at all.

Note how you can have your player character armed with any weapon you like (use different views) and give some amount of damage to enemy based on that.
#55
It's "change" :)

Code: ags

cSomeNpc.ChangeRoom( 4); // put them in room 4
cSomeNpc.ChangeRoom(-1); // remove


See the manual for additional info on the subject.
#56
The question is, how is the player supposed to aim?

Is there some kind of a crosshair or what?

Or does the player character only shoot in one specific direction?

Please elaborate on it more.
#57
Yep, we need to look at the exact codes you use.

So...

npc's struct definition (and where did you put it?),
spawnnpc,
and "before fade-in" codes

...would be of primary interest.


EDIT:

And also, where is an npc array is placed (script code / script header) ?
ie: NpcStruct npc[100]; or whatever it's called.
#58
First of all, make sure you correctly named the sound file (eg: SOUND2.WAV) and put in into the Sound folder of your game.

Also, look into the following topic for a possible solution to your problem:

http://www.adventuregamestudio.co.uk/yabb/index.php?topic=33017.0

#59
You simply need to test repeatedly whether the bullet character hit each character using a "while" loop. Every character has a corresponding number (ID ie. identifier) associated with it. Use that to go through all of them but the bullet itself to test for collision :)

Say you have 7 characters: 0, 1, 2, 3, 4, 5 and 6; where 0 is the player character and 1 is the bullet. Then you can do:


within repeatedly execute:

int bullet_id = 1;

int id = 2;
while (id <= 6) // run for characters with the following IDs: 2, 3, 4, 5, 6
{
    // test each for collision but make sure bullet cannot hit itself ;)
    if (AreThingsOverlapping( bullet_id ,  id ) && ( id != bullet_id ) )
    {
        // remove bullet from the current room
        character[ bullet_id ].ChangeRoom( -1 );

        // start playing a death animation on character being hit
        character[ id ].LockView( BEING_HIT_VIEW );
        character[ id ].Animate( 0, 0, eOnce, eNoBlock );
    }

    id ++; // proceed to testing the next character in a row
}


This should get you started figuring it out.

By the way, it is possible to set up a list of characters that are subject to be hit but I intentionally haven't shown how to do that yet as it relates to declaring an array of pointers to characters which may look somewhat confusing to understand if you are new to that sort of things.
#60
By the way, is there any way to disable auto-indentation in AGS 3.0?
I use my own custom formatting of script which always interfere with it.

Also, I noticed pressing Ctrl-T in script editor swaps two lines around. I suspect it can now make people mess up their codes if they accidently press it instead of F5 trying to "Test game". Personally, I do that mistake now and then as I'm working in both AGS 3.0 and 2.72 versions. I think that's because formerly you have to close the script editor window to test a game but now it is part of the AGS main GUI and so I see treeview on the right and spontaneously think I can test it from here.

Another thing about the frame SPD setting, would it be feasible to also display that under each frame in a loop as it used to be? It's now harder to estimate how loop will run: need to click each frame to see the delay value. And by estimate I mean it in a bit different sense that just view preview, as I, for example, need to see the exact values for each frame at once.

p.s. And where is the loop counter in debug mode gone? Again it's maybe personal by I always found that a nice built-in feature to have, especially for quick test games :)


EDIT:

Out of curiosity, what control component does the AGS Editor use to display tabs if I may ask?   :)
SMF spam blocked by CleanTalk