04-27-2022, 08:45 PM
Salvaged from the other boards, some of you may have seen this before:
Copy. Paste. Compile. I'll let the code speak for itself and hopefully it'll help folks learn a bit more about WHY certain variables are more suitable for use with 32-bit color values than others.
Code: (Select All)
Screen _NewImage(640, 640, 32)
_Title "Number Types and Colors"
Print "Welcome to Steve's Qucik Lesson on Number Types and Colors."
Print
Print "The most important thing to keep in mind in this lesson is that we're going to be talking exclusively about 32-bit color values here. For all other screen modes, this lesson holds much less importance."
Print
Print "Press <ANY KEY> to begin!"
Sleep
Cls , 0
Print "First, let's talk about how SINGLE variable types work (or DON'T work), in regards to 32-bit colors."
Print
Print "Let's choose a nice color and use it to draw a box on the screen."
Print "How about we choose a BLUE box? _RGB32(0, 0, 255)"
Print
Line (50, 90)-(250, 250), _RGB32(0, 0, 255), BF
Locate 18, 1: Print "Looks like a nice BLUE box. Right?"
Print "Press <ANY KEY> to continue!"
Sleep
Cls , 0
Print "Now, let's store that BLUE value inside a SINGLE tyoe variable."
Print "BLUE = _RGB32(0, 0, 255)"
Print ""
Print "Once we've did that, let's draw the exact same box on the screen again with the variable."
BLUE = _RGB32(0, 0, 256)
Line (50, 90)-(250, 250), BLUE, BF
Locate 18, 1: Print "Looks like a nice BLUE box. Right?"
Print "Press <ANY KEY> to continue!"
Sleep
Cls , 0
Print "What do you guys mean, 'What box?'??"
Print "Do you mean to tell me you nice folks DIDN'T see a pretty BLUE box on the last screen??"
Print
Print
Print "Just what the hell happened to it?!!"
Print
Print
Print "For the answer to that, let's print out two values to the screen:"
Print "BLUE = "; BLUE
Print "_RGB32(0, 0, 255) = "; _RGB32(0, 0, 255)
Print
Print "At first glance, those APPEAR to be the same numbers, but let's expand the scientific notation fully:"
Blue&& = BLUE
Print "BLUE = "; Blue&&
Print "_RGB32(0, 0, 255) = "; _RGB32(0, 0, 255)
Print
Print "Press <ANY KEY> to continue!"
Sleep
Cls , 0
Print "HOLY COW, BATMAN!! Was those two numbers DIFFERENT?!!"
Print "BLUE = "; Blue&&; "vs"; _RGB32(0, 0, 255)
Print
Print "Well... They're only a LITTLE different... Right?"
Print "I mean, how bad can one little number difference be? Right??"
Print
Print "For the answer to that, let's look at the HEX values of those numbers:"
Print "BLUE = "; Hex$(Blue&&)
Print "_RGB32(0, 0, 255) - "; Hex$(_RGB32(0, 0, 255))
Print
Print "And to help understand what we're seeing in HEX, break those values down into groups of 2 in your mind."
Print "(I'm too lazy to do it for you..)"
Print "The first two values are ALPHA, followed by RED, followed by GREEN, followed by BLUE."
Print
Print "So BLUE = FF alpha, 00 red 01 green, 00 blue"
Print "_RGB32(0, 0, 0) = FF alpha, 00 red, 00 green, FF blue"
Print
Print "And keep in mine that FF is HEX for the decimal value of 255."
Print
Print "Press <ANY KEY> to continue!"
Sleep
Cls , 0
Print "Since SINGLE values lose precision after numbers get so large, our variable BLUE"
Print "has to round to the nearest scientific notation point and try for the closest"
Print "possible match."
Print
Print "And even though "; Blue&&; " is only one number off from "; _RGB32(0, 0, 255); ","
Print "that number still greatly changes the color value."
Print
Print "It changes it from FF 00 00 FF (255 alpha, 0 red, 0 green, 255 blue) to"
Print "FF 00 01 00 (255 alpha, 0 red, 1 green, 0 blue)."
Print
Print "Our BLUE has become a GREEN, simply by using a SINGLE variable type!!"
Print "(And, it's such a low shade green, my poor eyes can't make it out at all."
Print "To me, the damn 'green box' was just as black as my black screen."
Print "I didn't see it at all!)"
Print "Press <ANY KEY> to continue!"
Sleep
Cls , 0
Print "So, at this point, I think it should be obvious WHY we don't want to store"
Print "color values inside SINGLE variables."
Print
Print "But what about using a normal LONG to hold the values??"
Print
Print "Let's look and see!"
Print
Print "For this, let's draw our box again:"
Line (50, 150)-(250, 250), _RGB32(0, 0, 255), BF
Locate 18, 1: Print "Looks like a nice BLUE box. Right?"
Print
Print "But let's get the POINT value from that box, and store it in a LONG variable."
BLUE& = Point(100, 200)
Print "BLUE& = "; BLUE&
p&& = Point(100, 200)
Print "POINT(100, 200) = "; Point(100, 200)
Print
Print
Print "Again, we're looking at two numbers that don't match!"
Print
Print "FOR THE LOVE OF GOD, WHYYYY??!!!!"
Print "Press <ANY KEY> to continue!"
Sleep
Cls , 0
Print BLUE&; "<>"; p&&
Print
Print "Why are those two numbers so different??"
Print
Print "For that answer, let's look at their HEX values again:"
Print "BLUE& = "; Hex$(BLUE&)
Print "POINT(100, 200) = "; Hex$(p&&)
Print
Print "."
Print "..."
Print "......"
Print
Print "WHAT THE HEX?? Those two values are EXACTLY the same??"
Print
Print "They are. It's just that one of them is stored as a SIGNED LONG, while the other is an UNSIGNED LONG."
Print
Print "HEX wise, they're the same value..."
Print
Print "BUT, can you see where the two numbers might not match if we use them in an IF statement?"
Print
Print "IF "; BLUE&; "="; p&&; "THEN...."
Print
Print "Ummm... That might not work as intended!"
Print
Print "Press <ANY KEY> to continue!"
Sleep
Cls , 0
Print "Even thought the HEX values for "; BLUE&; "and"; p&&;
Print "are EXACTLY the same, the values themselves are quite different."
Print
Print "A LONG will, indeed, hold the proper value for a 32-bit color, as it stores"
Print "all four HEX values properly for us."
Print
Print "As long as our program uses NOTHING but LONG values, you'll never have a"
Print "problem with using LONG as a variable type..."
Print
Print "BUT...."
Print
Print "The moment you start to compare LONG values directly against POINT values,"
Print "your program is going to run into serious issues!"
Print
Print "Because at the end of the day,"; BLUE&; "is not the same as "; p&&
Print
Print
Print "Press <ANY KEY> to continue!"
Sleep
Cls , 0
Print "So, with all those examples, and all that said, let's answer"
Print "the most important question:"
Print
Print "'What TYPE works best for 32-bit colors??"
Print
Print
Print "DOUBLE, _FLOAT, _UNSIGNED LONG, _INTEGER64, _UNSIGNED _INTEGER64"
Print
Print "Of all the types which QB64 offers, only the above are TRULY viable"
Print "to hold a 32-bit color value."
Print
Print "Any type not listed above is going to be problematic at one time or"
Print "another for us!"
Print
Print "And of those suitable types, I personally prefer to keep integer values"
Print "as integers, so I recommend: _UNSIGNED LONG or _INTEGER64."
Print
Print
Print "Press <ANY KEY> to continue!"
Sleep
Cls , 0
Print "And WHY _UNSIGNED LONG??"
Print
Print "Simply because it's only 4 bytes of memory (the minimal we can possibly use for"
Print "32-bit color values), and it's what QB64 uses internally with POINT and such."
Print
Print
Print "So, if _UNSIGNED LONG works so well, WHY would I *ever* use _INTEGER64??"
Print
Print "Becauses sometimes I like to code command values into my colors."
Print "(Such as: NoColor = -1)"
Print
Print "_UNSIGNED LONG *only* holds the values for the colors themselves."
Print "EVERY number from 0 to FFFFFFFF is accounted for as part of our color spectrum."
Print
Print "If I need *special* or unique values for my program, I usually just use _INTEGER64s"
Print "for my variable types and then I can assign negative numbers for those unique values."
Print
Print
Print "Press <ANY KEY> to continue!"
Sleep
Cls , 0
Print "At the end of the day though, when all is said and done, you're still the"
Print "one responsible for your own code!"
Print
Print "Use whichever type works for you, and works best for your needs."
Print
Print "Just keep in mind: Various TYPEs come with various limitations on your code."
Print
Print "_BYTE, INTEGER, (both signed and unsigned) are insane to use..."
Print "SINLGE loses precision. Expect to lose whole shades of blue...."
Print "LONG may cause issues with POINT, if compared directly...."
Print "_UNSIGNED LONG works fine, any ONLY stores 32-bit color values...."
Print "_INTEGER64 works fine, and can store extra values if necessary...."
Print "DOUBLE and _FLOAT both work, but are floating point values...."
Print
Print
Print "And with all that said and summed up, it's now up to YOU guys to decide what"
Print "works best in your own programs."
Print
Print
Print "As I said, I personally recommend _UNSIGNED LONG or _INTEGER64 in special cases."
Print "But the choice, and the debugging, is entirely up to YOU. :D"
Copy. Paste. Compile. I'll let the code speak for itself and hopefully it'll help folks learn a bit more about WHY certain variables are more suitable for use with 32-bit color values than others.