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 |