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.
16
General ENIGMA / Ini Plugin Upgrade
« on: August 10, 2014, 09:28:13 pm »
Hello all,
A while back I started working on some fixes to the ini plugin (which affects OSX and Linux users --Windows has its own approach). I had 3 goals:
1) Provide basically the same behavior as GM:S (excluding obvious flaws). So, all the ini_* functions (including ini_write_*).
2) Extend that to support saving and loading comments verbatim --now you can comment your ini files without ENIGMA eating the comments.
3) Replacing that horribly ugly ini Extension icon.
I originally lost interest, but at Robert's request, I have polished up my branch and stabilized it. You can try it out here:
https://github.com/sorlok/enigma-dev/compare/sorlok:robust_inis
A sample ini file that the plugin can load and save (mostly) verbatim:
Please let me know your thoughts on this. I'm still debugging weird edge cases, but once it's stable I'll prepare a pull request.
A while back I started working on some fixes to the ini plugin (which affects OSX and Linux users --Windows has its own approach). I had 3 goals:
1) Provide basically the same behavior as GM:S (excluding obvious flaws). So, all the ini_* functions (including ini_write_*).
2) Extend that to support saving and loading comments verbatim --now you can comment your ini files without ENIGMA eating the comments.
3) Replacing that horribly ugly ini Extension icon.
I originally lost interest, but at Robert's request, I have polished up my branch and stabilized it. You can try it out here:
https://github.com/sorlok/enigma-dev/compare/sorlok:robust_inis
A sample ini file that the plugin can load and save (mostly) verbatim:
Code: [Select]
; Comments can appear above sections.
[somesection]
test = hi ;..also after vars
test2 = " hi "
;Var quote
test3 = " hi " ;quotes are used to preserve spaces in values.
test4 = hi ;test
test5 = hi
test6 = hi ;tset
test7 = "hi;" ;...quotes also help if the comment character is inside your value
test8 = "newvar;"
;A comment at the end of the file
Please let me know your thoughts on this. I'm still debugging weird edge cases, but once it's stable I'll prepare a pull request.
17
General ENIGMA / Portable EXE is flagged as malware by Google Chrome
« on: August 04, 2014, 09:12:14 pm »
Just FYI:

18
General ENIGMA / ENIGMA prototype bindings for SDL
« on: August 01, 2014, 08:16:45 pm »
Good evening all,
Last week I started a prototype to get ENIGMA working with SDL platform bindings (code here). It was actually a lot easier than I thought, and we've got running games now:

I know that SDL is being bound, because the input's frozen. Whoops.
Anyway, so far this project was just for my own curiosity. I don't intend to continue it, but I wanted to check with you all first before abandoning it. Is this a wanted feature? Some benefits of SDL:
The challenges:
Side-note: Input does actually work in my test scripts; I'm not 100% sure why it's frozen in Project Mario.
Last week I started a prototype to get ENIGMA working with SDL platform bindings (code here). It was actually a lot easier than I thought, and we've got running games now:

I know that SDL is being bound, because the input's frozen. Whoops.

