GroovyBee Posted June 2, 2015 Share Posted June 2, 2015 In games you often need to convert a variable that keeps track of power, energy, force etc. into something more meaningful to display to the player so they don't always have to think about what the number is and exactly what it means. Lets create a contrived example: Say you want to display the player's remaining fuel as a graphic and not a number. The fuel has 4 limits :- 2/3 to 3/3 - Green 1/3 to 2/3 - Yellow 1 to 1/3 - Red 0 - Death. and is always in the range 0 to 100. So you could code something like this :- mvi thePlayerFuel, r0 cmpi #(100*2)/3, r0 bge @@FuelIsAllGreen cmpi #(100*1)/3, r0 bge @@FuelIsAllYellow cmpi #1, r0 bge @@FuleIsAllRed ; Fuel depleted - Fall through... ... @@FuelIsAllGreen: mvii #FUEL_GREEN, r0 mvo r0, SCREEN_POS(0,0) b @@FuelCommon @@FuelIsAllYellow: mvii #FUEL_YELLOW, r0 mvo r0, SCREEN_POS(0,0) b @@FuelCommon @@FuelIsAllRed: mvii #FUEL_RED, r0 mvo r0, SCREEN_POS(0,0) ; Fall through... @@FuelCommon: ... But a much neater approach is to make use of the carry flag in the compares, so I came up with this :- clrr r1 mvi thePlayerFuel, r0 cmpi #(100*2)/3, r0 adcr r1 cmpi #(100*1)/3, r0 adcr r1 cmpi #1, r0 adcr r1 beq @@FuelDepleted addi #@@FuelConversionTable, r1 mvi@ r1, r1 mvo r1, SCREEN_POS(0,0) ... @@FuelConversionTable: DECLE 0 ; Dummy DECLE FUEL_RED DECLE FUEL_YELLOW DECLE FUEL_GREEN 2 Quote Link to comment https://forums.atariage.com/topic/238994-convert-a-range-to-a-backtab-card/ Share on other sites More sharing options...
+DZ-Jay Posted June 2, 2015 Share Posted June 2, 2015 Nice! I use a similar technique for the tunnel bounds check in Christmas Carol. Thanks for sharing. 1 Quote Link to comment https://forums.atariage.com/topic/238994-convert-a-range-to-a-backtab-card/#findComment-3249294 Share on other sites More sharing options...
GroovyBee Posted June 2, 2015 Author Share Posted June 2, 2015 Nice! I use a similar technique for the tunnel bounds check in Christmas Carol. Yep! Thats a good use, particularly if your GRAM cards are well organised. Quote Link to comment https://forums.atariage.com/topic/238994-convert-a-range-to-a-backtab-card/#findComment-3249295 Share on other sites More sharing options...
Arnauld Posted June 2, 2015 Share Posted June 2, 2015 If you don't mind making a small approximation, you may also consider using the lookup table directly by computing fuel / 33 ~= (fuel * 7) >> 8. Something along those lines: mvi thePlayerFuel, r1 ; r1 = fuel sll r1 ; r1 = fuel * 2 beq @@fuelDepleted ; abort right away if zero sll r1, 2 ; r1 = fuel * 8 sub thePlayerFuel, r1 ; r1 = fuel * 7 swap r1 ; r1 = (fuel * 7) >> 8 andi #3, r1 addi #@@FuelConversionTable, r1 mvi@ r1, r1 mvo r1, SCREEN_POS(0,0) @@FuelConversionTable: DECLE FUEL_RED DECLE FUEL_YELLOW DECLE FUEL_GREEN Of course, this approach makes more sense if you happen to have -- say -- 4 intervals rather than 3 and a fuel counter going from 0 to 255: mvi thePlayerFuel, r1 sll r1, 2 beq @@fuelDepleted swap r1 andi #3, r1 addi #@@FuelConversionTable, r1 mvi@ r1, r1 mvo r1, SCREEN_POS(0,0) @@FuelConversionTable: DECLE FUEL_RED DECLE FUEL_ORANGE DECLE FUEL_YELLOW DECLE FUEL_GREEN 2 Quote Link to comment https://forums.atariage.com/topic/238994-convert-a-range-to-a-backtab-card/#findComment-3249315 Share on other sites More sharing options...
GroovyBee Posted June 2, 2015 Author Share Posted June 2, 2015 If you don't mind making a small approximation, you may also consider using the lookup table directly by computing fuel / 33 ~= (fuel * 7) >> 8. Yep! There are always many ways to solve a problem. This was just an example with fictional colour bands. You might have a graphical gauge with very different points at where the colour changes start/end in your own games. Quote Link to comment https://forums.atariage.com/topic/238994-convert-a-range-to-a-backtab-card/#findComment-3249318 Share on other sites More sharing options...
intvnut Posted June 2, 2015 Share Posted June 2, 2015 For something like this, I'm likely to throw a table at it, similar to Arnauld, but perhaps with more redundancy in the table if that allows me to keep the original ranges. For example, with the 3-color approach, something like this gets close enough: . MOV thePlayerFuel, R1 ; 0 .. 100 SLR R1, 2 ; \_ divide by 16; now 0 to 6 SLR R1, 2 ; / BEQ @@fuel_depleted ADDI #@@fuel_tbl, R1 MVI@ R1, R1 MVO R1, wherever ;... @@fuel_tbl: DECLE FUEL_RED, FUEL_RED ; 0 .. 31 DECLE FUEL_YELLOW, FUEL_YELLOW ; 32 .. 63 DECLE FUEL_GREEN, FUEL_GREEN, FUEL_GREEN ; 64 .. 100 . The larger table is offset by the smaller code. This particular example retains the 0..100 range of the original. Quote Link to comment https://forums.atariage.com/topic/238994-convert-a-range-to-a-backtab-card/#findComment-3249363 Share on other sites More sharing options...
GroovyBee Posted June 2, 2015 Author Share Posted June 2, 2015 Another good solution to the contrived example I provided . But in both cases, if your gauge has band limits at 17, 45, 67 and 91 its not going to be so simple . Quote Link to comment https://forums.atariage.com/topic/238994-convert-a-range-to-a-backtab-card/#findComment-3249364 Share on other sites More sharing options...
intvnut Posted June 2, 2015 Share Posted June 2, 2015 Another good solution to the contrived example I provided . But in both cases, if your gauge has band limits at 17, 45, 67 and 91 its not going to be so simple . True. But just as we snap graphics to BACKTAB tile boundaries, I would probably snap my thresholds to less numerically spiteful values, such as 16, 48, 64 and 96. But lacking that option, abusing the carry bit as you did does work. In one of the early versions of Space Patrol, I used a similar trick when counting the number of active sprites (for the multiplex engine), comparing each sprite's 'attribute number' (an index into a table of sprite attributes) to 0, and adding up the carries. That worked reasonably well. (Later, I changed the representation of the sprite indices, and used a different trick here. To save cycles in the sprite => MOB mapping code, I scaled the sprite attribute index by 4 (since each entry in the sprite attr table was 4 words), and then added 1, to force all active sprites to have non-zero indices. When counting active sprites, I added groups of 3 sprite entries together and then masked with #3, which was even cheaper then the compare-with-zero/ADCR approach.) Quote Link to comment https://forums.atariage.com/topic/238994-convert-a-range-to-a-backtab-card/#findComment-3249369 Share on other sites More sharing options...
+DZ-Jay Posted June 2, 2015 Share Posted June 2, 2015 I think the point of the original post was to show the trick of using the carry bit instead of purely test-and-branch. I think it did that rather well. 1 Quote Link to comment https://forums.atariage.com/topic/238994-convert-a-range-to-a-backtab-card/#findComment-3249485 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.