Cybearg Posted February 9, 2013 Author Share Posted February 9, 2013 Does "if pulse then goto 10" have any actual cycle advantage over "if pulse <> 0 then goto 10"? Because if not, I'd like to keep things as unobtuse as possible. I'd be able to save even more cycles here: if flicker = 0 && temp4{0} then goto 110 if flicker = 1 && temp4{1} then goto 110 if flicker = 2 && temp4{2} then goto 110 if flicker = 3 && temp4{3} then goto 110 if flicker = 4 && temp4{4} then goto 110 if flicker = 5 && temp4{5} then goto 110 if flicker = 6 && temp4{6} then goto 110 if flicker = 7 && temp4{7} then goto 110 and here: if temp4{0} && temp2 >= colorodds[temp3] then a[temp1] = blkc[0]: temp3 = temp3 + 1 if temp4{1} && temp2 >= colorodds[temp3] then a[temp1] = blkc[1]: temp3 = temp3 + 1 if temp4{2} && temp2 >= colorodds[temp3] then a[temp1] = blkc[2]: temp3 = temp3 + 1 if temp4{3} && temp2 >= colorodds[temp3] then a[temp1] = blkc[3]: temp3 = temp3 + 1 if temp4{4} && temp2 >= colorodds[temp3] then a[temp1] = blkc[4]: temp3 = temp3 + 1 if temp4{5} && temp2 >= colorodds[temp3] then a[temp1] = blkc[5]: temp3 = temp3 + 1 if temp4{6} && temp2 >= colorodds[temp3] then a[temp1] = blkc[6]: temp3 = temp3 + 1 if temp4{7} && temp2 >= colorodds[temp3] then a[temp1] = blkc[7]: blkcount = blkcount - 1 ... if you know of a way for me to refer to a bit operation with a variable, such as: if temp4{temp3} && temp2 >= colorodds[temp3] then a[temp1] = blkc[temp3]: temp3 = temp3 + 1 Anyway, there are probably ways for me to improve my code, but I have as many weeks of programming experience as you can count on one bird-flip, so it's unlikely that I'm going to catch everything. Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted February 9, 2013 Share Posted February 9, 2013 That part where you are looping back to 105 seems to be the main thing eating up most of your time. If you put a REM before goto 105, run the program in Stella, then hit alt + L on your keyboard, you'll notice how it mostly stays at 262. Quote Link to comment Share on other sites More sharing options...
bogax Posted February 9, 2013 Share Posted February 9, 2013 (edited) 105 rem increment flicker flicker = flicker + 1 & 7 rem determines if a color is being used if setbits[flicker] & temp4 then goto 110 goto 105 data screen_add $02, $02, $07, $0F, $17, $1F, $27, $2A, $2A, $29, $25, $1C, $14, $0C, $05, $01 end data block_bit $80, $08, $01, $08, $10, $08, $01, $08, $80, $10, $01, $04, $08, $04, $01, $10 end data setbits $01, $02, $04, $08, $10, $20, $40, $80 end 110 rem cycle through pfpixels, turning them on if they are equal to the color being drawn temp6 = base : temp4 = blkc[flicker] for temp5 = 0 to 15 if a[temp6] = temp4 then temp2 = screen_add[temp5] : $A4[temp2] = $A4[temp2] | block_bit[temp5] temp6 = temp6 + 1 & 15 next rem set playfield to current color COLUPF = temp4 Edited February 9, 2013 by bogax 2 Quote Link to comment Share on other sites More sharing options...
Cybearg Posted February 9, 2013 Author Share Posted February 9, 2013 Wow, thanks a lot! That works fantastically! ... I have to say I don't understand it, though. It's drawing pfpixels without referencing the pfpixel locations data set I made before and without even saying "pfpixel." How is that? Quote Link to comment Share on other sites More sharing options...
bogax Posted February 9, 2013 Share Posted February 9, 2013 Wow, thanks a lot! That works fantastically! ... I have to say I don't understand it, though. It's drawing pfpixels without referencing the pfpixel locations data set I made before and without even saying "pfpixel." How is that? it writes it directly to memory instead of passing the info to the pfpixels routine and having it do it (the screen is at $A4) Quote Link to comment Share on other sites More sharing options...
Cybearg Posted February 9, 2013 Author Share Posted February 9, 2013 That's awesome. Is there some way to utilize that to help with the whole flickering problem? I've made a couple additional little tweaks that have hopefully streamlined things here and there. It's hard to imagine, but it's actually running smoothly at all times, so far as I can tell. heartbreak.bas.bin heartbreak.bas Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted February 9, 2013 Share Posted February 9, 2013 If no one else is going to step up to the plate, then I can write the kernel. It wouldn't be tonight though. Once the kernel is done then you probably won't have to worry about setting the playfield pixels at all. The kernel would simply look at the color of the block, and if the color was black it wouldn't draw that block. In other words you could off-load all the pixel set up to the kernel, and simply deal with the colors. The kernel would greatly simplify things. No flicker, and pixel perfect hardware collisions. 4 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted February 9, 2013 Share Posted February 9, 2013 I haven't played it non-stop for hours, but so far Stella hasn't stopped one time with this latest version. Quote Link to comment Share on other sites More sharing options...
Cybearg Posted February 9, 2013 Author Share Posted February 9, 2013 If no one else is going to step up to the plate, then I can write the kernel. It wouldn't be tonight though. Once the kernel is done then you probably won't have to worry about setting the playfield pixels at all. The kernel would simply look at the color of the block, and if the color was black it wouldn't draw that block. In other words you could off-load all the pixel set up to the kernel, and simply deal with the colors. The kernel would greatly simplify things. No flicker, and pixel perfect hardware collisions. Ahem... Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! My appreciation knows no bounds! No rush, but I'm massively curious, so if you do make progress, please do pop in and say a thing or two about how it's going. Again, thanks much! I was starting to panic that no one would be willing/able to do it. Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted February 9, 2013 Share Posted February 9, 2013 If you use the code below to clear the visible screen instead of pfclear, you should be able to safely use the hidden row of playfield variables (var44 = 0 : var45 = 0 : var46 = 0 : var47 = 0). rem **************************************************************** rem * rem * Clears the screen. rem * rem ```````````````````````````````````````````````````````````````` rem ` playfield: ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ end 1 Quote Link to comment Share on other sites More sharing options...
iesposta Posted February 9, 2013 Share Posted February 9, 2013 it writes it directly to memory instead of passing the info to the pfpixels routine and having it do it (the screen is at $A4) Nice. Now just where is the location to do this in DPC+? I know the display bank is copied to RAM, I just wish I knew how to manipulate it directly. I'll keep on learning. Quote Link to comment Share on other sites More sharing options...
Cybearg Posted February 9, 2013 Author Share Posted February 9, 2013 If you use the code below to clear the visible screen instead of pfclear, you should be able to safely use the hidden row of playfield variables (var44 = 0 : var45 = 0 : var46 = 0 : var47 = 0). Niiiice. I loves me some extra variables! These function just like any other but I guess the names are set at var 44/45/46/47? Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted February 9, 2013 Share Posted February 9, 2013 Niiiice. I loves me some extra variables! These function just like any other but I guess the names are set at var 44/45/46/47? No you can use them to make aliases. Same for lifecolor, statusbarlength, and lives. On a similar subject, I forgot to tell you that I added dim rand16 = lifecolor to the version of your program that I PMed you, so your random numbers would be more random: rem **************************************************************** rem **************************************************************** rem * rem * VARIABLE ALIASES rem * rem **************************************************************** rem ` rem ` (You can have more than one alias for each variable.) rem ` rem ```````````````````````````````````````````````````````````````` rem ` dim _Base = q dim _Block_Count = r dim _Level = s dim _Cool_Down = t dim _Anglevar = u dim _Pulse_Counter = v dim _Flicker = w dim _Offset = x dim _Ball_Color = y dim _Heart_Color = z dim rand16 = lifecolor www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#rand On a different subject, this isn't anything like your game, but when I saw your game, I was faintly reminded of the circular Space Invaders game called The Attack of the Green Smelly Aliens from Planet 27b/6 that I played on the Amiga in the early 1990s. I thought you might want to see it: http://www.youtube.com/watch?v=Umz8ELy77Ug Quote Link to comment Share on other sites More sharing options...
Cybearg Posted February 9, 2013 Author Share Posted February 9, 2013 I don't see what makes them so smelly. Neat, though! Yeah, I can certainly see why you'd think of it. And I'll add that rand16 in there--I know that I seemed to roll up the same direction multiple times quite often, it seemed. I've attached the latest version (not that there have been a whole lot of changes--mostly just a few tweaks here and there with some additions and suggestions). heartbreak.bas heartbreak.bas.bin Quote Link to comment Share on other sites More sharing options...
bogax Posted February 9, 2013 Share Posted February 9, 2013 (edited) On a similar subject, I forgot to tell you that I added dim rand16 = lifecolor to the version of your program that I PMed you, so your random numbers would be more random I was thinking something similar here's a scatter plot previous value v current value for a combined PRNG http://postimage.org/image/xt2hiwf0p/ the LCG is seed * 17 + 103 iirc The bB RNG is a 16 bit LFSR I believe (but not the one used for the picture) in bB it would be something like myrnd = myrnd * 4 + myrnd +103 r = rand ^ myrnd ie it wouldn't cost much and it looks (to me) much more random. Edited February 9, 2013 by bogax Quote Link to comment Share on other sites More sharing options...
Cybearg Posted February 9, 2013 Author Share Posted February 9, 2013 I had planned to use rand16 but simply ran out of variables to do it with. Glad to see that there are some sneaky variables that I can rope into helping me out. Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted February 9, 2013 Share Posted February 9, 2013 According to z26, the flicker resulting from that 272 scanline count really isn't so bad, though it may get worse (or better?) You should really be using Stella. I would guess a good 95% of us do, for the awesome debugger, amongst other things. Aside from NUSIZx weirdness (like in Meltdown) I dare say Stella is by far the most accurate emulator out there for the 2600. Also you might want to check out its TV effects. The kernel is done, but work has to be done to integrate it. I took an older version of the game and hacked it in to test it. So you have to try and and break out an assembly kernel from BB kernel like RevEng did. Some things to know: - ORG statements are being used in the assembly kernel right now. They hard code an address for the compiler to put the assembly kernel in. You can change those if you want, or play around with ALIGN statements. - "Unused" play field ram is being used for temporary ram in the assembly kernel. - Register $FA is being used to even out the cycles in skipdraw. It should always remain with a value of 0. It will get trashed if you do a triple nested jump to subroutine though. Currently they subroutines seem to be only 2 deep, so that is okay. $FA is an illegal NOP opcode as well. I could potentially also use TSX as well, but it gets a little more messy as I'm using JSR's. - At the end of the assembly kernel, I'm doing a hard-coded jump back into the bb kernel. I don't think this will shift, but you never know. Here's the old rom I hacked into. The title screen doesn't show up because I hacked it to jump directly to the assembly kernel. Just press fire as normal and the assembly kernel will display. This is just meant as a demo. Remember it is an older version too. From what I've seen the assembly kernel should be compatible with the newer versions. hb(demo).bin Here's the assembly. Right now it's just over 2 pages by about 10 bytes or so. It probably could be made to fit 2 pages exactly, but I have to go out right now and it probably be good enough as is. You must add all the statements to include it in BB. I think that is "asm" or something. You might also need to include vcs.h if it can't find it. Anyhow see if you can get this going. HeatASM.zip Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted February 9, 2013 Share Posted February 9, 2013 Here is a revision of the kernel. I cut out some bytes, so that it is exactly 2 pages long (which is more desirable). Then I replaced the ORG statements with an ALIGN statement, which makes it a little more manageable. HeatASM(rev1).zip Quote Link to comment Share on other sites More sharing options...
Cybearg Posted February 9, 2013 Author Share Posted February 9, 2013 Thank you SO MUCH! That demo looks great! This asm file is meant to be either included directly (as you say above) or chopped into pieces and added to batariBasic in asm statements, correct? It would be very helpful if it wasn't necessary to search for and replace/add to stuff on every new bB iteration. What kind of set-up for the colors is necessary with the kernel? Since it doesn't use flickering, all those flicker statements should be removed, I assume, but then what would the structure of the color calls look like? Or does this assembly code replace that part? Is there any risk of me accidentally using register $FA? Is it something that I'm liable to make be not equal to 0 or are you just informing me about that? Also, can the scope of this kernel extend beyond the limits of Heartbreak in particular? What is its actual full potential and what all can be done with it? EDIT: I have no experience with this and can't truly read assembly, though I sorta-kinda-maybe get the gist of what that new kernel is doing, kinda? Anyway, since I don't know how a new kernel like this is supposed to join together with the existing stuff, I tried making a tweaked includes file and added this line to the start of heartbreak.bas: includesfile heartbreak.inc The includes file is just the standard include with a mention of heartkern.asm thrown in there after all the standard kernels are loaded. That's apparently wrong, since heartbreak.bas won't compile through bB due to: heartbreak.bas.asm (421): error: Unknown Mnemonic 'rtsstart'. I hate to bother Omega with having to explain all this to a complete newbie, so if anyone else can clue me in as to how these puzzle pieces fit together, that'd be much appreciated. Since I can't upload the .inc file type, this is what heartbreak.inc looks like: ; ; Inclues go below - order is crucial, since this is also the order in which ; they will appear in the generated assembly file ; ; header file 2600basicheader.asm ; standard kernel: two players, two missiles, a ball and an asymmetric playfield. std_kernel.asm ; standard startup routine. startup.asm ; below are collections of subroutines and functions ; if you have any more to add, put them immediately below this line. pf_drawing.asm pf_scrolling.asm std_routines.asm heartkern.asm ; The overscan routine goes below. it sets up sprites for the std_kernel. ; if you have any routines that will not run until the overscan period, ; put them immediately below this line. std_overscan.asm ; below is the generated batari Basic file bB.asm ; score graphics. score_graphics.asm ; below is the footer, which contains the score digits and startup vectors. ; If you want to create your own custom score digits, you may hack the file below, ; but first you should rename it to something else. 2600basicfooter.asm heartbreak.bas heartkern.asm Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted February 9, 2013 Share Posted February 9, 2013 (edited) Before I look at what you did... yes, the kernel is meant to inserted. In BB I think you use ASM, then put in the assembly code, and finally terminate it with END. Not 100% sure since I don't use BB, just going off memory here. You don't have to do anything special to set up the colors. They have already been set up in certain locations in ram. As long as you don't change those ram locations it will work, and if you do change those locations you just update the locations assigned for what I called "colBlock1" to "colBlock16" in the file. As a short explanation, you used some of BB's variables. BB variables have been mapped to certain locations in the RIOT ram by the BB kernel. If you start your game, and get to the playing screen, use the "~" key in the Stella emulator to open the debugger. Once there you will see where your colors are stored. With the $FA, if you overwrite it you will know immediately. When you take a shot some garbage will show up on the screen. I'm just using it to even out cycles, but in reality we might not even have to even out the cycles. I haven't tested that to see. I wouldn't worry too much about it. If you are having trouble compiling it could be a few reasons. Maybe try to put Processor 6502 and include vcs.h at the top of the assembly file. Also make sure you have a copy of vcs.h in the same folder as the assembly file or map the path. I'd just put a copy in the folder and see if it compiles with or without it there. Edited February 9, 2013 by Omegamatrix Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted February 9, 2013 Share Posted February 9, 2013 Looking at the above includes in your post, I'm not sure that is the way to include this file. I haven't looked at what RevEng did. In the demo I made I put it before the score and after the BB kernel. You might try putting ORG $FD00 before the heartkernel.asm, and make sure it is after BB kernel. Then see if it will compile in. If it does it still won't work yet as we haven't told it to jump there when it is in the playing screen, and go to the regular BB kernel when it's the title screen. Quote Link to comment Share on other sites More sharing options...
Cybearg Posted February 9, 2013 Author Share Posted February 9, 2013 Well, instead of trying to include it with a .inc file, I tried just dropping it in asm ... end before everything else. It compiles with 94 bytes to spare on the ROM, which is great! ... Though nothing seems to happen. That may be because I... need to go back and delete out all the stuff about the flickering? From what you said, the kernel takes the color values directly from the memory addresses of the first sixteen variables, though keep in mind that those variables always have some value. If a block is dead, the color "2" is written to it. Why not black? Because there are black blocks in later levels and I needed a way to distinguish a black block from a dead block. That wasn't the case in the version you made the kernel for. If it draws the pfpixels directly through the kernel without the aid of the color flicker code: rem ============== rem COLOR FLICKER rem ============== 100 rem first, set levelcolor[level] into another variable for bitwise operations temp4 = levelcolors[level] 105 rem increment flicker flicker = flicker + 1 & 7 rem determines if a color is being used if setbits[flicker] & temp4 then goto 110 goto 105 data screen_add 2, 2, 7, 15, 23, 31, 39, 42, 42, 41, 37, 28, 20, 12, 5, 1 end data block_bit 128, 8, 1, 8, 16, 8, 1, 8, 128, 16, 1, 4, 8, 4, 1, 16 end data setbits 1, 2, 4, 8, 10, 32, 64, 128 end 110 rem cycle through pfpixels, turning them on if they are equal to the color being drawn temp6 = base for temp5 = 0 to 15 if a[temp6] = blkc[flicker] then temp2 = screen_add[temp5] : $A4[temp2] = $A4[temp2] | block_bit[temp5] temp6 = temp6 + 1 & 15 next rem set playfield to current color COLUPF = blkc[flicker] ... Which I only partially understand since bogax's brilliant reworking, will it still be able to account for that kind of thing? Currently, I just get a black screen, but I'm likely doing something wrong or maybe the COLOR FLICKER code needs to be removed in order to get it to all work together. heartbreak.bas Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted February 9, 2013 Share Posted February 9, 2013 You have to jump into the routine with BB. The black blocks with 2 are a big problem. If you however use 1, it might not be a problem at all. Quote Link to comment Share on other sites More sharing options...
Cybearg Posted February 9, 2013 Author Share Posted February 9, 2013 Changed the 2 to a 1. When you say You have to jump into the routine with BB. ... Do you mean jump into the subroutine? Because the compiler doesn't recognize DrawKernel as a valid subroutine since it's not defined outside of the asm ... end code. Gah, sorry for the annoyance of all the questions for simple stuff. EDIT: Oh, wait... Just looked at this, which explains how this sort of thing is supposed to work. From what I can tell, the .nameHere parts of Assembly are the actual subroutines, not the big DrawKernel: stuff, so I need to call one of those .nameHere parts. So which subroutine is meant to be called to begin the whole draw process? I see one for .storeShot (do I need to call that when the ball is generated?) .storeblock 1-16 (which I assume I need to call for each of the blocks being generated?) and then things like .loopThreeBlocks and .loopTwoCloseBlocks, etc., which I'm not sure how they would be called correctly. Also, I included the .asm file at the end of everything rather than the beginning, like so: rem end loop 800 goto draw_loop asm include "heartkern.asm" end Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted February 9, 2013 Share Posted February 9, 2013 Changed the 2 to a 1. When you say [/font][/color] ... Do you mean jump into the subroutine? Because the compiler doesn't recognize DrawKernel as a valid subroutine since it's not defined outside of the asm ... end code. Gah, sorry for the annoyance of all the questions for simple stuff. Try putting a dot in front of it in the assembly kernel, and call it the same thing in BB. Also, you might be able to put it before the area where you include the assembly file, or even better just use a new label. The way I set it up, you might to use a goto instead of a jump to subroutine. I'm going to get my haircut right now, and I won't be back for a few hours. So someone else might be able to help you in the meantime. Good luck, I want to see this working too! 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.