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 04, 2010, 06:23:53 pm »
Retro and other concerned individuals:

In the case that strings are involved, it'd be a hijacked switch. What I was hinting at is basically this (assume that the hash of "hello" and "herro" is 143):

Code: [Select]
case 143:
  if (enigma::sval == "hello") { ... }
  if (enigma::sval == "herro") { ... }

Note, however, a couple things:
1) Ideally, the hash function would be played with a little bit to try to achieve the fewest collisions possible
2) An actual hijacked switched statement would look more like this:
Code: [Select]
switch hash()
    case hash: if (...) goto ...
    case hash: if (...) goto ...
3) The most ideal option, but perhaps a more difficult one, is to do the hash map myself, storing pointers to goto labels in my own array (this is legal in C)
This would look like this:
goto enigma::hashmap_switch_1[sval];
Where operator[] computes the hash, starts raiding pre-defined buckets for the correct label, then returns it for jump. This is how switch() actually works, and how I hope to do it.

Announcements / Re: Encryption
« on: March 04, 2010, 06:07:50 pm »
Hmmmm... ENIGMA would be great for server side code if the graphics system could be disabled as easily as I intend...
Code to implement the framework for a set of simple checks could be integrated into the parser or something, but I'm not making any promises until I have a plan for such. Doesn't help that I hate coding online things.

Announcements / Re: Pride
« on: March 03, 2010, 06:20:22 pm »

Oh, and Fede: Many people use primitives for circle-related effects. Think ripples or rings. Especially awesome with surfaces.

Announcements / Re: Pride
« on: March 03, 2010, 01:49:58 pm »
I do love my parentheses (and messing with you). Really, they're mostly for thoughts that might confuse the rest of the sentence; I separated them because they are confusing or because they are pieces of info that those who read them should probably know.


Since if I even hint it's toward the end of the month, you'll guess what day it is, I may as well tell you I want it out on April Fool's day. I might release some things for testing around the 15th or 20th.

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.