AMGC2 Loader
juvinious

I wrote a command line utility to load AMGC2 plugins, making it easier for me to test and develop new plugins without having to load the GUI each time. The benefit of course is that it doesn't require me to use MASkinG and allows me to play the game. :)
I've tested it with all the plugins on Miran's page and they all work except Blocks and Chess.
This is not to circumvent Miran's work however and for the full experience it's recommended that you use AMGC2. But it could help others that don't have MASkinG or no desire to install it to play and enjoy the games. And hopefully entice other developers into creating more content for AMGC2.
For more information check the page below or the archive.

Links:
Web Page
source

Feedback is appreciated. :)

[edit]
Added the archive in case the links don't resolve.

miran

Nice. The links don't seem to work though. Could be a firewall thing on my side...

Anyway, the games are basically just plugins and IGame.h fully defines the interface, so yeah, anyone can make a client. :) I assume yours just plays the games and doesn't do any fancy stuff like settings and highscores?

juvinious

Updated the links, hopefully they'll go through.
If not then there's probably an issue with no-ip.com.

It does offer a menu for doing the settings and save them in a .cfg file. You can also create key bindings manually for it like you do in amgc2 in the .cfg file. I don't see the need for keeping highscores so I left that out. It does however print out your highscore on the cl when you are done. :)

One thing to note is that many of the games, mine included, are dependant on the location from which they are started. ie they look for their data files and what not in ./games/pluginname
so most of them need to be setup just like they were setup to be used in AMGC2.
I was hoping that the SetGamePath() and game_path were to be used for that reason, that way plugins can just use "game_path + resource" to load their data and there wouldn't be a problem. But that's just hopefull wishing. :P

miran

The thing is I only added SetGamePath (is that what it's called? I forget) not long ago, in one of the most recent versions. So most of the games don't use it and still assume to be located where the author put them...

EDIT: Links still don't work for me. I just get "loading ..." in the browser status bar and it never stops... :( EDIT: Actually it's "waiting for <your ip> ..."

Richard Phipps

The webpage works for me.

juvinious

Miran: ok I attached the archive in the first post. :)

miran

As I said, could be a firewall thing on my side. I'm at work and there are some pretty paranoid people here, so half the internet doesn't work half the time...

EDIT: I get this when running buildme.bat:

