Show Posts

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.

Messages - Josh @ Dreamland

Announcements / Re: Pride
« on: March 02, 2010, 11:36:56 PM »
Yeah, using namespace std works. I asked it to print the using scope... it took five seconds or so...
Asking it to print everything it had just parsed took 36 seconds. Heh...

Announcements / Pride
« on: March 02, 2010, 11:21:36 PM »
I'm so proud of this little community for not hanging on security considerations when looking to the efficiency ones. :3

Good news. Here's the result of parsing this code:

Code: [Select]
#include <map>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <set>
#include <iostream>

#include <windows.h>

No error.
Parse time: 1509 milliseconds

Macros (12684) [+ ]
Variables [+ ]
Define: CreateWindow
  #define CreateWindow CreateWindowA
Define: CreateWindowA
  #define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k) CreateWindowExA(0,a,b,c,d,e,f,g,h,i,j,k)
Define: CreateWindowExA
  CreateWindowExA:  Function with 12 parameters, returning HWND__  Dereference path: (params = 786444)*</group>

Since Windows includes everything, and I do mean everything, that anyone could ever need to make a game, there's really no point in assuming the parser needs further work. The parser no longer requires lists of functions and types.

Oh, and, if you noticed the odd parameter count when I asked it to define CWExA, don't worry, it stores that count in a jumbled short. It used to dissect the short and display the actual parameter bounds, but the code that does so got lost in one SVN commit or another.

Since you've all proven to be concerned with efficiency, here are some related tidbits of considerations:

1) The most pressing efficiency loss when treating EDL more like GML than C relates to the switch () statement. Those of you who are particularly well-informed with either GM or ENIGMA know that both engines treat a switch like a less-ugly chain of if()s. The complexity is the same; an == check for each label. A consideration, however, is to make a small, close-to-perfect hash function. Basically, this will allow for var case labels using some template magic. GM People: Stop reading after this next sentence.

I believe this can be done in O(1), maybe with two or three checks a number. Basically, a hash function will be used on the input to each case label, assuming these are constant. (Thanks to the C parser, checking can be done on this when they are not literals [such as 3.14 or "some string"]. How great is that?) Basically, the hash will take the sum of first and last byte of any strings along with its length, do some round() tricks on floats, and leave ints alone (C++ doesn't allow switching anything but int, and doesn't allow case labels of anything but constant int). Now, the thought of course is, what if two strings produce the same hash? That's why one check is done at the case label. You'll see the same idea being employed in hash maps. I owe it to Luda that I was enlightened to it. If anyone has a better idea, of course, by all means...

2) The next most annoying thing is compatibility garbage related to simple functions, like draw_primitive_begin(). From my reckonings, GM uses DirectX's idea of a Vertex Buffer Object. That's not always an option for GL... R3 and lower use glBegin(). This raises a compatibility issue when drawing two at once (this is allowed in GML, but not in GL). The reason I assume GM uses VBO is that it can in fact keep two separate primitives going at once. Long, long ago I decided to deal with the problem by allowing a statically allocated array to be used to hold the points for quick iteration... I made it static because I didn't want the overhead each function call to make sure we hadn't overflown anything and needed more space. However, this meant either an annoying amount of memory overhead, or an equally or more annoying setting to allow the maximum number of points to be set. (I thought 360 would be reasonable for most applications, but...) Anyway, in retrospect, it was an awful idea (good thing it was #if'd out by default). I think the plan should be to try for VBO, but if it doesn't exist, just offer glBegin(), no buffering. (This would break some compatibility for people with Intel cards barely meeting stone-age GL specifications). The good news is, no one who had any decent coding practice would notice the break.

I figured I'd get your opinions on those little things as well. If/when there is a DirectX port, that won't really be a concern (the nice thing is that with DirectX, we can make the same decisions as Yoyo did, good or bad, and no one can complain. Too bad I'm still using GL).

I'd throw in a third thing, but that's probably enough to swallow for one post. Those who would like to put their two cents in on security issues can do so in the previous thread. I guess we'll just keep doing this until I have a public opinion on the decisions that haunted me in early development stages (I want to get it all right this time. Or at least most of it).

While you people decide that, I'll be replacing lists of types and functions in the GML formatter with the new lookup calls. (Also, I think I need to make sure "using namespace" works in the global scope. )

Announcements / Re: Rejoice
« on: March 02, 2010, 10:44:54 PM »
Serp shortcuts. Makes a great optimizer.

Announcements / Re: Encryption
« on: March 02, 2010, 10:12:23 PM »
Sometimes one bites off more than one can chew. Like including windows.h. It introduced a few concepts I saw in Boost but was afraid of. So those have been implemented. Other than that, it's going pretty swell. :P

Anyway, it's nice to see that those who hang around these boards are more down-to-earth.

Announcements / Re: Encryption
« on: March 02, 2010, 07:04:56 PM »
I'm afraid to reread my topic considering the replies are exactly what I was trying to convey. ;_;

Really, my biggest fear is room tampering.

Announcements / Encryption
« on: March 02, 2010, 09:04:44 AM »
Despite what I'd like to believe (and maybe even what I'd like you to believe), making something in C++ doesn't mean it can't have its resources modified or even stolen. ENIGMA (being C++) makes sure that code isn't such a resource. No one can decompile your game. However, we do have a problem.

Because ENIGMA will be a regular system, unoptimized output executables will have the same basic format. Furthermore, because it is open source, an encryption algorithm is even more futile than it was in Game Maker. I can't just hide a seed and expect everyone to give up before finding it.

Now, in R3, rooms were stored as an array in the source code. This means that it would take a good amount of skill to modify them, but it's still feasible. Someone with a decent knowledge of how GCC handles such could probably make a tool to do it. If ENIGMA were to inherit GM's better disassemblers, we could possibly face problems with such (the hope is that since no one can get all of it, no one will write a tool to get some of it).

Fortunately, as long as you let GCC optimize your code, it should be too irregular to be removable by an automated tool. (Even if it was removed, it couldn't be decompiled other than manually, don't worry.) However, I'm not sure about unoptimized code. It would be far too much work to decompile it back to EDL (especially with the C++ goodness that gets thrown in), but it may be possible to remove entire events and replace them (making games easy to mod or cheat).

What's more, unified sprite and sound encryption is worthless. Pidgin doesn't encrypt passwords it stores for users because the developers understand that in an open source project--and for that matter, in any other project--doing so accomplishes nothing. So ENIGMA can not have a unified encryption system to protect non-code resources.

Personally I don't see this as a problem. However, I know one of the reasons people are in awe of the idea of C++ is that they think it will protect such resources. I can't think of a decent game whose resources aren't an open book (there are many Windows resource extractors. Not to mention, you Valve fans, think Garry's Mod). But, I can think of a way to fix this.

