Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Scavenger on Mon 24/08/2015 18:50:36

Title: What is required to compile a plugin / FWrite/FRead Question
Post by: Scavenger on Mon 24/08/2015 18:50:36
Hey, I'm trying to write a short engine plugin for my game, but I've long since switched computers and lost all of my Visual Studio stuff. I know a bit of C++ so the coding itself isn't an issue, but setting up the project is. I've plum forgotten how to set it up. Compiling was always a weak point for me. I've tried a few versions of VS, but none of them seem to have the DLL Project set up I remember?

Could someone tell me which version of VS I need and the settings I need to use, or link me to a VS project version of the engine plugin sample code? I can work it out from there, but I have no idea where to begin. The only projects I can find for AGS plugins are the editor ones. :(
Title: Re: What is required to compile a plugin?
Post by: Wyz on Mon 24/08/2015 20:08:45
From the top of my head:
Title: Re: What is required to compile a plugin?
Post by: Scavenger on Tue 25/08/2015 21:11:49
Alright, I've managed to compile it! Thanks! The rest should be just fine.
Title: Re: What is required to compile a plugin?
Post by: Monsieur OUXX on Mon 31/08/2015 12:21:55
But... Wasn't there a demo plugin for download, ready to be compiled, coming along a nice .sln file? I think there was. And on the download page, some instructions regarding the proper VS to use, etc.
Title: Re: What is required to compile a plugin?
Post by: Scavenger on Tue 01/09/2015 19:06:44
That was for the editor plugin, AFAIK. I couldn't find one for the engine plugin. It doesn't matter, though, I've already done it.

I'm currently trying to render a translucent sprite using the same method as I use in my module, but hopefully this is faster. I've coded out something that will write a 320x200 sprite to the screen, but as soon as it tries to run AGS throws up an illegal exception. The plugin runs when this code isn't running, so it's not anything outside of this:

Quote
---------------------------
Illegal exception
---------------------------
An exception 0xC0000005 occurred in ACWIN.EXE at EIP = 0x10001202 ; program pointer is +5, ACI version 3.21.1115, gtags (920,320)

And the code I was using is:



int LoadCLUT (int slot)
{
clutslot = slot;
return 0;
}
//This is run in the Room After Fade in manually, to point the plugin towards a 256*2048 CLUT I made earlier.

int AGS_EngineOnEvent (int event, int data) {
  if (event == AGSE_POSTSCREENDRAW) {
    if (clutslot > 0)
{
// Get a reference to the screen we'll draw onto
BITMAP *virtsc = engine->GetVirtualScreen();
BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
BITMAP *rain = engine->GetSpriteGraphic (920);
unsigned char **charbuffer = engine->GetRawBitmapSurface (virtsc);
unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
unsigned char **rainarray = engine->GetRawBitmapSurface (rain);
int x = 0;
int y = 0;
int transamount = 256 * 4;
while (y < 200)
{
while (x < 320)
{
charbuffer[x][y] = clutarray [charbuffer[x][y]][rainarray [x][y]+transamount]; //This compares the screen's colour and the sprite's colour, and adds an offset
                                                                                                                //so we're clearly in the 50% transparency zone. I'll add 0 index checking later.
x++;
}
x=0;
y++;
}

// Release the screen so that the engine can continue
engine->ReleaseBitmapSurface (virtsc);
engine->ReleaseBitmapSurface (clutspr);
engine->ReleaseBitmapSurface (rain);
}
}
  return 0;
}


I'm not exactly sure what's going on, as it should work, unless this is way out of my league C++ wise.
Title: Re: [C++] What is required to compile a plugin / Code Mysteriously Crashes Engine
Post by: Crimson Wizard on Tue 01/09/2015 20:04:55
Well, in general case it would make sense to test the object pointers you get from somewhere else, like engine in this case, to assert object was successfully retrieved.
Like:
Code (cpp) Select

BITMAP *virtsc = engine->GetVirtualScreen();
BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
BITMAP *rain = engine->GetSpriteGraphic (920);
if (!virtsc || !clutspr || !rain)
{
    // possibly output some debug string here
    return 0;
}



I can also point out that you are possibly using array indexes incorrectly.
The raw bitmap data has row (line) index first and column index second.
So it should be like
Code (cpp) Select

charbuffer[y][x]

instead.
Title: Re: [C++] What is required to compile a plugin / Code Mysteriously Crashes Engine
Post by: Scavenger on Tue 01/09/2015 20:28:52
Oh my god, I didn't think it would be that simple, I'm so used to things going x-y and not y-x.

It. Works.

(https://dl.dropboxusercontent.com/u/50882197/art/GameStuff/overlay_test.PNG)

Thank you so much! Now I can make all the neat effects I could possibly want!! A full screen translucent overlay with no overhead and no green tinge like I had last time! I'm going to use the hell out of this thing!
Title: Re: What is required to compile a plugin / Code Mysteriously Crashes Engine [solved]
Post by: Monsieur OUXX on Wed 02/09/2015 13:15:25
If needed: use this tool to produce a shitload of functions without much hassle http://www.adventuregamestudio.co.uk/forums/index.php?topic=46244.0
Title: Re: What is required to compile a plugin
Post by: Scavenger on Wed 02/09/2015 18:20:40
Okay, one last question and my plugin will be fully complete.

I have the following struct and variable I need to save in AGSE_SAVEGAME and restore otherwise my plugin will not carry over effects when I restore the game.

struct transoverlaytype {
int sprite;
int x;
int y;
int trans;
int level;
bool enabled;
} overlay[10];

int clutslot;


How would I write and read this data with FWrite/FRead? Can I directly type in engine->FWrite(*overlay,??,data), or do I need to format it somehow? I'm a little lost at this point.
Title: Re: What is required to compile a plugin / FWrite/FRead Question
Post by: Crimson Wizard on Wed 02/09/2015 19:02:31
Quote from: Scavenger on Wed 02/09/2015 18:20:40
How would I write and read this data with FWrite/FRead? Can I directly type in engine->FWrite(*overlay,??,data), or do I need to format it somehow? I'm a little lost at this point.
You could do it like that, and that would work for starters, but I won't recommend this; AGS saved structs like that and it was a headache to make it load this data back on different platforms (non-Windows, non-32 bit).
In brief, the problem is that on different systems (even with different compilers) the struct may be positioned in memory differently (this is known as data padding (https://en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding)). Your case may be simple, because you have mostly ints in your struct, nevertheless, writing struct in whole may lead to bad habits in future.

I would suggest to read/write one variable at a time.
E.g.
Code (cpp) Select

for (int i = 0; i < 10; ++i)
{
    engine->FWrite(overlay[i].sprite, sizeof(int), data);
    engine->FWrite(overlay[i].x, sizeof(int), data);
    engine->FWrite(overlay[i].y, sizeof(int), data);
    <...>
}
Title: Re: What is required to compile a plugin / FWrite/FRead Question
Post by: Scavenger on Wed 02/09/2015 22:22:21
Alright, I managed to do this:

Code (C++) Select
if (event == AGSE_SAVEGAME)
{
for (int i = 0; i < 10; ++i)
{
engine->FWrite(&overlay[i].sprite, sizeof(int), data);
engine->FWrite(&overlay[i].x, sizeof(int), data);
engine->FWrite(&overlay[i].y, sizeof(int), data);
engine->FWrite(&overlay[i].level, sizeof(int), data);
engine->FWrite(&overlay[i].trans, sizeof(int), data);
engine->FWrite(&overlay[i].enabled, sizeof(bool), data);
}
engine->FWrite(&clutslot, sizeof(int), data);
}
if (event == AGSE_RESTOREGAME)
{
for (int i = 0; i < 10; ++i)
{
engine->FRead(&overlay[i].sprite, sizeof(int), data);
engine->FRead(&overlay[i].x, sizeof(int), data);
engine->FRead(&overlay[i].y, sizeof(int), data);
engine->FRead(&overlay[i].level, sizeof(int), data);
engine->FRead(&overlay[i].trans, sizeof(int), data);
engine->FRead(&overlay[i].enabled, sizeof(bool), data);
}
engine->FRead(&clutslot, sizeof(int), data);
}


And it seems to be working! It just needed that little & sign I've seen before where things wouldn't take anything but pointers. Hopefully that'll be all for this plugin!
Title: Re: What is required to compile a plugin / FWrite/FRead Question
Post by: Monsieur OUXX on Fri 04/09/2015 09:25:27
Do you think your could open-source your plugin, so that people can see how to make one? (the "save/restore" aspect of it is very interesting)