Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Java + Allegro = jalleg?

This thread is locked; no one can reply to it. rss feed Print
Java + Allegro = jalleg?
gillius
Member #119
April 2000

Hi guys,

Is anyone interested in using Allegro from Java or other JVM languages (JS, Python, Ruby, Groovy, Kotlin, etc.)?

I started a little trial with JNA-based Allegro 5.2 and it was not bad at all.

#SelectExpand
1 public static void main(String[] args) throws Exception { 2 Allegro al = Allegro.INSTANCE; 3 4 System.out.println(al.installSystem(Allegro.ALLEGRO_VERSION_INT, null)); 5 System.out.println(al.isSystemInstalled()); 6 7 AllegroColor color = al.mapRgbF(1f, 0f, 0f); 8 9 Pointer display = al.createDisplay(640, 480); 10 al.clearToColor(color); 11 al.flipDisplay(); 12 Thread.sleep(1000); 13 14 //Just to prove we can use Allegro from any JVM language, such as JavaScript Nashorn (built into Java 8) 15 ScriptEngineManager engineManager = new ScriptEngineManager(); 16 ScriptEngine engine = engineManager.getEngineByName("nashorn"); 17 engine.getBindings(ScriptContext.GLOBAL_SCOPE).put("al", al); 18 engine.eval("var color = al.mapRgbF(0, 1, 0);" + 19 "al.clearToColor(color);" + 20 "al.flipDisplay();"); 21 Thread.sleep(1000); 22 23 al.destroyDisplay(display); 24 al.uninstallSystem(); 25 }

There is NO native code or native compiler needed. I'm using the Allegro 5.2 monolith DLL that I found prebuilt from liballeg.org.

I just declare Allegro functions as Java Interface functions and use JNA, using mainly the liballeg documentation but also the header files as-needed.

public interface Allegro extends Library {
  Allegro INSTANCE = (Allegro) Native.loadLibrary("allegro_monolith-5.2", Allegro.class,
      Collections.singletonMap(Library.OPTION_FUNCTION_MAPPER, new AllegroFunctionMapper()));

  int ALLEGRO_VERSION_INT = 5 << 24 | 2 << 16 | 1;

  //Display Routines
  Pointer createDisplay(int w, int h);
  void destroyDisplay(Pointer display);
  void flipDisplay();

//...

How did I get here?

I used to work with Allegro in the late 90s on DOS (DJGPP) -- it was a very important part of my learning to program and inspiration for my current career. I saw the TNIS 2016 page and there was a note about how you can use any language supported, linked to a wiki. I saw the only Java option was a JNI-based thing from Kazzmir 11 years ago that did not appear to be finished, or against current Allegro. I thought, Java has much better options now (JNA not being the only), and is portable like Allegro (even to Android) so is a great fit. I've done Java professionally for over 10 years now so thought I could contribute something here and give back to a library (and community!) that was so important to me.

I'm not really a user of Allegro anymore, but I thought perhaps people might be interested in being able to use Allegro without needing to mess with a lot of native compilers and get more into development this way. And of course a full game could be built. To start development one could potentially need only Java JRE client installed and download Allegro jar, then could even write games in JavaScript or something else without even needing a compiler, and supporting cross-platform (although no Java-based JS on Android). And of course they can step up from there to Java compilation itself.

If this is something people would be interested in, I can continue farther.

Gillius
Gillius's Programming -- https://gillius.org/

Mark Oates
Member #1,146
March 2001
avatar

J'alleg, sounds like Klingon.

That's cool! Bind all the languages!

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Chris Katko
Member #1,881
January 2002
avatar

That's really interesting! I'd love to be able to host demo versions of my game on a website the way Humble Bundle sometimes does. (No idea how they do it...)

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

gillius
Member #119
April 2000

I picked jalleg as a working name instead of jallegro because Kazzmir's library on SourceForce is called jallegro. I haven't uploaded it anywhere yet so the name is open if anyone has a suggestion.

Java support unfortunately doesn't allow anything to work in the browser, even so, Allegro itself can't run that way. It would be possible to support Java Web Start (JNLP) so that a user can click on a link which automatically downloads and launches the app. I don't know how many users actually have this enabled given a lot of advice to remove Java from browsers due to the security risk (since Java applets/JNLP are so rarely used). But even if user has blocked Java in browser it would be possible to distribute a cross-platform Allegro game in a single JAR file you can double click on Windows or Linux. It would be big though as I notice the Allegro DLL itself is about 12MB (you have to include DLL/so for every OS and CPU architecture), and I don't know how "binary portable" Allegro is between different Linux machines (do you have to recompile Allegro on different distros?)

Not sure how the Humble games play in the browser, but I know emscripten is a way to compile C code to JavaScript, so if you had a platform with an HTML5 port you could compile to there -- not sure if that's what they are doing.

Gillius
Gillius's Programming -- https://gillius.org/

Elias
Member #358
May 2000

Quote:

Member #119

It's the real Gillius! :D

jalleg sounds interesting - is there a way to create the interface functions automatically, or does it have to be a hand-maintained file?

--
"Either help out or stop whining" - Evert

Mark Oates
Member #1,146
March 2001
avatar

You guys make me feel young again :'(:)

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Chris Katko
Member #1,881
January 2002
avatar

So what's the main advantage here? ... since Java applets are security-restricted these days.

Just directly writing an app in Java, and having Allegro do the game functionality?

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

gillius
Member #119
April 2000

Elias, it is possible to generate JNA mappings automatically using the JNAerator tool. I've done JNAerator on small projects and it's worked well. I have an unjustified fear that it may have problems on something as complicated as Allegro's headers that are filled with preprocessor macros, but the tool does support preprocessor directives (it can figure out AL_FUNC, for example).

However, I haven't tried a full build because I need all of the system headers as well, and I have no compiler or headers. I bet if someone has Linux it will be a lot easier to set up JNAerator since the include paths are well-known there. I just didn't want to figure out how to install mingw and Windows SDK headers and integrate them into JNAerator to start this out...

So far, I've been using segments of Allegro headers (like structs and enums) into JNAerator to convert those, then tweak by hand.

There are some possible benefits to doing it by hand:

  1. The automated tool will name the methods directly (al_install_system) but I've been naming them like installSystem with a custom mapper function that converts installSystem into al_install_system.

  2. JNAerator will cram all of the functions and all of the enums into one massive class. I've been splitting out the enums into outer classes. Likewise I've been renaming to Java conventions (ALLEGRO_COLOR to AllegroColor), which JNAerator doesn't do.

  3. JNAerator won't understand multi-module nature of Allegro, and I think a best final solution would split out all of the separate DLLs into their own interfaces, which also helps the massive class problem.

All that said, if we could get a proper output from JNAerator, it would probably be easier to use standard refactoring tools to just take its output and refactor it nicely. Or, you could argue I'm getting too fancy and we should just use its output as-is.

EDIT to answer Chris Katko: I have two main points for this:

  1. Allow Allegro development in Java and JVM-based languages (JS, Groovy, etc.)

  2. Allow developers to learn Allegro/programming in environments that may be easier to set up than C/C++ compilers (I know it's really easy on Linux but not so easy on Windows). Basically, using JS or Groovy or similar we can have a sort of "Allegro script" where you just point the Allegro runner at the script and it runs it (if we think anyone would actually use that)

Gillius
Gillius's Programming -- https://gillius.org/

Ariesnl
Member #2,902
November 2002
avatar

I thought everyone was trying to get rid of java nowadays
ofcourse the more language support, the better.

Perhaps one day we will find that the human factor is more complicated than space and time (Jean luc Picard)
Current project: [Star Trek Project ] Join if you want ;-)

gillius
Member #119
April 2000

As a practical language in use, Java is far from dead. Not even close. But Java is also conflated with the Java Virtual Machine (JVM) which also runs other languages becoming popular (Groovy, Clojure, Scala, etc.).

But honestly, I don't have a real practical purpose for this. That's partly why I came out asking whether or not anyone would care. With the exception of Minecraft, Java doesn't really have any future in gaming. Even though Android is doubling-down on Java in Android by switching to OpenJDK, game developers use C/C++ and probably will for performance reasons for quite a long time.

My point is I have no vision of this being a competitive choice. I thought perhaps it might be another way to introduce Allegro/game dev/programming to people who would be afraid of C/C++ development for various reasons.

The amount of interest generated (plus or minus) will change how seriously I take this project and the amount of time I put into it. The "just for fun" level may be to develop far enough to make a simple game in a few languages, put it on github and stop there, while a more serious approach may be to install a full-on development environment and/or Linux to see if we can use JNAerator to generate the full Allegro binding automatically.

EDIT: I checked into JNAerator and used it to generate a full Allegro binding from allegro.h. It does work, but I did have to touch it up a little. I say it gets me maybe 80% of the way there. Some random issues:

  1. I had to manually deal with size_t

  2. The only issue I had not having native system headers is any function taking/returning c_time was skipped (a few file I/O functions)

  3. While it defined types like ALLEGRO_BITMAP, for whatever reason all of the Allegro object types it treated like void** when it mapped them (like in al_load_bitmap)

  4. the fixed point math and haptic functions were all skipped (??)

I think I can take this as a starting point and then maintain it essentially by hand, since the API changes so rarely. I can fix up things like typed pointers, and I can rename things so that this line based on the out-of-the-box code:

ALLEGRO_COLOR.ByValue color = al.al_map_rgb_f(1f, 0f, 0f);

Looks like what I would like it to:

AllegroColor color = al.mapRgbF(1f, 0f, 0f);

Gillius
Gillius's Programming -- https://gillius.org/

Niunio
Member #1,975
March 2002
avatar

There is an Allegro for JavaScript. I've tested it, and even started a wrapper for Smart Mobile Studio, as I really don't like JS. It's based on Allegro 4 API, I don't know if a move to Allegro 5 API is planned.

-----------------
Current projects: Allegro.pas | MinGRo

gillius
Member #119
April 2000

That is super crazy awesome!

The author states Allegro 4 API explicitly because they don't like the 5 API and wanted to preserve the 4 API, so I don't think a move is ever planned.

It doesn't seem like there is anything of a port to it, really a re-implementation of Allegro API in HTML5 and JS.

But, that project fully realizes one of my goals for the Java binding, which is picking up programming and game dev easily. It doesn't get any easier than allegro.js, since all you need is a browser!

I've gone far enough with my JNAerator experiment last night I think I will finish some sort of binding to Allegro 5. It'll still be fun to see a whole new set of languages added to the list that can use Allegro. Then people can do crazy things like say they built a game with purely functional programming in Lisp (Clojure). I've never figured out Lisp so someone else will have to contribute that one but then at least someone can say they saw an Allegro game in Lisp :).

Gillius
Gillius's Programming -- https://gillius.org/

Elias
Member #358
May 2000

Allegro can also be compiled entirely into Javascript using emscripten. I've run some of my games in a browser that way :) This was an early test and I got it to work somewhat more nicely after that, but not sure I ever uploaded it somewhere:

http://allegro5.org/html5/ex_draw_bitmap.html

I just didn't really see much need for it so lost interest.

--
"Either help out or stop whining" - Evert

gillius
Member #119
April 2000

OK, I get very easily how C code can be compiled to JS, but I don't understand how it can interface with graphics, sound, mouse, etc. I mean, you call libraries/APIs, libc, etc. You could translate those but at some point you have have to have something that re-implements the graphics calls as HTML5 APIs or whatever.

What amazes me is I run your sample and the performance is "amazing*" (* for Javascript running in a browser on a crappy low-end laptop with crappy integrated graphics) in the sense I can run a bunch of images at 60fps.

I can see a need for that conversion if it works easily enough, for example all of the TINS games could be put online.

All of that is way cooler than what I'm doing :(.

Gillius
Gillius's Programming -- https://gillius.org/

bamccaig
Member #7,536
July 2006
avatar

For the ex_draw_bitmap.html, my proprietary AMD drivers managed 446 bitmaps in texture mode running at +- 30 FPS. :) Looks pretty smooth. Definitely a cool technology. It also looks useful to demonstrate the bugs in the Linux drivers. >:( The FPS count drops randomly and picks back up, just like I experience in Counter-Strike: Source.

I honestly don't think that a Java port is going to massively change anything, just as a Python port hasn't (I believe that Elias developed Python bindings that ship with the distribution). But it doesn't hurt to have it, especially if you can accomplish it quickly. These days universities are teaching Java, not C or C++, so it might well lessen the burden on new developers if they can write their games in Java.

The part that I like is the ability to easily interact with it in JavaScript by evaluating it. I could see a potential "game builder" being developed with that. Mind you, it would likely run much faster if you manually binded Allegro to V8 in C, but that would probably require much more work... It's probably not overly practical to do either, but it's a neat idea.

I say take this as far as you can, and polish it as much as possible. Document how you update the bindings so that even if you lose interest somebody else could pick up where you left off...

It may not be as cool as the Emscripten thing, but keep in mind that browser developers (e.g., Google and Mozilla) built that into the browser themselves. You couldn't run that same code on older browsers.. It's taking advantage of the fact that Google and Mozilla and others saw the use for "compiling" JavaScript into a native binary before running it and developed support for it... asm.js is a subset of JavaScript that is virtually translatable to C or assembly, which makes it possible to produce a very efficient program from for the target hardware using existing technologies... The code still runs in older browsers, at least pure asm.js, but much slower. The graphics access is likely through an HTML5 API. I seem to recall something about GL support or something? The rest is magic. Of course, most JavaScript in the wild isn't applicable...

gillius
Member #119
April 2000

Thanks bamccaig, that is good motivation.

Getting JNAerator to work was not bad at all. It got me almost all of the way then I just tweaked things. I ended up switching to JNA direct method binding which has speed close to custom JNI, but it means by default the functions are named same as Allegro, but as they are static class functions you can static import and the end result looks just like C code, close enough you can almost copy/paste.

I believe the haptic functions are missing because I didn't define ALLEGRO_UNSTABLE. I don't get why the fixed point math didn't come over, but it's trivial to add functions by hand. Direct mapping method doesn't support varargs, so I can't support al_fprintf without some extra code, but we don't need that in Java.

I'm very close to having something good enough to start building a github repo for. Here is my example application (yes, it works). Startup time is fast on Java 8 64 bit Windows 10, it's less than a second to show the display.

#SelectExpand
1 public static void main(String[] args) throws Exception { 2 al_install_system(ALLEGRO_VERSION_INT, null); 3 4 ALLEGRO_COLOR color = al_map_rgb_f(1f, 0f, 0f); 5 6 ALLEGRO_BITMAP display = al_create_display(640, 480); 7 8 al_clear_to_color(color); 9 al_flip_display(); 10 Thread.sleep(1000); 11 12 //Just to prove we can use Allegro from any JVM language, such as JavaScript Nashorn (built into Java 8) 13 ScriptEngineManager engineManager = new ScriptEngineManager(); 14 ScriptEngine engine = engineManager.getEngineByName("nashorn"); 15 //It should be possible to write a script to iterate all static methods and export them as globals to make it more C-like 16 engine.eval("var al = Packages.org.gillius.jalleg.binding.AllegroLibrary;" + 17 "var color = al.al_map_rgb_f(0, 1, 0);" + 18 "al.al_clear_to_color(color);" + 19 "al.al_flip_display();"); 20 Thread.sleep(1000); 21 22 al_destroy_display(display); 23 24 al_uninstall_system(); 25 }

As for bamccaig's comment about "game builder", yes you could do that in Java. The other thing you can do in Java is hotswap debugging, for example in IDE you run game in debugger and you change code, hit compile and instantly see it update in your game, without restarting. This is an awesome feature for games because a lot of it is about experimentation. And of course you can integrate trivially a language like JS (as I did) or Groovy and allow coding right on the fly in the game itself. But, honestly you can do that in C, too with Lua (I believe the World of Warcraft UIs were built all in Lua?)

I also would not worry about performance in the "game builder" scenario compared to V8 for example, for various reasons (from my perspective):

  1. It's not like we're trying to build a Unity competitor here :)

  2. Even JS on Java is fast, Nashorn actually compiles down to Java bytecode and is JITted to native and run through native profile-driven optimizer.

  3. The logic engine is normally not the bottleneck anyway (and I've seen real games use interpreted engines for logic)

  4. The old man in me says I built and saw some pretty good Allegro-style games built on a old Pentium machine with software rendering, so even the slowest technology now is many times faster than that.

My conclusion then is that the one and only goal of Allegro and Allegro bindings then is to make game development as EASY as possible, regardless of performance, because it's hard to be too slow. And in my mind, Java is easier than C. Only on the mobile Android ports might performance matter.

Gillius
Gillius's Programming -- https://gillius.org/

Elias
Member #358
May 2000

gillius said:

how it can interface with graphics, sound, mouse, etc.

Ah, yes, you need to implement those in HTML5. Graphics are easy as they already are written in OpenGL and we require WebGL. And someone wrote HTML5 drivers for Allegro once. But I couldn't get them to work in 5 minutes, so I cheated and used the SDL2 port of Allegro (and SDL2 has a HTML5 implementation).

--
"Either help out or stop whining" - Evert

gillius
Member #119
April 2000

OK guys, the jalleg project is published now. https://github.com/gillius/jalleg

Some of you asked about details on how I made the binding code, that is here: https://github.com/gillius/jalleg/blob/master/jalleg-binding/steps.md

If you just want to run it, you just need to have a Java 7+ JDK installed in your path (i.e. `javac -version` on command line shows 1.7+) and a connection to the Internet. Run the gradlew script (*nix and .bat versions included): gradlew run to build everything and see my example run. Gradle knows how to download itself and any libraries needed to compile and run.

If you're on Windows 64 bit running 64 bit Java, I've already included the allegro_monolith-5.2.dll for you and there's nothing you need to do. If running 32 bit Java download http://download.gna.org/allegro/allegro-bin/5.2.0/allegro-mingw-gcc5.3.0-x86-5.2.0.zip and put the resulting DLL in your path.

I'd like help for those on the Linux side. If you're on Linux, it will try to load liballegro_monolith-5.2.so using the normal way Linux libraries are loaded. I have no clue if that's the right name for Linux. If I had a pre-built Allegro library for Linux I would include it, but I could not find one. If that name is wrong you can just change the name of the lib at the top of AllegroLibrary.java to test it out, if you have Allegro's so installed "normally" in Linux it should just work.

Gillius
Gillius's Programming -- https://gillius.org/

Go to: