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.
196
General ENIGMA / Re: Fun with imge_single
« on: July 23, 2014, 11:02:42 pm »Then in place of [snip=edl]caller->image_index[/snip], you use [snip=edl]caller->image_single == -1? caller->image_index : caller->image_single[/snip].
What you describe is how I think GM actually implements it. The problem with this, if I'm not misreading your code, is that it requires us to check image_single every time we want to access image_index. Lots of seemingly-unrelated areas of code (like the collision system, I think?) use image_index directly. Maybe we could get away with turning just image_index into its own class, with an int() operator that checks image_single.... but that's not quite right either. Remember, you can do the following:
Code: [Select]
//In Create()
self.image_index = 0;
self.image_speed = 0.5;
//Some time later.
self.image_single = 4;
self.image_index = 2; //This affects the "underlying" value, NOT image_single.
//Some time later.
self.image_single = -1;
//At this point image_index should be 2.
I guess we could solve that with operator=, but see my next point.
Anything that slows down or has potential of slowing down ENIGMA for users who do not need those or don't use those functions is counter productive IMO. I canceled one of my past pull requests by concern of it slowing down. Don't assume people won't notice, perhaps things become more noticeable when your game is very complex and requires every bit of juice squeezed out. These type of functions that are not really used much should not be forced but made optional through the use of extension IMO.
I'm inclined to agree. As excited as I am to have figured out a decent solution to image_single, the fact remains that it's a deprecated and confusing feature, and no-one uses it. I'd much prefer to switch it "off" by default ---one of my Pull Requests adds a "compat" setting for GM5 (for timeline_running); maybe we can use the same setting to selectively enable image_single?
Again, if you guys really want this merged I'll prepare a cleaner patch, but I'm uneasy about this particular feature and I'd much prefer to keep it in some kind of extension.
197
General ENIGMA / Re: Fun with imge_single
« on: July 23, 2014, 10:19:52 am »
I completely agree --for now, this is safest in my repo fork.
For it to work in the compat extension, we'd need the following:
For it to work in the compat extension, we'd need the following:
- The ability to change the type of image_index as defined in graphics_object.h
- The ability to add image_single into the class definition of graphics_object.h
- The ability to modify events.res to add the image_single!=-1 check.
198
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.
199
Developing ENIGMA / Re: Iji on ENIGMA
« on: July 18, 2014, 12:34:59 am »
Update: message boxes outside of cutscenes are actually different objects from those inside cutscense. So now chatting via triggers works:
https://www.youtube.com/watch?v=UNecqkDnufA
There'll be a few pull requests rolling in later related to this.
https://www.youtube.com/watch?v=UNecqkDnufA
There'll be a few pull requests rolling in later related to this.
200
Developing ENIGMA / Re: Accessing with types and passing by strong reference
« on: July 14, 2014, 08:42:02 pm »If you use sound_add() or something, then it would return Sound_ID, so there wouldn't be a problem. What I meant was that if you load something that returns an integer, then you wouldn't be able to use it as a resource without specific casting. I guess you could still always do "sound = (Sound_ID)5;". But this shouldn't really be a problem, because any function that actually creates or adds a resource, should return the right type.
Ok, that makes sense.
201
Developing ENIGMA / Re: Accessing with types and passing by strong reference
« on: July 14, 2014, 10:19:37 am »
This would have the added benefit of fixing a weird interaction with "assume default variables are 0" and having identifiers just be integers. So this would be a great feature from my point of view!
variants (or possibly vars?) contain a "type" in addition to a value. So storing a "class sprite_id" in a variant can be done by storing the integer value in the variant's "value", and storing an enum (sprite_id) in the variant's type. Then, when casting to a "sprite_id", you can fail (or return -1) if the types don't match.
Would this prevent external music files from working correctly? Those are often distributed with a game in a separate directory, and loaded dynamically at runtime. (I may be misunderstanding how your typedef solution is supposed to work.)
1) I previously suggested we just use classes (both return and pass to functions), as the user wouldn't know any better. He might be confused why "sprite_id*5" doesn't work, but that shouldn't work in any case. But it does mean problems with variables. By default every variable is a "variant", which means "variant" would have to cast to "Sprite" and "Background" and so on. I don't think that is possible, as it might only cast to "*Sprite" at best, and that would be required for this to work
variants (or possibly vars?) contain a "type" in addition to a value. So storing a "class sprite_id" in a variant can be done by storing the integer value in the variant's "value", and storing an enum (sprite_id) in the variant's type. Then, when casting to a "sprite_id", you can fail (or return -1) if the types don't match.
Also, this would mean we ALWAYS would have to use sprite name or the ID returned by sprite_add, to reference this sprite. This means we couldn't just load an integer from a file, and then use it as an ID. But the user shouldn't be doing that anyway, as he cannot know which ID the sprite will be assigned to.
Would this prevent external music files from working correctly? Those are often distributed with a game in a separate directory, and loaded dynamically at runtime. (I may be misunderstanding how your typedef solution is supposed to work.)
202
Developing ENIGMA / Re: Iji on ENIGMA
« on: July 13, 2014, 01:44:01 pm »Sounds good. Please keep us apprised of any more of these hacks that arise; it's good to have them in mind when designing backend components.
Absolutely.
203
Works in Progress / Re: Super Tux Boy
« on: July 09, 2014, 04:31:49 pm »
Looks really cool! I'll try it out when I get home.
204
Developing ENIGMA / Re: Iji on ENIGMA
« on: July 09, 2014, 04:31:21 pm »This is very nice sorlok, you are actually inspiring me, keep up the good work!
That's great to hear! The inspiration works both ways in fact, so thanks to you as well!
Sorry If I generally appear ignorant on compiler related issues, but it's because I usually am, I will speak up if I feel the need to however, but for the most part that stuff is best directed at Josh.
As strange as it may sound, the compiler source is actually not a problem for me. Generally the issue for me is not getting something done, but getting it done in a non-polynomial amount of time.
Ah, so band-aid stuff. Though, as far as I know, image_single was implemented; I'm not sure when that changed. Probably when polygone decided to redo my subimage handling when he moved it. It's not difficult to support image_single; you just check if it isn't -1 before you add image_speed to the current subimage.
The image_single stuff was revoked in a later commit, since you actually have to do a bit more than just check -1. In particular, when image_single is set back to -1, you have to revert to the previous frame (before the original call to set image_single). Or something like that; I haven't checked in a while.
Your final point, TGMG addressed in a regex replacer a while back. Good luck tracking it down, though. In the future, I intend to allow special handling of that in the EDL lexer. It's extremely easy, in fact; all you'll do is duplicate the default lexer and set [snip=cpp]keywords["try"] = TT_INVALID[/snip], then in the handler below, [snip=cpp]return token_t(TT_IDENTIFIER, "$try", filename, line, pos - lpos);[/snip]. A quicker (uglier) quick fix is just to use an ENIGMA-side #define. I.e, in definitions, put something like this:
I'll have a look. Basically, my current strategy is "keep nasty hacks in my fork until upstream has better systems in place for handling this kind of thing". So I'll wait for the EDL lexer extensions, rather than hacking in some macros now.
I've still got tons of legitimate work to do on Iji, so the hacks can stay in stasis for a while.
205
Developing ENIGMA / Re: Iji on ENIGMA
« on: July 08, 2014, 12:50:36 am »
Sure, here's a list of the changes I don't want to merge at the moment:
Oh, and the extensions idea you mentioned sounds marvelous.
- image_single - implementing this is not easy, and the 3 ways I've tried doing it make the regular drawing code much, much messier.
- with+script - my fix is inefficient, and most people don't use with+script.
- depth::remove() - this was sometimes encountering null pointers, a sign of a much bigger bug. I put a band-aid on it, but I think fixing the actual bug is the right solution.
- texturecache fix - my solution works, but is naive. Robert said he'll fix it his own way once GM 1.99 beta (or something) becomes stable.
- variable auto-renaming - I haven't implemented this yet, but I want to automatically replace, e.g., "try = 10" with "try_ = 10". The way I plan to do it will be inefficient.
Oh, and the extensions idea you mentioned sounds marvelous.
206
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.
207
General ENIGMA / Re: Cross-platform filename mangling
« on: July 05, 2014, 12:52:58 pm »
Project Mario still fails; please see the list of files I posted in my original post.
In particular, "x.WAV" should be "x.wav", or you should update the code to load "x.WAV" instead of "x.wav".
In particular, "x.WAV" should be "x.wav", or you should update the code to load "x.WAV" instead of "x.wav".
208
General ENIGMA / Re: Cross-platform filename mangling
« on: July 04, 2014, 12:14:00 am »
That's fine; I'll just keep the changes in my own fork then.
209
General ENIGMA / Re: Cross-platform filename mangling
« on: July 03, 2014, 02:56:47 pm »
Glad to hear that you'll be updating Project Mario. However, I still feel that asking users to scour their code base for "\" just to make things work on Linux is raising the barrier to entry for ENIGMA too high. In addition, abstracting all file paths into a Platforms/ class allows us to do neat things for mobile platforms. (For example, we can automatically prefix the filename with "/sdcard/data/" or whatever else is needed on Android.)
If you still feel this is an unwanted fix, I will keep this branch isolated in my fork of the repository.
If you still feel this is an unwanted fix, I will keep this branch isolated in my fork of the repository.
210
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.