Creating directory obj/...
Creating directory dep/...
Building...
Compiling main.cpp...
Linking amgc2load.exe...
c:/mingw/bin/../lib/gcc-lib/mingw32/3.2.3/../../../libmingw32.a(main.o)(.text+0x
97):main.c: undefined reference to `WinMain@16'

EDIT: Adding END_OF_MAIN() fixed that. It works :) but it crashes on shutdown... :-/

juvinious

Oops forgot to add END_OF_MAIN()
I'll fix that and update, haven't tested it out on anything but linux.
Thanks. :)

[edit]
Ok fixed the END_OF_MAIN()
miran:
Hmm crashes on exit? Doing what exactly?
After loading a game?
I've added some of your DEBUG("main.log") messages to the main.cpp.
Recompile with "buildme.bat debug" (you might need to do buildme.bat clean first) and then try running again and post the main.log please. :)

miran

When I build in debug mode it says it can't load the dll... :-/

Otherwise this is what it prints:

Initiating Allegro
Loading game numbers.dll
Successfully loaded Numbers
This plugin has no configuration settings
Couldn't init sound. Please check your configuration
Disabling sound
Opening in window
Allocating screen buffer
Please wait while game initiates . . . . . done!
Your score was: 1
Unloading Resources
Shutting down

juvinious

Hmmm, when I get a chance I'll get my other box and play around with it on windows. So far that looks fine btw, could be problematic when deleting the game from memory, I'll need to check on that. But I assume the game otherwise plays fine?
Thanks again. :)

miran

I'm home now, on Linux, and the program doesn't work! Any game I try it says this:

Loading game template.so
Failed to load games/template/template.so

Doesn't matter if I build in debug or normal mode. When run in debug mode the main.log file looks like this:

main.cpp, main (203)
amgc2_wrapper.h, GetPlugin (319)
amgc2_wrapper.h, GetPlugin (322)
amgc2_wrapper.h, Plugin (244)
amgc2_wrapper.h, Load (262)
amgc2_wrapper.h, Load (265)
amgc2_wrapper.h, Load (274)
amgc2_wrapper.h, Load (280)
amgc2_wrapper.h, Load (289)
amgc2_wrapper.h, Load (294)
amgc2_wrapper.h, Plugin (246)
main.cpp, main (218)

I just compiled the source, put the binary in the AMGC directory and ran it with amgc2loader games/template/template.so. Doing the same on windows works (although I haven't tried all games) except for crashing on exit...

Btw, I noticed the following passage in your readme.txt:

readme.txt said:

The benefit of course is that you don't need to
have MASkinG installed to play games. :)

I'd just like to say that you don't need to have MASkinG installed to play games with the original AMGC2 either. You just need MASkinG if you want to build the source code, which is only really applicable on Linux...

Audric
juvinious said:

(...) they all work except Blocks (...)

Curse my metal body, I didn't update to the latest AMGC2 interface.

miran

I think you don't need to change anything in the code, just recompile. The zip on the AMGC2 homepage has a windows exe that is already compiled with the latest specification. :)

juvinious

Hmm I figured out why it crashes on exit. Deleting the module from outside is not a good idea, which I was doing. You do include a creational method:

extern "C" DLLEXPORT IGame* GetPlugin() 
{
  return new somegame;
}

It would be nice to add an additional:

extern "C" DLLEXPORT void DestroyPlugin(IGame *game)
{
        delete game;
}

It's recommended that deletion take place from inside the module just to play it safe.

Oh and about not having MASkinG installed, I was more referring to having the entire AMGC2 installed and having to load the GUI each time to play/test a plugin. Which is what my utility allows me to do. I'll reword it...

And the crashes loading plugins on linux seem to be a pain and consistent.
Currently I'm pulling code from amgc's source and dumping into one file. Which could be that I might be overlooking something. I'm going to fix this and not extract code, but include from off the amgc2 source directory and use the methods directly where possible or wrap them. This will probably prevent any failures/incompatibilities between the two and will keep the source consistent with the latest amgc2.
Thanks again. :)

miran
Quote:

It's recommended that deletion take place from inside the module just to play it safe.

Yeah, you're right. I'll make it so in the next revision while trying to keep backwards compatibility. :)

Quote:

And the crashes loading plugins on linux seem to be a pain and consistent.

They're not crashes, the plugins simply fail to load. I took a look at your code and it doesn't seem like you're doing anything any different than me. I really have no idea why simply loading a .so wouldn't work in your program when almost identical code works just fine for me. :-/

Thomas Fjellstrom

Do either of you check dlerror for the reason the plugins are failing to load?

miran

There is dlerror? :o :P

juvinious

Yes sir:
Check me out.

[edit]
*** just to clarify it's just an example of it in use, if you want more information check out the man pages.

Thomas Fjellstrom

I grepped through juvi's code, and didn't find one, so I had to ask.

juvinious

I updated the source to work mostly off of amgc2's source so you are going to need to have it to compile it, which will hopefully eliminate most if not all incompatibility issues.
The script will automatically grab what it needs under *nix systems and build it. On windows you are going to have to manually attain the source tarball and extract it somewhere then pass the src dir with "buildme.bat --dir c:\somedir\amgc2\src".
Follow the instructions in the README file.
:)
The links and the attachment in the first post have been updated.

Audric

Attached is the fixed version of Blockman, runs fine with AMGC2 Loader (tried MingW), except... the loader seems to reset and/or ignore the configuration ?
Blockman attempts to WRITE in the config file to save the last played level.

push_config_state();
char path[1024];
snprintf(path, sizeof(path), "%s%s.cfg", game_path, GetName());
set_config_file(path);
set_config_int("settings", blocks_settings[1].name, blocks_settings[1].value);
pop_config_state();

Works fine, and is generic enough to suit any installation (game_path and GetName())

miran

Still doesn't work on linux. But now it says it failed to load .so (any .so I try, doesn't matter which) and then crashes...

juvinious

Ok I've updated it once again. Fixed tons of stuff and cleaned up the code. It's at version 1.8.

Audric: Blocks works great and the configurations save correctly now with the latest changes. :)

miran: I'm developing this in linux, I don't know what could be wrong. It re-uses your amgc2 code to properly handle the plugins. Could you try the latest version and see if it fixes any issues? Could be that the plugins need to be recompiled?

Thanks all. :)

miran

I'll test when I get home this afternoon. I don't think anything needs to be recompiled because I recompile AMGC at the same time as your loader and it works while your loader doesn't. It's really weird... :-/

EDIT: Now it prints a different set of messages but basically still doesn't work:

Initiating Allegro
Opening in window
Please wait while game initiates...
Loading game template.so
Failed to load template.so

Oops! There was a problem with the plugin
Terminating
Unloading Resources
Shutting down

juvinious

That is very strange it shouldn't have a problem, especially if the plugins are being built against the same source.
Well hopefully the latest one works for you, if not I'm at a loss and I can only guess the best thing to do is to put in some more error checking for the .so loading routine. Also evaluating where specifically it's crashing might help too.

[edit]
Hmm I just posted and it seems you did too.

Quote:

EDIT: Now it prints a different set of messages but basically still doesn't work:

Initiating Allegro
Opening in window
Please wait while game initiates...
Loading game template.so
Failed to load template.so

Oops! There was a problem with the plugin
Terminating
Unloading Resources
Shutting down

template.so? :o
template.so isn't loading then.
Hmm could be a problem with cwd and paths, I had issues with that before I thought I fixed it. :-/
Try passing 'amgc2load ./template.so'
Because if the plugin loaded fine it would have given you another error msg.

miran

Still the same. If you print out the value dlerror() returns like Thomas said, it can help a bit. I added that in my copy and here's what it reports after failing to load the .so:

./amgc2load: undefined symbol: GetPlugin

Which is weird. But it gets even more weird if I compile your program manually with g++ -o amgc2load main.cpp -I../src/ -ldl `allegro-config --libs`:

�@: cannot open shared object file: No such file or directory

Only if I compile with -O2, I get the first error. So maybe it's something about the way it's compiled. Maybe something doesn't get linked in properly?

juvinious

Hmm maybe it's a name conflict. I didn't realize that the export "C" is GetPlugin for the loader and I'm using that as well.
I just changed it to loadPlugin throughout hopefully that's the problem.
I uploaded it with the changes to the first post.

miran

Makes no difference.

juvinious

:'(
There is no hope.
Missing libraries?
What distro?

miran
Quote:

There is no hope.

:'(

Quote:

Missing libraries?

What could be missing?

Quote:

What distro?

FC5_x64, but what could that have to do with anything? My code works when I use it, but not when you use it... :(

EDIT: I made a little test program which works like your loader. It includes IGame.h and plugin.h from the AMGC2 source dir and uses them to load a plugin specified with the command line and prints out plugin info i n an Allegro window. Analyze it and see what you're doing differently, because this program works just fine for me.

1#include <plugin.h>
2#include <IGame.h>
3 
4int main(int argc, char **argv) {
5 if (argc >= 2) {
6 IGame *game = *(new Plugin<IGame>(argv[1]));
7 if (game) {
8 allegro_init();
9 set_color_depth(32);
10 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 400, 32, 0, 0);
11 install_keyboard();
12 textprintf_ex(screen, font, 0, 0, -1, -1, "name: %s", game->GetName());
13 textprintf_ex(screen, font, 0, 8, -1, -1, "author: %s", game->GetAuthor());
14 textprintf_ex(screen, font, 0, 16, -1, -1, "description: %s", game->GetDescription());
15 textprintf_ex(screen, font, 0, 24, -1, -1, "version: %s", game->GetVersion());
16 delete game;
17 readkey();
18 }
19 }
20
21 return 0;
22}
23END_OF_MAIN();

And here's the makefile too. I use the same makefile to compile your loader as well. (note: I keep the source code in a directory under the AMGC2 dir)

CFLAGS = -s -O2 -W -Wall -I../src/

LIBS = \
  -ldl\
   `allegro-config --libs`

all: main.cpp
  g++ -o ../testload main.cpp $(CFLAGS) $(LIBS)

juvinious

I do exactly the same thing except for two things:
I install the keyboard before set_color_depth(32) and I don't use -ldl in my build flags.
Did you try getting info for a plugin through the command line?
./amgc2load plugin.so -i
It prints the same information to the console.

Thomas Fjellstrom

I downloaded the loader thing yesterday sometime, and it works fine here.

I repeat, IT WORKS HERE. These are the steps I followed:
1. downloaded amgc2load
2. ran the amgc2 compile script
3. CDed into the res/amgc2/games/tetris folder
4. typed "make"
5. CDed back to the base amgc2load folder
6. ran: ./amgc2load res/amgc2/games/testris/tetris.so
7. PROFIT!

miran
Quote:

I install the keyboard before set_color_depth(32) and I don't use -ldl in my build flags.

It doesn't matter, the same happens if I build with your cbuild script or my makefile.

Quote:

Did you try getting info for a plugin through the command line?
./amgc2load plugin.so -i
It prints the same information to the console.

No difference. The error occurs when loading the .so.

Thomas: Yes, that's how it's supposed to be. But for some reason this doesn't work for me in Linux (it works in Windows though)...

Audric

Time to check the linker version ?
For mingw I have:
$ ld -v
GNU ld version 2.15.91 20040904

$ gcc -v
Reading specs from C:/MSYS/mingw/bin/../lib/gcc/mingw32/3.4.5/specs
Configured with: ../gcc-3.4.5/configure --with-gcc --with-gnu-ld --with-gnu-as --host=mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --enable-languages=c,c++,f77,ada,objc,java --disable-win32-registry --disable-shared --enable-sjlj-exceptions --enable-libgcj --disable-java-awt --without-x --enable-java-gc=boehm --disable-libgcj-debug --enable-interpreter --enable-hash-synchronization --enable-libstdcxx-debug
Thread model: win32
gcc version 3.4.5 (mingw special)

amgc2 loader is useful, by the way, since amgc2 spends a noticeable time scanning the directories for all games (listing them in text mode, white text on black background, was a bit too much, I think) So the loader is valuable for quicker testing during development. Can even run it from the makefile :)

miran
Quote:

amgc2 loader is useful, by the way, since amgc2 spends a noticeable time scanning the directories for all games (listing them in text mode, white text on black background, was a bit too much, I think)

That's only really applicable in Windows. In Linux all the plugins are scanned so quickly you never even see that printout ;)

Thomas Fjellstrom
Quote:

Thomas: Yes, that's how it's supposed to be. But for some reason this doesn't work for me in Linux (it works in Windows though)...

Then maybe theres something wrong with YOUR system? Seems to work for several other people.

miran

Well, yeah, it looks like it...

juvinious

That's the pita of binary based distros.
You wouldn't have that problem if you were using a real distro. *cough *cough gentoo. ;)

Anyhow, I've updated my missle defend clone to use game_path so that it can be loaded in any directory. It's attached, if not you can grab it from its page.

Now if we can get the other plugin developers to update their plugins to use the game_path, my loader will be easier to use. :)

miran

Did you by mistake put the wrong source in the tar.gz you attached to your last post? Because your code crashes. Guess what is wrong. Here's a small hint:

1//...snip...
2class MissleDefend : public IGame
3{
4 public:
5 
6 Manager *gameManager;
7 
8 MissleDefend() : IGame()
9 {
10 //Nothing
11 }
12 
13 ~MissleDefend()
14 {
15 delete gameManager;
16 }
17//...snip...

;)

Here's another hint for you:

1// this is how it should look like:
2class MissleDefend : public IGame
3{
4 public:
5 
6 Manager *gameManager;
7 
8 MissleDefend() : IGame(), gameManager(0)
9 {
10 //Nothing
11 }
12 
13 ~MissleDefend()
14 {
15 if (gameManager) {
16 delete gameManager;
17 gameManager = 0;
18 }
19 }

Another minor suggestion: Rename the README file to readme.txt, startup my GUI host program and be amazed. :)

And finally a request from the general public: Could anyone running Windows that also happens to have Allegro 4.2.0, AMGC2 and preferably the MinGW compiler please try to compile a Windows DLL of the game? Here are the instructions:

1. Unpack the game to amgc2/games.
2. Edit the makefile so that line 4 looks like this: SRCDIR=../..
3. Edit mdefend.cpp so that the code starting at line 2271 looks like the second snippet in this post.
4. Run "make win" and ignore all the warnings.
5. Run amgc2.exe to verify that mdefend.dll works.
6. Attach mdefend.dll here or send to my email (in amgc2's readme.txt).
7. Go play a couple of rounds of Missile Defend! It's good! :)

juvinious
Quote:

Because your code crashes.

Heh, I'm not suprised considering the amgc2loader isn't working for you. ;P
But yeah you are right I should be initializing it to 0 and having the check before deleting. I changed it to look like that and renamed readme.txt to comform to amgc2. ::)

On a side note my loader seems to be a tad bit slower than yours, but not incredibly slower, I assume the timing is a bit off in my loader. I just ran it and it worked fine in amgc2 and in the loader.

Source attached. (deleted from previous post)

GullRaDriel

I was trying to compile it and put it here, but I got errors:

1C:\Download\amgc2\amgc2\src>make
2g++ -O2 -fomit-frame-pointer -ffast-math -funroll-loops -s -W -Wall -mwindows -D
3__GTHREAD_HIDE_WIN32API -o obj/mingw/MainMenu.o -c MainMenu.cpp
4MainMenu.cpp: In member function `virtual void IconItem::DrawItem(MAS::Bitmap&,
5int, int, const MAS::Rect&)':
6MainMenu.cpp:14: error: 'class MAS::ListBoxEx' has no member named 'AreGridLines
7Enabled'
8MainMenu.cpp:15: error: `DrawGrid' undeclared (first use this function)
9MainMenu.cpp:15: error: (Each undeclared identifier is reported only once for ea
10ch function it appears in.)
11c:/Codeblocks/bin/../lib/gcc/mingw32/3.4.4/../../../../include/MASkinG/compound.
12h: At global scope:
13c:/Codeblocks/bin/../lib/gcc/mingw32/3.4.4/../../../../include/MASkinG/compound.
14h:37: warning: unused parameter 'objList'
15c:/Codeblocks/bin/../lib/gcc/mingw32/3.4.4/../../../../include/MASkinG/compound.
16h:37: warning: unused parameter 'cmp'
17c:/Codeblocks/bin/../lib/gcc/mingw32/3.4.4/../../../../include/MASkinG/compound.
18h:37: warning: unused parameter 'focusObject'
19c:/Codeblocks/bin/../lib/gcc/mingw32/3.4.4/../../../../include/MASkinG/compound.
20h:37: warning: unused parameter 'c'
21make: [obj/mingw/MainMenu.o] Error 1 (ignored)
22g++ -o ../amgc2.exe -O2 -fomit-frame-pointer -ffast-math -funroll-loops -s -W -W
23all -mwindows -D__GTHREAD_HIDE_WIN32API obj/mingw/main.o obj/mingw/MainMenu.o ob
24j/mingw/GameDriver.o obj/mingw/PluginManager.o obj/mingw/hsc.o obj/mingw/HscDial
25og.o obj/mingw/fps.o obj/mingw/screenshot.o obj/mingw/OptionsDlg.o obj/mingw/Key
26Settings.o obj/mingw/KeyDialog.o obj/mingw/SettingsDialog.o obj/mingw/global.o o
27bj/mingw/OnlineDlg.o -lmasking -lalfont -lalleg obj/mingw/icon.res
28g++: obj/mingw/MainMenu.o: No such file or directory
29make: *** [main] Error 1

Lots of warnings before, and I was forced to change OBJDIR to obj/mingw32 instead of obj\mingw32

We will see later ;-)

miran

You need MASkinG from CVS. But why do you want to compile AMGC2.exe? Does the precompiled version not work for you? If you just want to compile the game dll, you don't need to compile amgc2 itself, you just need to have its source code.

GullRaDriel

I don't have CVS allowed trough our fucking proxy.

I got some work to finish, and I will try to give you this dll after.

miran
Quote:

I don't have CVS allowed trough our fucking proxy.

As I said, you do NOT need MASkinG at all! To compile game dlls you just need a couple of files from the AMGC2 code and plain Allegro.

GullRaDriel

Attached is the dll.

miran

Thanks. :D

Hehe, I was able to compile it myself actually as I'm at work right now where I use a Windows machine and had 15 minutes of time :)

Juvinious: AMGC2 page has been updated and now lists Missile Defend v1.9 :)

Neil Walker

Hello,
I have nothing to add to this thread, other than to say I think your newly designed website is most excellent and a great design. Well done that man.

(the only thing that would be nice would be an inclusion of online manual for your libraries, e.g. masking)

miran
Quote:

Hello,
I have nothing to add to this thread, other than to say I think your newly designed website is most excellent and a great design. Well done that man.

(the only thing that would be nice would be an inclusion of online manual for your libraries, e.g. masking)

Thanks, that's a good idea. I might even write some tutorials some time... :D

Thread #585675. Printed from Allegro.cc