R4, as some of you are aware, will allow you to define C++ functions for use in your game. This is a great way to do with DLLs (but do note that external_define has been done for months). I could allow the implementation of a function called resource_encrypt (and one called resource_decrypt) to allow users to define their own algorithms. This would be done with the hopes that such an algorithm would not be in a uniform position in the executable every time. :eng99: If it was, it'd be as simple as writing a tool to look for like bits of code and extract the new stuff. Though they could still not decompile your code (and I am talking about the algorithm), they could call the decryption algorithm themselves, right where it sits, on whatever resources they extracted. Frankly, I think our better bet is to not waste time on encryption.

To protect room tampering, ENIGMA could hard code their creations in a large function (which would be optimized hopefully to un-uniform gobbledy... but it could still be replaced by a determined expert).

The function could be implemented conditionally; only executing if it has been defined by the user. This is just an idea I'm putting out, thoughts welcome. Especially from assembly people.

TL;DR: Paranoia resulting from the idea of really talented people wasting their time hacking games. Mods are inevitable, resource extraction is hard to stop, decompilation highly unlikely (as in, no one will waste their time on a huge game, and automation is impossible).

Announcements / Re: Rejoice
« on: February 26, 2010, 07:16:50 PM »
#if is how I was going to do it. But that's compile time, so it means we can't have such a function anyway.

Announcements / Re: Rejoice
« on: February 26, 2010, 01:12:24 PM »
...Nothing error related functions can do to stop or resume errors can ever make the code more efficient. Easy way is to use if's, copying code logically doubles size and makes inlining impossible.

Tips, Tutorials, Examples / Re: lol streams
« on: February 25, 2010, 08:23:50 AM »
Duly noted.

Tips, Tutorials, Examples / Re: lol streams
« on: February 24, 2010, 07:38:55 PM »
Does... that work? It should error that your function should be a member of std::ostream rather than declared in the global scope...

Announcements / Re: Rejoice
« on: February 24, 2010, 06:58:36 AM »
Boy, I can't wait to add that.

Announcements / Re: Rejoice
« on: February 23, 2010, 05:21:34 PM »
How'd the documentation for that look?

Announcements / Re: Rejoice
« on: February 23, 2010, 05:17:23 PM »
Oh yes, that's funny. I'm dyslexic, asshole. ...haha.
Fine, maybe I just can't spell old dead people.

Announcements / Re: Rejoice
« on: February 21, 2010, 12:38:37 PM »
Well, I meant more like being able to check functions only in certain moments where the user would want it using the functions, hopefully without too major speed loss. E.g. you could call "error_start()" to start being error checking session and "error_stop()" to stop it, or perhaps "error_object(obj, true)" to check for errors that occur within a certain object and "error_object(obj, false)". Just suggesting...

The former (error_start) leaves two options.
1) Have an if() to check if it's enabled, which wastes the same a mount of time as just doing the damn error checking
2) Use function pointers that can be swapped on error_start(), which removes any chance of inlining.

The latter (error_object) is a terrible idea by any standard. Now instead of one if(), we're looking up whether we are supposed to be generating errors for that object in a... map? Array? Either of them are awful in one way or another (map's lookup time, array's allocation time).

I'd be better off just leaving the errors than to add functions for them, but I'd rather not have them when they aren't needed.

Issues Help Desk / Re: A replacement for draw_text
« on: February 20, 2010, 11:09:09 PM »
The GM6 doesn't store font glyphs as bitmap, they store it by font name. EXE stores the bitmaps.