Anyway, so far this project was just for my own curiosity. I don't intend to continue it, but I wanted to check with you all first before abandoning it. Is this a wanted feature? Some benefits of SDL:
- It has mostly the same code on all 3 platforms (glXSwapIntervalEXT notwithstanding).
- SDL2 (which I am using) has support for Android. So... this makes things easier, right?
- Even if you never use it, it's always nice to have a "backup", and right now most "Platforms" only have 1 option.
- I have to fix all the xLib stuff anyway at some point, and switching to SDL might actually be easier.
The challenges:
- A lot of the code in Platforms/ is actually not platform-specific, so I'd have to do a lot of refactoring.
- This will inevitably lead to temporary breakage, which everyone (including me) hates.
- Basically, I only want to put in the extra effort if people will use it.
Side-note: Input does actually work in my test scripts; I'm not 100% sure why it's frozen in Project Mario.
19
General ENIGMA / Fun with imge_single
« on: July 23, 2014, 07:37:53 am »
After two previous attempts, I've finally got image_single working. These three commits (#1, #2, #3), in order, comprise the basic solution.
Before explaining what my solution does, I need to explain why the previous two approaches fell short.
My approach is basically to create two classes that wrap gs_scalars/integers and overload operator= to track every access. Then, the following logic occurs:
This approach works very well (tested in Iji, a very image_single-heavy game). There's a potential issue with image_index getting a few frames ahead if image_single is called from another object's with() block, but it doesn't come up in practice, because everyone just resets image_index manually most of the time anyway when setting image_single to -1. This is, I think, part of the reason why image_single was dropped originally.
Caveat emptor: I'm not planning on merging this anytime soon. It adds a penalty to every image_index access even if image_single is not used, which I don't think is fair (since no-one uses it for new games). Also, it's only been tested on GM5 (yes, technically GM:S also supports image_single, and I've heard it behaves slightly differently). So I'm only presenting this as an overview to answer the question "What would be necessary to properly support image_single?". The nice thing is that these changes, although messy, are all relatively localized, so we could, in theory, enable them selectively at compile time.
Before explaining what my solution does, I need to explain why the previous two approaches fell short.
- Approach 1: #define image_single as image_index. The problem here is that, when image_single is set back to -1, image_index must be set back to its old value, including the fractional component (if, e.g., speed is <1). But the fractional component must be dropped if image_index was manually reset any time during that period.
- Approach 2: Use events.res to overwrite image_index in some event (say, End Step). The problem here is that image_single can be set by another event using "with(object)". This leads to flickering, as the image_index has likely advanced a frame, but image_single won't be applied until the next frame.
My approach is basically to create two classes that wrap gs_scalars/integers and overload operator= to track every access. Then, the following logic occurs:
- ImageIndex::operator=() -- Sets a "manual" flag to let the program know that image_index was set by the user (not by image_single). (Protects against image_index updated while image_single is still in control.)
- ImageSingle::operator=() -- If the new value is -1, restore the old value. Else, save the old value of image_index, but only if the manual flag is set. (Protects against multiple calls to image_single in a row.)
- The step event -- don't update if image_single is >=0.
This approach works very well (tested in Iji, a very image_single-heavy game). There's a potential issue with image_index getting a few frames ahead if image_single is called from another object's with() block, but it doesn't come up in practice, because everyone just resets image_index manually most of the time anyway when setting image_single to -1. This is, I think, part of the reason why image_single was dropped originally.
Caveat emptor: I'm not planning on merging this anytime soon. It adds a penalty to every image_index access even if image_single is not used, which I don't think is fair (since no-one uses it for new games). Also, it's only been tested on GM5 (yes, technically GM:S also supports image_single, and I've heard it behaves slightly differently). So I'm only presenting this as an overview to answer the question "What would be necessary to properly support image_single?". The nice thing is that these changes, although messy, are all relatively localized, so we could, in theory, enable them selectively at compile time.
20
Developing ENIGMA / Iji on ENIGMA
« on: July 07, 2014, 03:55:01 pm »
Hey all,
Now that I've finally gotten past the intro cutscene, I figured it would be a good time to formally introduce my project: porting Iji to ENIGMA (and thus, a native Linux port).
Requisite gameplay video:
https://www.youtube.com/watch?v=iBErmgih7fU
The video describes some basics about what I'm trying to accomplish. In terms of commits to ENIGMA, I have been pushing relevant commits upstream for months, but there will always be some hacks that I feel should not be included in the engine. Thus, you'll have to use my Github fork of ENIGMA to run this.
NOTE: Game is super-crashy, and may hang your system.
Now that I've finally gotten past the intro cutscene, I figured it would be a good time to formally introduce my project: porting Iji to ENIGMA (and thus, a native Linux port).
Requisite gameplay video:
https://www.youtube.com/watch?v=iBErmgih7fU
The video describes some basics about what I'm trying to accomplish. In terms of commits to ENIGMA, I have been pushing relevant commits upstream for months, but there will always be some hacks that I feel should not be included in the engine. Thus, you'll have to use my Github fork of ENIGMA to run this.
NOTE: Game is super-crashy, and may hang your system.
21
General ENIGMA / Cross-platform filename mangling
« on: July 02, 2014, 08:12:20 pm »
Hello again everyone,
I've run into an issue that requires sweeping changes, and I thought I'd post here to get everyone's thoughts on my proposed solution. The issue: "\" on Linux messes up things like "file_exists()" and "sound_add()" (and a LOT of other functions). Although using "/" will work on both Windows and Linux, many developers forget or aren't aware. At the very least, both Project Mario and Iji are affected.
My proposed fix is outlined in this commit, which is a prototype fix that I will expand to cover all the other file functions if everyone thinks it makes sense.
Basically, I've changed the following:
The "filestr" class is defined in PFfilemanip.h, and takes a "const char*" in a single-argument constructor. This allows you do the following in your script:
...in other words, no changes are required to user scripts. The "filestr" class also exports "c_str()", so the functions themselves (e.g., "file_exists") only need to change the parameter type of "fname". The constructor of "filestr" is platform-dependent:
In other words, Windows filenames are unaffected, and Linux filenames should "just work". (There are still potential problems with case sensitivity, but by far the most common problem I've seen is with backslashes.)
Please let me know what your thoughts are on my solution. In particular:
I'm happy to scour the code base and make these changes, but I want to make sure this is a good approach first.
I've run into an issue that requires sweeping changes, and I thought I'd post here to get everyone's thoughts on my proposed solution. The issue: "\" on Linux messes up things like "file_exists()" and "sound_add()" (and a LOT of other functions). Although using "/" will work on both Windows and Linux, many developers forget or aren't aware. At the very least, both Project Mario and Iji are affected.
My proposed fix is outlined in this commit, which is a prototype fix that I will expand to cover all the other file functions if everyone thinks it makes sense.
Basically, I've changed the following:
Code: [Select]
//Every instance of "fname", such as :
int file_exists(std::string fname);
//...becomes:
int file_exists(const filestr& fname);
The "filestr" class is defined in PFfilemanip.h, and takes a "const char*" in a single-argument constructor. This allows you do the following in your script:
Code: [Select]
file_exists("somefile.txt")
...in other words, no changes are required to user scripts. The "filestr" class also exports "c_str()", so the functions themselves (e.g., "file_exists") only need to change the parameter type of "fname". The constructor of "filestr" is platform-dependent:
Code: [Select]
//On Linux:
filestr::filestr(const char* fname) : data(fname) { std::replace(data.begin(), data.end(), '\\', '/');}
//On Windows:
filestr::filestr(const char* fname) : data(fname) {}
In other words, Windows filenames are unaffected, and Linux filenames should "just work". (There are still potential problems with case sensitivity, but by far the most common problem I've seen is with backslashes.)
Please let me know what your thoughts are on my solution. In particular:
- Is this something generic enough to replace *every* occurrence of "string fname" with "const filestr& fname"?
- Is the "filestr" class defined in the right place?
- Are there any other concerns I should be aware of, or reasons this is not considered a good solution?
I'm happy to scour the code base and make these changes, but I want to make sure this is a good approach first.
22
General ENIGMA / Compatibility flags.
« on: June 23, 2014, 05:49:18 pm »
Hello all,
Something came up during my timeline branch that I'm not quite sure how to address. The field "timeline_running" is (I think) OFF by default in GM:Studio. In GM5, however, it does not exist, and it is implied that all timelines start as running. So, GM5 games still can't use timelines (since I made the GM:Studio behavior the default).
There's a simple fix to this: in write_object_data.cpp, we can do something like this:
However, I'm not quite sure where to put this option (a screenshot of the Enigma settings dialog is below for reference).
Any thoughts?
Something came up during my timeline branch that I'm not quite sure how to address. The field "timeline_running" is (I think) OFF by default in GM:Studio. In GM5, however, it does not exist, and it is implied that all timelines start as running. So, GM5 games still can't use timelines (since I made the GM:Studio behavior the default).
There's a simple fix to this: in write_object_data.cpp, we can do something like this:
Code: [Select]
//Old code:
wto <<"instance->timeline_running = false;\n"
//New code:
wto <<"instance->timeline_running = " <<(GM5COMPAT?"true":"false") <<";\n"
However, I'm not quite sure where to put this option (a screenshot of the Enigma settings dialog is below for reference).
- Unlike normal options, this should be set automatically when importing a project. Do we do that for anything else at the moment?
- None of the current categories seem like a good place to put this option. Do we have any similar settings at the moment?
Any thoughts?

23
General ENIGMA / Question about audio:none
« on: June 13, 2014, 07:20:20 pm »
Good evening,
I've got a development-based question about the "None" audio backend. Would it make sense to add empty initializations of "sound_add", "sound_play", etc. to this backend? In other words, "sound_add()" would check for the file and return an id, sound_play would take that id and do nothing (no sound). Basically, this would allow developers to compile games that use audio functions without actually linking to an audio backend, which is useful for debugging, performance testing, and other things.
If this doesn't really belong in "None", what about a "Mute" backend that does what I described? I'm comfortable implementing such a system, but I thought I'd check first.
I've got a development-based question about the "None" audio backend. Would it make sense to add empty initializations of "sound_add", "sound_play", etc. to this backend? In other words, "sound_add()" would check for the file and return an id, sound_play would take that id and do nothing (no sound). Basically, this would allow developers to compile games that use audio functions without actually linking to an audio backend, which is useful for debugging, performance testing, and other things.
If this doesn't really belong in "None", what about a "Mute" backend that does what I described? I'm comfortable implementing such a system, but I thought I'd check first.
24
General ENIGMA / Timelines won't update correctly after saving.
« on: June 13, 2014, 05:47:50 pm »
Hello!
I've been tracking down the issue egofree reported in the Timelines announcement thread, and I think I've finally got it narrowed down. Please refer to the image at the bottom of this post. Also, you'll need egofree's test game:
https://dl.dropboxusercontent.com/u/29802501/TestTimeLine.gmx.zip
Open the game, and open the first timeline's Step 60 code. You'll see show_message(60);. This (at least on Linux) will fail to compile, so change it to: show_message("60"); (note the quotes). Now, save the game and compile it without closing the editor. As you can see from the picture:
A) the "code" window shows the updated text
B) the filesystem itself shows the updated text
C) the compiler is still using the old text.
After some more digging, I found out that:
Does anyone (esp. Robert) know if there's special code that "refreshes" objects when they're saved to disk (or when the "ok" button is checked in Lateral GM), and if the same logic is not being run for timelines? I can try to narrow this down further, but I honestly haven't done much work with Lateral GM, so if this is an easy fix I'd appreciate if someone could let me know.
I've been tracking down the issue egofree reported in the Timelines announcement thread, and I think I've finally got it narrowed down. Please refer to the image at the bottom of this post. Also, you'll need egofree's test game:
https://dl.dropboxusercontent.com/u/29802501/TestTimeLine.gmx.zip
Open the game, and open the first timeline's Step 60 code. You'll see show_message(60);. This (at least on Linux) will fail to compile, so change it to: show_message("60"); (note the quotes). Now, save the game and compile it without closing the editor. As you can see from the picture:
A) the "code" window shows the updated text
B) the filesystem itself shows the updated text
C) the compiler is still using the old text.
After some more digging, I found out that:
- The same error occurs in EGM format (not just GMX folder format).
- Closing and re-opening the project will "fix" the issue (as egofree reported)
- The same issue does NOT affect objects (which compile similarly to timelines).
Does anyone (esp. Robert) know if there's special code that "refreshes" objects when they're saved to disk (or when the "ok" button is checked in Lateral GM), and if the same logic is not being run for timelines? I can try to narrow this down further, but I honestly haven't done much work with Lateral GM, so if this is an easy fix I'd appreciate if someone could let me know.

25
General ENIGMA / Cutscenes working in Iji on ENIGMA (experimental)
« on: March 15, 2014, 03:58:37 am »
Hey all,
I was up late for unrelated reasons, so I decided to consolidate all of my mega-unstable ENIGMA hacks to see what the end result was. And here it is:



That's right, you can watch the entire intro cutscene from Iji now. Back when I started hacking on this, you couldn't even get past the title screen, or see any text. The heavy lifting for cutscenes is done by my Timelines code, but there's a slew of bug fixes to boot. Gameplay is still impossible; there's a weird room-related bug I'm trying to track down. But this is very encouraging!
If you're curious to try it yourself, you can use this branch. Just be forewarned: that code is NOT production ready. I'll be cleaning it up and testing it more thoroughly in the coming weeks.
Happy hacking all.
I was up late for unrelated reasons, so I decided to consolidate all of my mega-unstable ENIGMA hacks to see what the end result was. And here it is:



That's right, you can watch the entire intro cutscene from Iji now. Back when I started hacking on this, you couldn't even get past the title screen, or see any text. The heavy lifting for cutscenes is done by my Timelines code, but there's a slew of bug fixes to boot. Gameplay is still impossible; there's a weird room-related bug I'm trying to track down. But this is very encouraging!
If you're curious to try it yourself, you can use this branch. Just be forewarned: that code is NOT production ready. I'll be cleaning it up and testing it more thoroughly in the coming weeks.
Happy hacking all.
26
General ENIGMA / Timeline Reader/Writer, lgmplugin
« on: January 23, 2014, 01:50:54 am »
Hello all,
Not sure exactly where this post should go, since the lgmplugin is halfway between Enigma and LGM. Anyway...
This code is commented out in lgmplugin's EFileWriter: (and similar code in Reader)
I figure that I can write a timeline reader/write pretty easily (after all, Timelines parse from GM into LGM properly), but just wanted to check here first to see if there are any "gotchyas" ---any reason those lines were commented out in the first place.
Also, are there any best practices for data formats? E.g., is there already a Timeline file format that I should follow?
Thanks~
Not sure exactly where this post should go, since the lgmplugin is halfway between Enigma and LGM. Anyway...
This code is commented out in lgmplugin's EFileWriter: (and similar code in Reader)
Code: [Select]
// writers.put(Timeline.class,new TimelineIO());
I figure that I can write a timeline reader/write pretty easily (after all, Timelines parse from GM into LGM properly), but just wanted to check here first to see if there are any "gotchyas" ---any reason those lines were commented out in the first place.
Also, are there any best practices for data formats? E.g., is there already a Timeline file format that I should follow?
Thanks~
27
Developing ENIGMA / Fixed a memory-corrupting texture bug; need help testing backends.
« on: January 15, 2014, 07:10:34 pm »
Hey all,
I've found a really nasty bug that corrupts any multi-sub-image texture when it's swapped out and reclaimed. Observe:

