+Gemintronic Posted March 5, 2013 Share Posted March 5, 2013 Basically, if you've come up with a novel technique for code ease, speed, size or economy of variables post it here. Examples are worth a thousand words. Oh, and don't be shy of posting on techniques at are only SLIGHTLY different. Every viewpoint or take on a problem counts. My first try? TheLoon Tip #1 (EASE OF CODING) - Constants for colors. Not everyone remembers $0E is white. Using constants to pick colors can be easier than constantly flipping through VisualbBs chart. Also, it lends greater readability to your fellow coders should they peruse your code. A further use would be to have a comparable set of constants for both NTCS and PAL. Choosing between regions would be as easy as removing the color set for the opposite standard. Here are my colors: rem My 25 standard colors for NTSC const _brown = $F2 const _pink = $3C const _skyblue = $98 const _olive = $E4 const _lilac = $7A const _aqua = $B8 const _orange = $38 const _blue = $86 const _red = $46 const _purple = $64 const _lime = $DA const _gold = $2E const _navy = $84 const _green = $C6 const _maroon = $42 const _yellow = $1E const _fuchsia = $58 const _cyan = $A6 const _white = $0E const _ltgray = $0C const _silver = $0A const _gray = $08 const _dkgray = $02 const _black = $00 const _tan = $FC const _forestgreen = $D2 3 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 5, 2013 Share Posted March 5, 2013 For me, trying to remember something like _lilac is harder than just selecting a color from either Visual batari Basic's color chart or from one of these color charts: www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#colorchart www.randomterrain.com/atari-2600-memories-tia-color-charts.html#ntsc_color_tool This isn't exactly a trick, but I start variable aliases with one underscore and labels with two underscores. Then I don't have to worry if I'm using a keyword by mistake and I don't have to worry if a label has the same name as a variable alias. 1 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted March 5, 2013 Author Share Posted March 5, 2013 @R.T. I like your style. If we're gonna comment on the tips we may as well try to add one of our own at the same time. The topic would get pretty dirty fast if we all called out the lunacy of my techniques TheLoon Tip #2 (ECONOMY OF VARIABLES) - Boolean and tender Variables are very scarce in bB. If something is either one state or another then you can use single bits out of a variable to store that state. making boolean variables is a two step process. First, we must use up a variable: dim boolean = a THEN we use defines to cut up our one variable into up to 8 true/false variables. The {0} through {7} part marks which bit in variable a to use. def enemydir=boolean{0} def canshoot=boolean{1} def scrolling=boolean{2} def heatseeking=boolean{3} def youwon=boolean{4} etc.. The one variable a was defined multiple times in different bit-wise places to give us up to 8 different boolean variables! Remember: you must make your if .. then statements slightly different when using bitwise values. They look more like this: rem If scrolling (boolean{2}) equals 1 (true) then scroll down. if scrolling then pfscroll down Notice we didn't say if scrolling = 1? We CAN, however declare scrolling = 1 to indicate scrolling should be true and scrolling = 0 for false. IF .. THEN statements just can't handle it the = 0/1 way. Another gotcha is that we cannot use constants for bitwise statements. So if scrolling = _false is out of the question (if _false is defined as a constant) 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted March 5, 2013 Share Posted March 5, 2013 Nice topic, theloon! RevEng Tip #1 - organising a large multi-bank game When I'm working on a large multi-bank game, I add descriptions of what each bank does to the bB compile messages. It allows me to see at a glance which part of the program is getting tight on space, and allows me to quickly jump to the right bit of code I want by searching for the bank. Here's an example of the description for the first bank in 21 Blue... asm echo " " echo "****** Starting a new pass..." echo " " echo "BANK 1: main game loop." end ...and the sample output from compiling 21 Blue... ****** Starting a new pass... BANK 1: main game loop. 106 bytes of ROM space left in bank 1 BANK 2: girl data, game+minigame vblank code. (soundfx, score adjust) 51 bytes of ROM space left in bank 2 BANK 3: girl data, titlescreen basic code. 112 bytes of ROM space left in bank 3 BANK 4: girl data, player/dealer hand score updater, draw boss-dealer. 18 bytes of ROM space left in bank 4 BANK 5: girl data, main blakjuko code. 62 bytes of ROM space left in bank 5 BANK 6: titlescreen kernel. 20 bytes of ROM space left in bank 6 BANK 7: kernel to draw chat, cards, etc. 148 bytes of ROM space left in bank 7 BANK 8: girl data, blakjuko utility routines, atarivox routines. 54 bytes of ROM space left in bank 8 Build complete. 1 1 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 5, 2013 Share Posted March 5, 2013 I ran into all kinds of weird, pull your hair out, suicide-inducing problems when using def in a very large program, so I gave up and use dim instead. Here's an example: rem **************************************************************** rem * rem * Create aliases for variables. rem * rem **************************************************************** rem ` rem ` (You can have more than one alias for each variable.) rem ` rem ```````````````````````````````````````````````````````````````` rem ` BitOp group 01. rem ` dim _BitOp_Group_01 = i rem ```````````````````````````````````````````````````````````````` rem ` Tells program when to flip the playfield colors. rem ` dim _Bit0_Color_Flip = i rem ```````````````````````````````````````````````````````````````` rem ` Keeps collision detection from registering more than once. rem ` dim _Bit1_Player_Hit_Wall = i rem ```````````````````````````````````````````````````````````````` rem ` Turns the bonus item on or off. rem ` dim _Bit2_Bonus_On_Off = i rem ```````````````````````````````````````````````````````````````` rem ` Channel 0 sound effects (group 1). rem ` dim _BitOp_Sound_Ch_0_Group_01 = j rem ```````````````````````````````````````````````````````````````` rem ` Player hit wall sound effect. rem ` dim _Bit0_Sound_Wall_Hit = j rem ```````````````````````````````````````````````````````````````` rem ` Channel 01 sound effects (group 1). rem ` dim _BitOp_Sound_Ch_1_Group_01 = k rem ```````````````````````````````````````````````````````````````` rem ` Bonus item appearance sound effect. rem ` dim _Bit0_Sound_Bonus_Appear = k Here's a small example in use: if _Bit0_Sound_Wall_Hit{0} then goto __Sound_Effect_Wall_Hit Here's a tip for this thread. Instead of underlining title text, which usually means link on the internet, use larger, bold text. So instead of this: TheLoon Tip #3 (SPEED) - Eventually, everyone's survival rate falls to 0 You'd use this: TheLoon Tip #3 (SPEED) - Eventually, everyone's survival rate falls to 0 Or this: TheLoon Tip #3 (SPEED) - Eventually, everyone's survival rate falls to 0 Or this: TheLoon Tip #3 (SPEED) - Eventually, everyone's survival rate falls to 0 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted March 5, 2013 Author Share Posted March 5, 2013 TheLoon Tip #3 (SPEED) - Eventually, everyone's survival rate falls to 0 According to R.T.s guide some variables get cleared after each DRAWSCREEN. We can actually use that expectation to simplfy and speed up our code. For instance, if we assume a variable is used up as a counter (dim counter = a) and an alarm for an animation is defined as such (def march = counter{4}) we can do this: if march then REFP0 = 8 : REFP1 = 8 So, every time the forth bit of counter gets set to 1 we change the reflection flag on player0 and player1. When march is 0 (false) DRAWSCREEN already makes the reflection = 0 for both sprites without us doing any more code ourselves. Quote Link to comment Share on other sites More sharing options...
RevEng Posted March 5, 2013 Share Posted March 5, 2013 RevEng Tip #2 - display how much rom a section of code uses Putting a couple of labels around the section of code and a single line of asm will allow you to see how many bytes the routine takes. rem ** checking how much space a particular bit of code uses player0: %11111111 %11111111 %11111111 %11111111 end player0x=80 player0y=40 mainloop COLUP0=$98 drawscreen control if joy0left then player0x=player0x-1 if joy0right then player0x=player0x+1 if joy0up then player0y=player0y-1 if joy0down then player0y=player0y+1 controlend goto mainloop asm echo "DEBUG: the joystick control uses ",(.controlend-.control)d," bytes." end Here's the compilation output... Starting build of scratch.bas batari Basic v1.01 (C)2005-2007 2600 Basic compilation complete. DEBUG: the joystick control uses 32 bytes. bytes of ROM space left DEBUG: the joystick control uses 32 bytes. 2809 bytes of ROM space left Build complete. 4 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted March 5, 2013 Author Share Posted March 5, 2013 @R.T. I'll defer to your professional web expertise. No underlines.. sigh TheLoon Tip #4 (ECONOMY OF VARIABLES) - You don't hafta work for the TSA to screen If you lay out your game correctly you can use the playfield for both visual queues and variable use. For instance, in my game M.M.S.B.C. II the topmost playfield pixels represent the main heath bar: playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX <-- ................................ ................................ ................................ ...........X..................X. ..........XXXXX..............X.X ....................X........... X..XXX.X.X.X..XX.X.X.X.X..X..XXX X..X.X.X.X.X.X...X.X.X.X..X..X.. X..X.X.X.X.X..X..X.X.X.X..X..XX. X..X.X.X.X.X...X.X.X.X.X..X..X.. XX.XXX.XXX.X.XX...X..X.XX.XX.XXX end As the players lose hit points the rightmost pixels get turned off until even the very leftmost pixels are gone. AT THAT POINT the var0 (top-leftmost 8 pixels) should equal 0. if var0 = 0 then goto game_over Notice I didn't have to use a variable for that main health stat! 2 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted March 5, 2013 Author Share Posted March 5, 2013 TheLoon Tip #5 (GRAPHICS) - Flip the ball over for massive damage! While the missiles and balls can only be one rectangular shape at a time we can alternate between shapes to create distinct objects! Once again this example relies on a variable called counter that increments once every main game loop. Since counter{0} is true every other frame we can use that to change our missile/ball shape quickly enough so that our eyes see a more complicated shape - in this case a sword with hilt! draw_weapon bally = bally - 2 if bally < 4 then bally = 0 : ballx = 0 : return if counter{0} then goto shaft else goto hilt shaft ballx = ballx + 1 bally = bally + 2 CTRLPF = $11 ballheight = 9 return hilt ballx = ballx - 1 bally = bally - 2 CTRLPF = $21 ballheight = 1 return There are one or two gotchas with this technique. First off, any area of the sword that isn't overlapping both frames of animation will be semi-transparent. So, count on the edges of the hilt and tip/handle of the sword to be darker than the middle. In addition, collision will be effected due to the actual ball/missile being shifted around each frame. 2 Quote Link to comment Share on other sites More sharing options...
RevEng Posted March 7, 2013 Share Posted March 7, 2013 RevEng Tip #3 - (GRAPHICS) cheap transporter/yars safety zone/explosion with the standard kernel Originally from this thread. (well, originally from Yar's Revenge) You can point the player data pointers to random game code, and set the height as you like. If you test this with a an empty program the effect will be be more solid, but as your bank fills up with code the effect will become more randomish. datastart const datastarthi=(#>.datastart) player0x=50 player0y=90 player0height=90 player0pointerhi=datastarthi gameloop rem divide by two to avoid hotspots in bank-switched games... player0pointerlo=rand/2 COLUP0=rand REFP0=rand NUSIZ0=$07 drawscreen goto gameloop 1 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted May 7, 2013 Author Share Posted May 7, 2013 TheLoon Tip #6 (EDITOR) - Import Changes back into VisualbB Sometimes you may start out creating a sprite or playfield in the VisualbB editor but end up hand tweaking things until your code and VisualbB don't match. Fear not! You can manually re-import the changes with ease! 1. Select the entire pfcolors: and playfield/playercolors: section for your sprite or playfield in your code and copy them to the clipboard. Make sure you copy *just* the bare two sections mentions and not any extraneous code. 2. Open your original sprite/playfield in VisualbB. 3. Right mouse-click on your selected sprite.spr or playfield.pla filename and hit "View in Notepad..." 4. In notepad clear out the old contents and PASTE the contents of the clipboard. 5. SAVE in Notepad. 6. Back in VisualbB right mouse-click on the sprite.spr or playfield.pla we were working with and hit Reload. BAM! Now our hand-tweaked items are back in the full editor for great justice. Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted May 7, 2013 Share Posted May 7, 2013 You can also save your program with a different name, then right click on it in the Project Explorer and select Generate Items From Code. You'll have a fresh, updated batch of sprites and playfields to play with. Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted May 7, 2013 Author Share Posted May 7, 2013 You can also save your program with a different name, then right click on it in the Project Explorer and select Generate Items From Code. You'll have a fresh, updated batch of sprites and playfields to play with. Sounds like a different, but useful tip in itself! Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted May 7, 2013 Share Posted May 7, 2013 Sounds like a different, but useful tip in itself! It's very useful if you change a lot of sprite frames in your program without using the sprite editor, then wish to edit them with the sprite editor later. Quote Link to comment Share on other sites More sharing options...
abaudrand Posted June 19, 2013 Share Posted June 19, 2013 Ive read the tip 1 of revenge with the echo command but I lack knowledge how I can use it to write the state of a variable. I would like to see which number is stored on a certain variable thru the game by using the echo command several time to check if the number is constant or modified by something I m missing. Could someone help? Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted June 19, 2013 Share Posted June 19, 2013 Ive read the tip 1 of revenge with the echo command but I lack knowledge how I can use it to write the state of a variable. I would like to see which number is stored on a certain variable thru the game by using the echo command several time to check if the number is constant or modified by something I m missing. Could someone help? If you'd like to have the value of a variable displayed in the score, you can use this: randomterrain.com/atari-2600-memories-batari-basic-commands.html#testvariables Quote Link to comment Share on other sites More sharing options...
RevEng Posted June 20, 2013 Share Posted June 20, 2013 Echo outputs info at compile-time, not run-time. No code gets put into your game when you add an echo statement. As RT suggests, you need to use the score or stella's debug facility to get run-time info. Quote Link to comment Share on other sites More sharing options...
abaudrand Posted June 20, 2013 Share Posted June 20, 2013 thanks for the help guys I ve seen the page you mention RT but I hoped something prior to play the game on stella. Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted June 20, 2013 Share Posted June 20, 2013 thanks for the help guys I ve seen the page you mention RT but I hoped something prior to play the game on stella. I'm not sure what you are saying, but I wasn't just linking to a page, I was linking to a specific place on the page that has code you can use in your program to run using Stella. Quote Link to comment Share on other sites More sharing options...
iesposta Posted September 10, 2013 Share Posted September 10, 2013 iesposta Tip #1 (MUSIC) data reduction. If the Control channel [aka Tone, Voice, Distortion] doesn't change in your data for AUDC0 and/or AUDC1, set the AUDC0 = (that value) and/or AUDC1 = (value) and remove all the repeated channel numbers (and any 0's) from the data statement. Any Control value with a volume of 0 is still Volume 0, so 0, 0, 0 or 0, 4, 0 act the same. Example saved (approximately) 57 bytes (the value 12 in Channel 0 and the value 4 in Channel 1): Before: rem * Play channel 0 AUDV0 = musicData[x] : x = x + 1 AUDC0 = musicData[x] : x = x + 1 AUDF0 = musicData[x] : x = x + 1 rem * Play channel 1 AUDV1 = musicData[x] : x = x + 1 AUDC1 = musicData[x] : x = x + 1 AUDF1 = musicData[x] : x = x + 1 rem * Set duration duration = musicData[x] : x = x + 1 goto GotMusic rem ***************************************************** rem * Music Data Block rem ***************************************************** rem * Format: rem * v,c,f (channel 0) rem * v,c,f (channel 1) rem * d rem * rem * Explanation: rem * v - volume (0 to 15) rem * c - control [a.k.a. tone, voice, and distortion] (0 to 15) rem * f - frequency (0 to 31) rem * d - duration data musicData 4,12,19 4,4,19 24 4,12,19 4,4,17 8 4,12,26 0,0,0 16 4,12,26 4,4,14 16 4,12,19 4,4,14 8 4,12,19 0,0,0 8 4,12,19 4,4,17 8 4,12,19 4,4,17 8 4,12,26 4,4,19 16 4,12,26 4,4,17 16 4,12,29 4,4,21 16 4,12,26 4,4,21 8 4,12,23 3,4,21 8 4,12,21 2,4,21 8 4,12,19 1,4,21 8 4,12,17 0,0,0 8 4,12,15 0,0,0 8 4,12,14 0,0,0 16 2,12,14 0,0,0 16 255 end goto GotMusic After: rem * Check for end of current note duration = duration - 1 if duration>0 then GotMusic rem * Check for end of data if musicData[x]=255 then duration = 1 : x = 0 : goto GotMusic rem * Play channel 0 AUDV0 = musicData[x] : x = x + 1 AUDC0 = 12 AUDF0 = musicData[x] : x = x + 1 rem * Play channel 1 AUDV1 = musicData[x] : x = x + 1 AUDC1 = 4 AUDF1 = musicData[x] : x = x + 1 rem * Set duration duration = musicData[x] : x = x + 1 goto GotMusic rem ***************************************************** rem * Music Data Block rem ***************************************************** rem * Format: rem * v,c,f (channel 0) rem * v,c,f (channel 1) rem * d rem * rem * Explanation: rem * v - volume (0 to 15) rem * c - control [a.k.a. tone, voice, and distortion] (0 to 15) rem * f - frequency (0 to 31) rem * d - duration data musicData 4,19 4,19 24 4,19 4,17 8 4,26 0,0 16 4,26 4,14 16 4,19 4,14 8 4,19 0,0 8 4,19 4,17 8 4,19 4,17 8 4,26 4,19 16 4,26 4,17 16 4,29 4,21 16 4,26 4,21 8 4,23 3,21 8 4,21 2,21 8 4,19 1,21 8 4,17 0,0 8 4,15 0,0 8 4,14 0,0 16 2,14 0,0 16 255 end goto GotMusic 1 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted May 24, 2017 Share Posted May 24, 2017 This is small, but variable-saving. The playerNx and playerNy variables can be used as part of fixed point variables. I was surprised that this worked, but I guess they are variables like any other.: dim EnemyXPos = player1x.f dim EnemyYPos = player1y.g 1 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted May 24, 2017 Share Posted May 24, 2017 This is small, but variable-saving. The playerNx and playerNy variables can be used as part of fixed point variables. I was surprised that this worked, but I guess they are variables like any other.: dim EnemyXPos = player1x.f dim EnemyYPos = player1y.g Yep, that's actually on the bB page, but you have to scroll down to the fourth example box to see it: randomterrain.com/atari-2600-memories-batari-basic-commands.html#fixedpoint Maybe I should make it stand out somehow so people won't miss it. Quote Link to comment Share on other sites More sharing options...
+Karl G Posted May 24, 2017 Share Posted May 24, 2017 Yep, that's actually on the bB page, but you have to scroll down to the fourth example box to see it: randomterrain.com/atari-2600-memories-batari-basic-commands.html#fixedpoint Maybe I should make it stand out somehow so people won't miss it. Perhaps, but me missing something like that is hardly unprecedented. :-) I did read the section on fixed point variables, but I must have missed that. 1 Quote Link to comment Share on other sites More sharing options...
iesposta Posted June 17, 2017 Share Posted June 17, 2017 Optimizations to save cycles, get ROM space: Put all same value declarations on one line (until compile errors out due to too many). examples: player0x=0: c=0: d=0: missile1x=0: temp2=0: timer=0 DFRACINC0=32: DFRACINC1=32: DFRACINC2=32: DFRACINC3=32: DFRACINC4=32: DFRACINC6=32 ------------------------------------ Technical explanation: This DFRACINC0=32: DFRACINC1=32: DFRACINC2=32: DFRACINC3=32: DFRACINC4=32: DFRACINC6=32 compiles into: load register with 32, set all the data-fetchers to 32 This DFRACINC0=32 DFRACINC1=32 DFRACINC2=32 DFRACINC3=32 DFRACINC4=32 DFRACINC6=32 compiles into: load register with 32, set data-fetcher 0 to 32, load register with 32, set data-fetcher 1 to 32, load register with 32, set data-fetcher 2 with 32, load register with 32, set data-fetcher 3 to 32, load register with 32, set data-fetcher 4 to 32, load register with 32, set data-fetcher 6 to 32 See how efficient the first explanation is, and how wasteful the second explanation is? 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted June 17, 2017 Share Posted June 17, 2017 RevEng Tip #4 - (CYCLES) only run things when you need to, with a simple scheduler Not everything needs to happen at 60Hz/50Hz in your game. Some things can happen every other frame, or every 4th frame. Balance when these things happen, to make the most of available cycles... mainloop frame=frame+1 rem ** alternate "goat AI" routine with "check goat collision", every other frame rem ** (frame&1 is always either 0 or 1) if (frame&1)=0 then gosub GoatAI if (frame&1)=1 then gosub CheckGoatCollision rem ** spread movement logic for 4 enemy trolls across 4 frames rem ** (frame&3 is either 0, 1, 2, or 3) if (frame&3)=0 then gosub Troll1Logic if (frame&3)=1 then gosub Troll2Logic if (frame&3)=2 then gosub Troll3Logic if (frame&3)=3 then gosub Troll4Logic [...] 1 Quote Link to comment 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.