The full version of my game is in the appstore and now I want to make a lite version as a sort of advertising. The code will be for the largest part exactly the same as the normal full version. Only a few lines have to change so if possible I'd rather not make a separate GLBasic project, keeping in mind possible bugfixes and code maintenance etc.
I saw in this topic (http://www.glbasic.com/forum/index.php?topic=4600.msg34580#msg34580) that you can use the ?IFDEF and ?ENDIF as precompiler commands for glbasic. In that topic it is used to determine whether you're compiler for iphone or not.
My question is, can I use ?IFDEF and ?ENDIF to check for a custom ?DEFINE, and if so how does it work? I've tried the code example below but that doesn't seem to work. It always gets to the if-part of the ?IFDEF, regardless of wether or not I disable that first ?DEFINE line it never goes to the else-part.
?DEFINE CompileLiteVersion
?IFDEF CompileLiteVersion
DEBUG "lite version\n" // if-part
?ELSE
DEBUG "This is NOT the lite version\n" // else-part
?ENDIF
You could have the debug version has the lite one, and then you could check using ?IFDEF GLB_DEBUG
You can't just disable that line with //, it doesn't care about comment lines or not. You have to delete the whole line or at least separate the ? and define with a space in the comment mabe?
This should work:
?DEFINE CompileLiteVersion
?IF CompileLiteVersion
DEBUG "lite version\n" // if-part
?ELSE
DEBUG "This is NOT the lite version\n" // else-part
?ENDIF
That's if the following works, taken from the 'Preprocessor Commands' from the Help file:
?IF GLB_VERSION < 7.0
?ERROR Precprocessor not enabled ;)
?ENDIF
?IF WIN32
?DEFINE FASTGFX
?ENDIF
?IF FASTGFX
STARTPOLY -1
POLYVECTOR 0, 0, 0,0, 0xffffff
POLYVECTOR 0,99, 0,0, 0xffffff
POLYVECTOR 99,99, 0,0, 0xffffff
ENDPOLY
?ELSE // slow graphics ->
DRRAWRECT 0,0,99,99, 0xffffff
?ENDIF
Quote from: Moru on 2011-Jan-24
You can't just disable that line with //, it doesn't care about comment lines or not. You have to delete the whole line or at least separate the ? and define with a space in the comment mabe?
Aha, I was commenting the line, thanks for the tip :good: So to be clear, in the following code the MyDefLite is defined, even though the line is commented out
// ?DEFINE MyDefLite
?IFDEF MyDefLite
DEBUG "code WILL get here\n"
?ENDIF
and in the following MyDefLite is not defined so it never gets to the debug line
// ? DEFINE MyDefLite // or delete this line
?IFDEF MyDefLite
DEBUG "code will NOT get here\n"
?ENDIF
hm, it seems like a bug though.. why does the preprocessor handle a commented line? O_O
Commented lines or line parts should be discarted (deleted) by the preprocessor.
You can use "?UNDEF MyDefLite" to disable the variable too.
and to be sure the right code is picked, add ?WARNING messages.
Okay, I finished going through the project and changing small things for the lite version using the ?IFDEFs. :) I just uploaded the app, now waiting for app approval..
*small kick*
How can I use the ?IFDEF and ?ENDIF commands to recognise if I compile in "Debug Mode" or not (selected in the Compiler menu)? I noticed that the gpc_temp.h file starts with the line "#define WANT_GLB_DEBUGGER 1" when Debug Mode is checked, but I tried the following and it didn't work. With the debugmode checked or unchecked the debug texts never display (compiling in Windows btw).
?IFDEF WANT_GLB_DEBUGGER
DEBUG "code never gets here\n"
?ENDIF
?IFDEF DEBUG
DEBUG "and code never gets here\n"
?ENDIF
?IFDEF GLB_DEBUG
?WARNING "Using Debug Mode"
?ENDIF
Ah thanks, that works :good:
*major kick* :)
How can I check for combinations of defines? Specifically, I want to make an exception in the lite version for Android, so I want something like ?IF DEFINED(blah) AND NOT DEFINED(boo). I've tried this but it gives an compiler error "syntax error : ... notdefined((1))", see example code below
?DEFINE MYDEF_LITE_VERSION
?DEFINE MYDEF_TEST_ANDROID
?IF DEFINED(MYDEF_LITE_VERSION)
DRAWRECT 80, 80, 80, 80, RGB(255, 0, 0) // lite, red rectangle
PRINT "test lite", 160, 80
?ENDIF
?IF DEFINED(MYDEF_TEST_ANDROID)
DRAWRECT 80, 200, 80, 80, RGB(255, 255, 0) // normal, yellow rectangle
PRINT "test android", 160, 200
?ENDIF
// next line is problem
?IF DEFINED(MYDEF_LITE_VERSION) AND NOT DEFINED(MYDEF_TEST_ANDROID)
DRAWRECT 80, 320, 80, 80, RGB(255, 0, 255) // lite but not android, purple rectangle
PRINT "lite, not android", 160, 320
?ENDIF
SHOWSCREEN
KEYWAIT
Any ideas? :doubt:
Does this work for you?: (ie. nesting)
?IFDEF MYDEF_LITE_VERSION
?IFNDEF MYDEF_TEST_ANDROID
...
?ENDIF
?ENDIF
I only see a 'DEFINED' and no 'NDEFINED' (or similar).
You can 'AND', and 'OR' and such, but you would need a 'NOT' operator too added.
You could reverse your 'MYDEF_TEST_ANDROID' define for the opposite meaning:
?DEFINE MYDEF_PRODUCTION_ANDROID // As opposed to 'MYDEF_TEST_ANDROID'
// Then this should be the equivalent to what your want:
?IF DEFINED(MYDEF_LITE_VERSION) AND DEFINED(MYDEF_PRODUCTION_ANDROID)
You may need to define BOTH for your needs, and change them BOTH to switch modes.
But at least there's a '?IFNDEF' command.
I also tried ?IFNDEF blah AND DEFINED(boo) but that didn't give the expected result. And if I combine DEFINED with a nested IFNDEF, it displays the purple rectangle when both MYDEF_LITE_VERSION and MYDEF_TEST_ANDROID are not defined. :blink: that's not right..
?IF DEFINED(MYDEF_LITE_VERSION)
?IFNDEF MYDEF_TEST_ANDROID
// lite and not android, purple rectangle
DRAWRECT 80, 320, 80, 80, RGB(255, 0, 255)
PRINT "lite, not android", 160, 320
?ENDIF
?ENDIF
But I tried nesting and this next bit does what I want :good: thanks
?IF DEFINED(MYDEF_LITE_VERSION)
?IF DEFINED(MYDEF_TEST_ANDROID)
// nothing
?ELSE
// lite and not android, purple rectangle
DRAWRECT 80, 320, 80, 80, RGB(255, 0, 255)
PRINT "lite, not android", 160, 320
?ENDIF
?ENDIF
why not use a simple IF/THEM?
IF demo=0
debug "Not demo!"
ELSE
debug "Demo!"
ENDIF
If you want to hide it a little (so it will not cracked), name DEMO to something else as DFWP at the start of your code:
DFWP=SQR(4)-1
Notice that game code is not changed by pirates in iOS. They just patch the iOS routines that check validations. If huge games as Infinity Blade has not been altered to get unlimited money, I think your's will not be...
You can also do :
?IF DEFINED(X) OR DEFINED(Y) AND ... etc
Quote from: ampos on 2012-Apr-19
why not use a simple IF/THEM?
IF demo=0
debug "Not demo!"
ELSE
debug "Demo!"
ENDIF
If you want to hide it a little (so it will not cracked), name DEMO to something else as DFWP at the start of your code:
DFWP=SQR(4)-1
Notice that game code is not changed by pirates in iOS. They just patch the iOS routines that check validations. If huge games as Infinity Blade has not been altered to get unlimited money, I think your's will not be...
This idea not are very good for avoid cracking apps... the variable DEMO maybe are stored on any kind of file... the cracker can compare full/lite versions to find this file changed...
Right?
For my game I think release two versions... one full... and other (lite) with many REMs for deactivate full features...
Quote from: Hark0 on 2012-Apr-20
Quote from: ampos on 2012-Apr-19
why not use a simple IF/THEM?
IF demo=0
debug "Not demo!"
ELSE
debug "Demo!"
ENDIF
If you want to hide it a little (so it will not cracked), name DEMO to something else as DFWP at the start of your code:
DFWP=SQR(4)-1
Notice that game code is not changed by pirates in iOS. They just patch the iOS routines that check validations. If huge games as Infinity Blade has not been altered to get unlimited money, I think your's will not be...
This idea not are very good for avoid cracking apps... the variable DEMO maybe are stored on any kind of file... the cracker can compare full/lite versions to find this file changed...
Right?
My idea is that if even Infinity Blade has not been cracked, will ours be? I doubt.
Quote from: ampos on 2012-Apr-19
why not use a simple IF/THEM?
IF demo=0
debug "Not demo!"
ELSE
debug "Demo!"
ENDIF
If you want to hide it a little (so it will not cracked), name DEMO to something else as DFWP at the start of your code:
DFWP=SQR(4)-1
Notice that game code is not changed by pirates in iOS. They just patch the iOS routines that check validations. If huge games as Infinity Blade has not been altered to get unlimited money, I think your's will not be...
You're right, it probably won't be cracked because finding the variable in the compiled binary is very hard. Btw, the variable names as you write them in GLB code are not included in the final binary. The compiler will convert them to memory addresses, so it doesn't really matter what you call them. Any potential hacker would have to decompile the binary and go through the compiler generated (=totally unreadable) code looking for some variable that *might*maybe* do something he wants.
However, you are basically using a variable as if it's a constant or a preprocessor define. So why not use a preprocessor define instead, as this is exactly what their purpose is for.
Quote from: Hark0 on 2012-Apr-20
For my game I think release two versions... one full... and other (lite) with many REMs for deactivate full features...
no, no, please.. do yourself a favor and see the opening post. If you use the preprocessor defines, you can use the same GLB project to maintain both the lite and full versions. At least for me this works perfectly.
?DEFINE DEF_MAKE_LITE_VERSION
// .. code
?IFDEF DEF_MAKE_LITE_VERSION
// display label "full version available"
MyGameDisplayFullVersion()
?ELSE
// full version feature
MyGameOptionsScreen()
?ENDIF
Quote from: BdR
You're right, it probably won't be cracked because finding the variable in the compiled binary is very hard. Btw, the variable names as you write them in GLB code are not included in the final binary. The compiler will convert them to memory addresses, so it doesn't really matter what you call them. Any potential hacker would have to decompile the binary and go through the compiler generated (=totally unreadable) code looking for some variable that *might*maybe* do something he wants.
Sorry... but.... How store the variable? Maybe in a file NOT in the "exe"...
If you compile FOR DEBUG... you have yet a Version "A"...
If you compile FOR RELEASE... you have ANOTHER version "B"...
Right?
Quote from: BdR on 2012-Apr-20
Quote from: Hark0 on 2012-Apr-20
For my game I think release two versions... one full... and other (lite) with many REMs for deactivate full features...
no, no, please.. do yourself a favor and see the opening post. If you use the preprocessor defines, you can use the same GLB project to maintain both the lite and full versions. At least for me this works perfectly.
?DEFINE DEF_MAKE_LITE_VERSION
// .. code
?IFDEF DEF_MAKE_LITE_VERSION
// display label "full version available"
MyGameDisplayFullVersion()
?ELSE
// full version feature
MyGameOptionsScreen()
?ENDIF
I have been readed but I no understand HOW the app knows where is his own state. O_O
Can you explain-me? :blink:
They fantastic point ist, that ?IF / ?IFDEF is for precompiler, you can use it to automate kicking out some code from your project. If you want something not to be in your demo, just use this and it wount even get compiled! Thats why it cracker wont be able to hack it, cuz they cant hack what isnt in your binary.
And if you want to compile full version, just change the ?DEFINE and precompiler does all the work for you.
Its just awesome, isnt it? =D
Very!
I do not understand.... :glare:
Quote from: Hark0 on 2012-Apr-20
Sorry... but.... How store the variable? Maybe in a file NOT in the "exe"...
The way ampos does it, is that he "stores" the variable value by including a line of code that sets the variable, so for example the full version could works like this:
Demo = 0
//..rest of code
IF (Demo = 0)
// full version, allow user access to all 100 levels
ELSE
// demo version, allow user access only to first 5 levels
ENDIF
And when you want to create the demo version, you only have to change one line and then you compile again, like this.
Demo = 1
//..rest of code unchanged
Btw this is called a "hardcoded" value, because it's a value in the program, not a value read from an external data or settings file.
This way, the binary for the DEMO and FULL versions are almost identical, except for "Demo = 1" or "Demo = 0" line. So in theory, an evil hacker *could* try to find the byte in the binary that sets the 0 or 1, so he can change the DEMO app to FULL version. (although I think this is a lot of work and very difficult, so I doubt any hacker will even try it)
Quote from: Hark0 on 2012-Apr-20
I have been readed but I no understand HOW the app knows where is his own state. O_O
Can you explain-me? :blink:
It's not one app that knows a DEMO and a FULL state.. The DEMO app and FULL app are two separate apps.
You as the programmer decide to create/compile the DEMO or FULL version of the program. You do this by including or not including the DEFINE line before compiling to final executable. And then the compiler will include or exclude certain parts of the code (based on the ?IFDEF ?ELSE ?ENDIF commands) to create either the DEMO app or the FULL app.
So the binary for the DEMO only contains code for the demo version, and the binary for the FULL version only contains code for the full version. So in this case, an evil hacker cannot change the DEMO app to a FULL app.
Here's a site that explains the purpose of these preprocessor commands, and their benefits:
(It is 'C++' based, but the concepts mostly apply to GLBasic too, which uses '?' instead of '#' as a prefix)
http://wiki.answers.com/Q/Explain_preprocessor_directives_in_c_plus_plus (http://wiki.answers.com/Q/Explain_preprocessor_directives_in_c_plus_plus)
Quote from: BdR on 2012-Apr-20
Quote from: Hark0 on 2012-Apr-20
Sorry... but.... How store the variable? Maybe in a file NOT in the "exe"...
The way ampos does it, is that he "stores" the variable value by including a line of code that sets the variable, so for example the full version could works like this:
Demo = 0
//..rest of code
IF (Demo = 0)
// full version, allow user access to all 100 levels
ELSE
// demo version, allow user access only to first 5 levels
ENDIF
And when you want to create the demo version, you only have to change one line and then you compile again, like this.
Demo = 1
//..rest of code unchanged
Btw this is called a "hardcoded" value, because it's a value in the program, not a value read from an external data or settings file.
This way, the binary for the DEMO and FULL versions are almost identical, except for "Demo = 1" or "Demo = 0" line. So in theory, an evil hacker *could* try to find the byte in the binary that sets the 0 or 1, so he can change the DEMO app to FULL version. (although I think this is a lot of work and very difficult, so I doubt any hacker will even try it)
AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH!
YES!!!! NOW YES!!!!
:good: :good:
(It's same my variable Idevice=true/false in my project for test paths..... ;))
Quote from: BdR on 2012-Apr-20
Quote from: Hark0 on 2012-Apr-20
I have been readed but I no understand HOW the app knows where is his own state. O_O
Can you explain-me? :blink:
It's not one app that knows a DEMO and a FULL state.. The DEMO app and FULL app are two separate apps.
You as the programmer decide to create/compile the DEMO or FULL version of the program. You do this by including or not including the DEFINE line before compiling to final executable. And then the compiler will include or exclude certain parts of the code (based on the ?IFDEF ?ELSE ?ENDIF commands) to create either the DEMO app or the FULL app.
So the binary for the DEMO only contains code for the demo version, and the binary for the FULL version only contains code for the full version. So in this case, an evil hacker cannot change the DEMO app to a FULL app.
Yes yes, right! I understand... :)