The first pic shows what happens on master; the second pic shows the correct behavior. The patch is here:
https://github.com/sorlok/enigma-dev/compare/texturecache_fix
And my test game:
https://drive.google.com/file/d/0B1P7NepPcOslbDlZanZNLUg2WDQ/edit?usp=sharing
Edit: Second test game, same glitch, no sub-images:
https://drive.google.com/file/d/0B1P7NepPcOslQVNBYjE1SlNKV0k/edit?usp=sharing
However, I really need someone to test this on other backends. In particular:
(I've confirmed that my patch works fine on OpenGL1.)
Once I get confirmed tests for these two platforms, I'll issue a pull request. I would really appreciate your help in this; Platform-specific bugs are a real pain, and this one affects everyone.
Thanks~
I've found a really nasty bug that corrupts any multi-sub-image texture when it's swapped out and reclaimed. Observe:


The first pic shows what happens on master; the second pic shows the correct behavior. The patch is here:
https://github.com/sorlok/enigma-dev/compare/texturecache_fix
And my test game:
https://drive.google.com/file/d/0B1P7NepPcOslbDlZanZNLUg2WDQ/edit?usp=sharing
Edit: Second test game, same glitch, no sub-images:
https://drive.google.com/file/d/0B1P7NepPcOslQVNBYjE1SlNKV0k/edit?usp=sharing
However, I really need someone to test this on other backends. In particular:
- DirectX9 -- I cannot, for the life of me, manage to get Enigma to work properly from SVN on Windows.
- OpenGL3 -- Everything compiles and runs, but I get no textures whatsoever (even on master).
(I've confirmed that my patch works fine on OpenGL1.)
Once I get confirmed tests for these two platforms, I'll issue a pull request. I would really appreciate your help in this; Platform-specific bugs are a real pain, and this one affects everyone.

Thanks~
28
Developing ENIGMA / New feature: Complex Polygons (review requested)
« on: January 10, 2014, 04:32:46 pm »
Hello all,
I've added some functions that allow ENIGMA to draw complex (self-intersecting) polygons. For example:

Since this is my first contributed feature --and it's really important to me not to step on the other developers' toes-- I decided to post here for feedback before I make a pull request. The code is available here:
https://github.com/sorlok/enigma-dev/tree/draw_polygon
Discussion is welcome, but please specify if any issues you have are deal-breaking issues. Everyone has different best practices, and I will try to accommodate your suggestions, but I have other features I'd like to work on too if there are no critical mistakes.
In particular, here are some potential issues, none of which I consider deal-breaking. Please let me know what you think:
Thanks in advance for your comments. If there are no deal-breaking issues, I'll prepare a pull request.
I've added some functions that allow ENIGMA to draw complex (self-intersecting) polygons. For example:

Since this is my first contributed feature --and it's really important to me not to step on the other developers' toes-- I decided to post here for feedback before I make a pull request. The code is available here:
https://github.com/sorlok/enigma-dev/tree/draw_polygon
Discussion is welcome, but please specify if any issues you have are deal-breaking issues. Everyone has different best practices, and I will try to accommodate your suggestions, but I have other features I'd like to work on too if there are no critical mistakes.
In particular, here are some potential issues, none of which I consider deal-breaking. Please let me know what you think:
- Currently only works for the GL1 backend. Rationale: I provide a fallback for other platforms that renders convex polygons. I can add GL3 support easily, too.
- Uses a custom class (PolyVertex) in a list to buffer calls to polygon_vertex(). Rationale: Drawing all at once minimizes GL errors (not ending the polygon) and memory leaks (not freeing temp. vertices for tessellation).
- Uses software tessellation (GLU). Rationale: If we move to hardware tessellation, we can still use this code as a fallback for GL1 and possibly GL ES (with some hacking).
- draw_polygon*() functions are in Graphics_Systems, not a plugin. Rationale: Drawing complex polygons is needed for GM5, and is (I feel) substantially different from primitives (such as triangle fans) to warrant inclusion as a main feature.
- (If I made a mistake in the GLU tessellation code, please let me know. That would certainly qualify as deal-breaking.)
Thanks in advance for your comments. If there are no deal-breaking issues, I'll prepare a pull request.
29
Developing ENIGMA / GM5 Compatibility plugin --feedback requested
« on: January 07, 2014, 01:21:03 am »
Hello all, looking for some advice on a plugin I've been working on for GM5 compatibility in Enigma. Branch is here:
https://github.com/sorlok/enigma-dev/tree/gm5_compat
Basically, I've been working on getting Iji running in Enigma. To that end, I've pushed a few bug fixes here and there. Combined with the branch linked to above (which I do NOT recommend merging; it's buggy and hackish) the game basically starts:
http://i.imgur.com/aXG69zA.png
I'd like some feedback on the idea of GM5 compatibility in general. Currently, I'm doing it all through a plugin, including the following:
For now, my approach to GM5 compatibility has been to keep as much as possible isolated in a plugin, so that compatibility can be turned "on" or "off" easily. This makes sense to me, but I figured now would be the best time to start discussing this.
Thanks, and happy coding.
https://github.com/sorlok/enigma-dev/tree/gm5_compat
Basically, I've been working on getting Iji running in Enigma. To that end, I've pushed a few bug fixes here and there. Combined with the branch linked to above (which I do NOT recommend merging; it's buggy and hackish) the game basically starts:
http://i.imgur.com/aXG69zA.png
I'd like some feedback on the idea of GM5 compatibility in general. Currently, I'm doing it all through a plugin, including the following:
- I've duplicated functions like draw_rectangle(), since GM5 does not provide an "outline" parameter. JDI finds these duplicates just fine, but perhaps this affects argument validation?
- My duplicate draw_*() functions take pen_size into account and use draw_line_width() to mimic GM5 wide outlines.
- pen_color, brush_color and other "magic" global variables are added as top-level static variables in the plugin.
- draw_text_sprite() and draw_polygon*() were also implemented. These might be useful for other games, or they might be too niche, and should be left in the compat library.
- There are some outstanding issues on C++ keywords being used as variable names (e.g., "short") that will inevitably have to be addressed.
For now, my approach to GM5 compatibility has been to keep as much as possible isolated in a plugin, so that compatibility can be turned "on" or "off" easily. This makes sense to me, but I figured now would be the best time to start discussing this.
Thanks, and happy coding.
