Thread: [GD-General] Protecting our game
Brought to you by:
vexxed72
From: <cas...@ya...> - 2002-12-29 21:22:20
|
Hi, I'd like to know how do games usually store the number of times played, the registration key, and other critical information, that should remain on the computer if the user decides to uninstall and reinstall the game. The registry is easy to monitor, you can store the data enchrypted, but removing the entire key you don't know if the game has just been installed or if the user has removed it on purpouse. How is this usually solved? Thanks in advance, Ignacio Castaño cas...@ya... ___________________________________________________ Yahoo! Postales Felicita las Navidades con las postales más divertidas desde http://postales.yahoo.es |
From: Ivan-Assen I. <as...@ha...> - 2002-12-31 13:57:53
|
my $0.02: 15 minutes spent with FileMon and RegMon from http://www.sysinternals.com should convince anyone that spewing random garbage in the registry or in MS-bla-blah-32.DLL files in the System folder is useless. So, if you just want to turn down the casual users who have no idea what the registry is, it's good "regiquette" to place your already-installed flag in HKLM\Software\YourCompany\YourProduct. |
From: Pierre T. <p.t...@wa...> - 2003-01-02 22:57:28
|
Here's something I don't get.... I was looking for the smallest floating-point value F such as F^2 doesn't underflow. So, I wrote something like : F^2 = FLT_MIN ; => F = sqrtf ( FLT_MIN ) ; Then, as a test, I wrote : const float HalfSqrtFMin = sqrtf(FLT_MIN) * 0.5f; const float f = HalfSqrtFMin*HalfSqrtFMin; I was expecting f to be zero due to underflow. Yet it wasn't. That was my first clue something weird was going on. So I investigated a bit more and found that the floating-point value I was looking for was 1.40130e-045, which gives zero once squared. This is the floating-point value whose binary representation is 0x00000001. I've always thought FLT_MIN was the "min positive value" (as stated in Float.h). What the hell is that number then ? I'm sure I'm missing something obvious.... Pierre PS: http://www.codercorner.com/FPU.jpg |
From: Colin F. <cp...@ea...> - 2003-01-03 08:02:18
|
2003 January 2nd Thursday Pierre, IEEE 32-bit floats are in the following format: SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM 33222222222211111111110000000000 10987654321098765432109876543210 The 8 exponent bits EEEEEEEE form a number from 0 to 255. The interpretation of this exponent is as follows: 0 : Denormalized number; No implicit leading "1" bit in mantissa; First bit in explicit mantissa bits (MMMMM...) is now the actual leading bit with an effective value of 1.0; Exponentiated value is (2^(-127)). 1..254 : Exponent is (EEEEEEEE - 127) 255 : Mantissa contains special number codes (NaN, undefined, infinity) Here's a quote from my <float.h> file: #define FLT_MIN 1.175494351e-38F /* min positive value */ This value is roughly equal to 2^(-126), which really *IS* the minimum positive FLOATING POINT value. In bit form: 0:0000001:00000000000000000000000 S = 0; E = 1; M = 1.0 Hence: 1.0 * 2^(1 - 127) = 2^(-126) Your expression: (0.5f*sqrtf(FLT_MIN)) * (0.5f*sqrtf(FLT_MIN)) is not zero, because the product has some room in the "denormalized" range. If the exponent number is "0", then we're in "denormalized" territory. The exponent part is thus (2^(-127)), and the denormalized value can be a single "1" bit in the least-significant bit of the mantissa, with an effective denormalized (no implicit "1" bit) mantissa value of (2^(-22)). Thus, a denormalized number can be as small as: ((2^(-127)) * (2^(-22)) = (2^(-149)) = 1.401298464E-45 roughly. Thus, if you allow for denormalized numbers, 1.401298464E-45 is the minimum positive value, as you have observed. (Or, 0x00000001 in memory viewed as hex, as you pointed out.) --- Colin cp...@ea... http://www.colinfahey.com ----- Original Message ----- From: "Pierre Terdiman" <p.t...@wa...> To: <gam...@li...> Sent: Thursday, January 02, 2003 2:55 PM Subject: [GD-General] FLT_MIN > Here's something I don't get.... > > I was looking for the smallest floating-point value F such as F^2 doesn't > underflow. So, I wrote something like : > > F^2 = FLT_MIN ; > => F = sqrtf ( FLT_MIN ) ; > > Then, as a test, I wrote : > > const float HalfSqrtFMin = sqrtf(FLT_MIN) * 0.5f; > const float f = HalfSqrtFMin*HalfSqrtFMin; > > I was expecting f to be zero due to underflow. Yet it wasn't. That was my > first clue something weird was going on. > > So I investigated a bit more and found that the floating-point value I was > looking for was 1.40130e-045, which gives zero once squared. This is the > floating-point value whose binary representation is 0x00000001. > > I've always thought FLT_MIN was the "min positive value" (as stated in > Float.h). What the hell is that number then ? I'm sure I'm missing something > obvious.... > > Pierre > > PS: http://www.codercorner.com/FPU.jpg > > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Gamedevlists-general mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-general > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_id=557 |
From: Pierre T. <p.t...@wa...> - 2003-01-03 17:40:20
|
> Thus, if you allow for denormalized > numbers, Ok, I found this in the MSDN : _control87( _EM_INVALID, _MCW_EM ); // DENORMAL is unmasked by this call If I use this, an FPU exception is generated on underflow, and resulting values are different indeed. Ok, it makes sense now - I just never really bothered thinking about denormalized values before. However I'm surprised the default state is not to trigger the exception. As long as it works well, I think I'm going to allow denormalized numbers. Any known problems with this ? ------------------ For the records, the whole thing started when a function similar to that one failed in Debug : void MyVector::ClampLength(float limit_length) { float CurrentSquareLength; if((CurrentSquareLength = SquareLength()) > limit_length * limit_length) { float Coeff = limit_length / sqrtf(CurrentSquareLength); x *= Coeff; y *= Coeff; z *= Coeff; } } ( With of course: float MyVector::SquareLength() const { return x*x + y*y + z*z; } ) Fed with this, it bypasses the test and divides by zero anyway : const float MaxLength = 4.91523e-24f; MyVector Dummy(-1.11408e-23f, -4.0593e-24f, 5.51083e-25f); Dummy.ClampLength2(MaxLength); That's a very subtle (and interesting IMHO) bug that happens only because of a combination of bad things : - limit_length squared underflows to zero - SquaredLength is ~10e-46 so it should underflow as well, and the test should become "if( 0 > 0 )" => false => no divide. Yet it doesn't underflow since internally the computation is performed with double-precision, regardless of the code using "float" or "double". So it really does "if (10e-46 > 0)" => true => blam. - the way the function is written, doing the assignment in the "if" (it wouldn't break if it was done when declaring the float, because the 10e-46 would have been assigned to the float, becoming zero) For some reasons it works correctly in Release. Probably just an accident.... Pierre |
From: Colin F. <cp...@ea...> - 2003-01-03 20:58:43
|
> Ok, I found this in the MSDN : > _control87( _EM_INVALID, _MCW_EM ); // DENORMAL is unmasked by this call Hey, that's neat! > As long as it works well, I think I'm going to > allow denormalized numbers. Any known problems > with this ? Loss of precision. 1.4E-45 has one bit of precision! So, in this extreme case you can have up to 50% error in precision, but at least the order of magnitude is still sane. You can have exact powers of two all the way down to (2^(-149)) without loss of precision of course. > That's a very subtle (and interesting IMHO) bug that happens only because of > a combination of bad things : Yes, this is very interesting. I didn't even know about denormalized floats until you mentioned this mystery and I did some research, but now I can see that it is something to be aware of. --- Colin |