KevKelley Posted April 16, 2020 Share Posted April 16, 2020 I had been reading about playfield variables and was curious if there would be any benefit versus using pfpixel to turn on or off playfield pixels? Less cycles? Less bytes? Or if there is no real discernable difference except how it may work with a particular line of code one may fit better? Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted April 16, 2020 Share Posted April 16, 2020 The bB page says that pfpixel uses 80 processor cycles every frame. Compare that to turning bits off and on: randomterrain.com/atari-2600-memories-batari-basic-commands.html#cycle_count_bitop If you are using the DPC+ kernel, there are no playfield variables that we can mess with, if I remember correctly. Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 16, 2020 Author Share Posted April 16, 2020 This was standard kernel. I was just trying to slowly understand the workings under the hood. I was gonna play around with using either/or to see if there is a difference. I had came across it in my reading to try and figure out a workable alternative to what I had done and get the same effect. Currently I had pfpixels moving around. I tried to limit their appearance with all else going on and came across that. I will play around with it later on lunch and update on my findings. Thanks! Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 16, 2020 Author Share Posted April 16, 2020 So I swapped my code with using playfield variables versus turning on or off a pfpixel. From what I can tell it seems as though it uses less cycles. I didn't delve entirely into the debugger but I ran the program for a while and under different conditions that the over cycle had occurred with and I did not experience it so I am thinking it may be fixed. Also on a plus side it uses about 300 bytes less. I changed this: if counter = 43 then pfpixel 31 7 on:pfpixel 25 7 off if counter = 51 then pfpixel 30 7 on :pfpixel 31 7 off if counter = 59 then pfpixel 29 7 on :pfpixel 30 7 off if counter = 66 then pfpixel 28 7 on :pfpixel 29 7 off if counter = 73 then pfpixel 27 7 on :pfpixel 28 7 off if counter = 87 then pfpixel 26 7 on :pfpixel 27 7 off if counter = 92 then pfpixel 25 7 on:pfpixel 26 7 off if counter =99 then pfpixel 25 7 off to this: if counter = 43 then var31=%10000000 if counter = 51 then var31=%01000000 if counter = 59 then var31=%00100000 if counter = 66 then var31=%00010000 if counter = 73 then var31=%00001000 if counter = 87 then var31=%00000100 if counter = 92 then var31=%00000010 if counter =99 then var31=%00000000 I understand that my initial method was probably very wasteful and there may be an even better method but I thought this was a good exercise in trying to understand pfpixels and use different ways to change the playfield. 1 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted April 16, 2020 Share Posted April 16, 2020 I really want to use pfpixel for procedurally drawn screens. Alas, what I've found is that using several pfpixel commands does indeed exacerbate CPU cycle problems. Also, it seems to use up more ROM space using pfpixel commands than playfield screen sections. Big bummer there ? My experiences could very well be my poor coding style in combination with using pfpixel in an unintended way I suspect this is something we'll have to make a custom community version of pfpixel to get closer to some of our needs. Kind of like what we did for the multi sprite kernel pfread. Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 16, 2020 Author Share Posted April 16, 2020 Seeing how this worked, I am going to play around with it and see what is possible. It did surprise me how much was saved. It also makes me wonder how this compares to pfhline of pfvline. I might be able to free up even more! 1 Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 16, 2020 Author Share Posted April 16, 2020 The game I'm working on would draw pfpixels on a timer and as you can see from the code I posted, I also had it turn on and off pfpixels in a row. I experienced overcycling so I shifted when these were drawn, hence the weird counter numbers like 43 or 87. That kind of worked but I didn't consider other factors like if a pfpixel is removed or potential collision detection with a missile. I do see how pfpixel could work better than a playfield variable but I can see how this could be very beneficial. I wanna learn more about what goes on under the hood and why this uses less. In Bag Boy and Manatee Madness I essentially redraw the entire (or parts) of the playfield and it never had overcycle problems versus a couple pixels being turned on simultaneously. I guess this gets me closer to learning assembly... Quote Link to comment Share on other sites More sharing options...
bogax Posted April 17, 2020 Share Posted April 17, 2020 do fewer if statements temp1 = counter/8 - 5 if !counter & 7 && temp1 < 8 then var31 = dat[temp1] data dat $80, $40, $20, $10, $08, $04, $02, $00 end 2 Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 17, 2020 Author Share Posted April 17, 2020 Ah. I have been slow to use data statements but I understand the principles. I suppose in this instance it would work well because it is a sequence versus a one-off. I will definitely have to check this out later. I was planning on trying to play around with these variables to see how far I can push it. Quote Link to comment Share on other sites More sharing options...
TwentySixHundred Posted April 17, 2020 Share Posted April 17, 2020 (edited) 18 hours ago, Gemintronic said: I really want to use pfpixel for procedurally drawn screens. Alas, what I've found is that using several pfpixel commands does indeed exacerbate CPU cycle problems. Also, it seems to use up more ROM space using pfpixel commands than playfield screen sections. Big bummer there ? My experiences could very well be my poor coding style in combination with using pfpixel in an unintended way I suspect this is something we'll have to make a custom community version of pfpixel to get closer to some of our needs. Kind of like what we did for the multi sprite kernel pfread. Yep, from my experience and experimentation i get the same results that pfpixel can be very costly in both ROM and cycles. I suspect when the code is cross compiled to asm it bloats substantially causing high ROM usage and demanding lots of processing time. It;s all good for a few pixels flipped a frame yet drawing full screen is not even feasible with the pfpixel command. It seems data tables is the better method Edited April 17, 2020 by TwentySixHundred 1 Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 17, 2020 Author Share Posted April 17, 2020 10 hours ago, bogax said: do fewer if statements temp1 = counter/8 - 5 if !counter & 7 && temp1 < 8 then var31 = dat[temp1] data dat $80, $40, $20, $10, $08, $04, $02, $00 end Thanks! I just swapped the code and this uses 40 less bytes. 7 minutes ago, TwentySixHundred said: Yep, from my experience and experimentation i get the same results that pfpixel can be very costly in both ROM and cycles. I suspect when the code is cross compiled to asm it bloats substantially causing high ROM usage and demanding lots of processing time. It;s all good for a few pixels flipped a frame yet drawing full screen is not even feasible with the pfpixel command. It seems data tables is the better method I started to play around with my my pfhlines to see if this would also help. For a short pfhline of about 5 pixels I was able to save about 50 bytes BUT I found that if my line extended across a couple playfield variables it may not be worth using it because then I would have to write up some checks to make sure the right pixels turn on or off. This may be helpful later on. I had experienced an issue earlier on where I was trying to turn off a long pfhline and ran into some overcycling so I solved it by having it turn off shorter segments on a timer. This might help free up some more space and cycles. Quote Link to comment Share on other sites More sharing options...
bogax Posted April 17, 2020 Share Posted April 17, 2020 my point was that you're doing a bunch of if statements that you don't need to do most of the time actually this makes more sense and if that last byte in the table is meant to be a 1 then you could use the table the kernel uses const v31_data = setbyte if counter & 7 then skip_v31 temp1 = counter/8 - 5 if temp1 < 8 then var31 = v31_data[temp1] skip_v31 1 Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 17, 2020 Author Share Posted April 17, 2020 I understand it makes sense. I know my code is probably bloated with unnecessary statements. As I have been coming up with things I plug it in and see what works. I had one question. What do you mean by the table the kernel uses? Looking at your code I assume that each playfield variable is set up using a table so instead of making a new data table for the variable you just alter the existing one? Quote Link to comment Share on other sites More sharing options...
bogax Posted April 17, 2020 Share Posted April 17, 2020 the kernel has a table called setbyte that it uses for setting pixels in the playfield and other stuff it varies depending on how the playfield is structured in this case it would be (in bB) something like data setbyte $80, $40, $20, $10, $08, $04, $02, $01, $01, $02, $04, $08, $10, $20, $40, $80, $80, $40, $20, $10, $08, $04, $02, $01, $01, $02, $04, $08, $10, $20, $40, $80 end I just made v31_data an alias for setbyte (which was totally unnecessary) playfield statements get their own tables for the whole playfield Quote Link to comment Share on other sites More sharing options...
bogax Posted April 17, 2020 Share Posted April 17, 2020 it's true it uses less ROM but the point is it uses less time (and something closer to only the time necessary) Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 18, 2020 Author Share Posted April 18, 2020 I guess I never really worry about time until it is too late. I know I tend to try to code and then tweak things after to see how I can improve, comparing my original code to see what I can do differently in the future. I still got lots to learn and am very thankful for your explanations. Quote Link to comment Share on other sites More sharing options...
bogax Posted April 18, 2020 Share Posted April 18, 2020 (edited) I didn't explain very well Perhaps some of this is not as obvious as I think (I'm thinking) we're optimizing for time First thing I note is that you test for counter values and when you find one, you set var31 then test for more values that you know it can't be. Usually I think of a table look up as (probably) trading ROM space for speed. In this case you said you'd chosen "weird counter numbers" for timing so I regularized The intervals and added a guard condition for multiples of 8 ie if counter & 7 then .. so now 7 out of 8 times you only do one if test If you really needed the weird numbers you could still eg test for values between say, 40 and 100 and skipped 40% of the time (if your counter went 0..100) and done only two tests That's more code and more time but it's probably a net gain You could go farther and test for numbers that are eg equal to - greater than an even multiple of 4 but less than the next odd multiple (if that fit the values you were looking for) that would add another test but cut out half the possibilities if counter & 4 then You might do a binary search if you had more weird values Or you might use a look up table, but then you'd need like 60 entries if the values could be anything 40..100 A look up table would still be lot faster even if it didn't save any space I didn't really figure it out, but I think in this case you'd still save a few bytes of ROM And tables can be completely arbitrary none of this needs assembly except perhaps to have an idea of the time and space I would certainly encourage you to learn the assembly and read the list file to see what you're getting and a bit of assembly can be really useful even if you're using bB I especially like RevEng's suggetion (somewhere in this forum) of getting the assembler to print the difference (amount of code) between two lables Edited April 18, 2020 by bogax clarify Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 18, 2020 Author Share Posted April 18, 2020 I plan on looking through the assembly to kind of learn more. I bought the Atari programming book but haven't delved into it too much but I've been looking at all the forum topics to try and get familiar with how it looks and works for when I eventually play around with it. In my program, when I mentioned "weird" values, what I meant was that when I first ran into overcycling issues I changed some values. I generally have a pfpixel drawn when counter reaches 100. Player0 can also pick up pfpixels. Originally I had the values on the counter at an even set of intervals and it seemed that when it drew and erased too many pfpixels at once it would over cycle. My original attempt at troubleshooting was to just change the values to avoid everything happening all at once until I could figure out a better way. For the most part it worked but it really seemed to just kick the can down the road. When I read about playfield variables it got me thinking. Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 18, 2020 Author Share Posted April 18, 2020 Now I do wonder, I see the playfield variables are formatted something like var31=%00000000. Is it possible to turn on a single bit from that, like var31{4}=1? Would that essentially work like a pfpixel on/off command? (I don't have my computer with me otherwise I would run a simple test on my own ) Quote Link to comment Share on other sites More sharing options...
bogax Posted April 18, 2020 Share Posted April 18, 2020 3 hours ago, KevKelley said: Now I do wonder, I see the playfield variables are formatted something like var31=%00000000. Is it possible to turn on a single bit from that, like var31{4}=1? Would that essentially work like a pfpixel on/off command? (I don't have my computer with me otherwise I would run a simple test on my own ) yes, but you can't calculate the bit specified the number in the brackets has to be a number literal not a variable or an expression and it doesn't always show an error if eg you use a variable you don't have to do all eight bits if you use the table dim bitstoswap = b dim idx = i const sbits0 = setbyte + 8 ; set a bit var31 = var31 | sbits0[idx] ; clear a bit var31 = (sbits0[idx] ^ %11111111) & var31 ; swap in bits 2, 3, 6 var31 = ((sbits0[idx] ^ var31) & %01001100) ^ var31 ; swap in bits 2, 3, 6 var31 = ((var31 ^ bitstoswap) & %01001100) ^ var31 it would be nice to build macros but bB macros are just DASM macros and DASM wouldn't understand the indexing so it would have to be done in ASM dim idx = i const sbits0 = setbyte + 8 def set_bit = callmacro stb_m def clear_bit = callmacro clb_m ; parameters target variable, number of bit to set macro stb_m asm ldx {2} lda sbits0,x ora {1} sta {1} end end ; parameters target variable, number of bit to clear macro clb_m asm ldx {2} lda sbits0,x eor #$FF and {1} sta {1} end end ; usage set_bit var31 idx clear_bit var31 idx Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 18, 2020 Author Share Posted April 18, 2020 Cool. I was looking at bitwise operations on lunch. It is something I haven't really done much with but I see how this can definitely help. When I first started these were probably the more confusing aspects of programming to me. I am slowly getting it. Thanks so very much! Quote Link to comment Share on other sites More sharing options...
TwentySixHundred Posted April 19, 2020 Share Posted April 19, 2020 As for overcycle and pfpixel when too many pixels are flipped on a single frame you can just set a _skp label if one those flip conditions are met. Provided, if all your condition statements are in a single code block and a pfpixel flip is executed then goto _skp label. This will ensure for that frame the pfpixel command isn't executed more then once per frame. Spreads the load over multiple frames Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 19, 2020 Author Share Posted April 19, 2020 Yeah. Since I have essentially 3 different code blocks for the generation, elimination, and other pfpixels, that wouldn't work unless I consolidated the code. Another solution I had thought of was to assign a bit and if I pfpixel is picked up it would flip, disable the unnecessary code for a frame, and then reset. Or have a variable so that if the box is picked up at the same time the counter hits a number than to add that variable to the other code. In the end using the playfield variables was much better. Plus I learned something nee. That I can apply to more applications in the future. Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 25, 2020 Author Share Posted April 25, 2020 When I last left off trying to turn on different different bit from the playfield variables. So after playing around some, i started messing around with XOR commands to change my pfhline draws and it seemed to work well, freeing up a little over 100 bytes. So I changed this: if e{0} then var4=%11111100 if e{1} then pfhline 6 1 9 on if e{2} then pfhline 11 1 14 on if e{3} then pfhline 16 1 19 on if e{4} then pfhline 21 1 24 on to this: if e{0} then var4=var4^%01111000 if e{1} then var4=var4^%00000011:var5=var5^%00000011 if e{2} then var5=var5^%01111000 if e{3} then var6=var6^%11110000 if e{4} then var6=var6^%00000111:var7=var7^%00000001 I had started using playfield variables, which is why e{0} originally had a variable but when I got into e{1} and e{4} it stretched over two variables. Initially I wasn't sure how to flip the bits which is why I kept the pfhlines temporarily. I use pfhlines in a couple more spots in my program so I will have to fix that up too, which should free up some space. 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.