RevEng Posted April 8, 2021 Author Share Posted April 8, 2021 12 hours ago, batari said: What would happen if I made a 12-high zone, aside from wasted space? Does it mean the sprites won't work correctly if I tweak the DLL to 12 high zones? At a minimum, any line in the top portion of the sprite that has an offset in the zone greater than 11 wouldn't appear. I'm pretty sure there would be some additional glitching on the bottom-portion of the sprite too, though I'd need to trace the code to describe the effect in any detail. 12 hours ago, batari said: As for the 12-high pixels for the standard kernel, the only way I can see that could match things up is to use three 8-high 7800 characters stacked vertically for every two playfield pixels high. It shouldn't be that hard to do. A potential issue with this, though, is converting the 48 bytes of playfield data to 288 bytes of character data in 7800basic. It can be helped with a lot of lookup tables and unrolled loops, but still that is a lot of stores. It'll take thousands of cycles to convert that. If you're willing to update them during the visible screen (there might be perceptible shearing if there are regular updates) you probably have the cycles to do it. With DMA running and a modest 160A screen with double-wide characters you'll have about 10000 6502 cycles leftover. But as you point out, playfield: needs to be converted anyway. It would just be easier to directly use 7800basic alphadata+plotmap. Something like this... playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end Could become something like this... alphachars '.X' alphadata screen1map tileset_blocks 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' 'X..............................X' 'X..............................X' 'X..............................X' 'X..............................X' 'X..............................X' 'X..............................X' 'X..............................X' 'X..............................X' 'X..............................X' 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' end ; you also need to "plotmap" this map somewhere onto the screen ; and include a PNG graphic called tileset_blocks.png in your code ; with graphics for the 2 characters. Things like pfpixel and pfread would require updates to pokechar and peekchar. (pfpixel/pokechar would need a different setup for the playfield though, as you'd need RAM based characters) 1 Quote Link to comment Share on other sites More sharing options...
+batari Posted April 8, 2021 Share Posted April 8, 2021 5 hours ago, Karl G said: I had thought that the standard kernel had 16 scanline high blocks, not 12. The play area is 88 double scanlines high, so (88*2) / 11 playfield rows = 16 At any rate, doing 11 rows of characters with 16 scanline high zones for the playfield would leave one zone below that to do the score and the equivalent of pfscore bars for a total of 192 scanlines. Yep, you are right! I thought it was 16, but I opened up a bB game last night and went through the scanlines in the Stella debugger. For some reason I counted 12 lines. Today, with the same game, it is clearly 16. I have no idea how that happened. Anyway, 16 makes it a TON easier for sure. Quote Link to comment Share on other sites More sharing options...
+batari Posted April 8, 2021 Share Posted April 8, 2021 4 hours ago, RevEng said: At a minimum, any line in the top portion of the sprite that has an offset in the zone greater than 11 wouldn't appear. I'm pretty sure there would be some additional glitching on the bottom-portion of the sprite too, though I'd need to trace the code to describe the effect in any detail. If you're willing to update them during the visible screen (there might be perceptible shearing if there are regular updates) you probably have the cycles to do it. With DMA running and a modest 160A screen with double-wide characters you'll have about 10000 6502 cycles leftover. But as you point out, playfield: needs to be converted anyway. It would just be easier to directly use 7800basic alphadata+plotmap. Something like this... playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end Could become something like this... alphachars '.X' alphadata screen1map tileset_blocks 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' 'X..............................X' 'X..............................X' 'X..............................X' 'X..............................X' 'X..............................X' 'X..............................X' 'X..............................X' 'X..............................X' 'X..............................X' 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' end ; you also need to "plotmap" this map somewhere onto the screen ; and include a PNG graphic called tileset_blocks.png in your code ; with graphics for the 2 characters. Things like pfpixel and pfread would require updates to pokechar and peekchar. (pfpixel/pokechar would need a different setup for the playfield though, as you'd need RAM based characters) So just to clarify, is the font data in ROM or RAM, and are the characters (the X and .) in ROM or RAM? Quote Link to comment Share on other sites More sharing options...
+Karl G Posted April 8, 2021 Share Posted April 8, 2021 10 minutes ago, batari said: Edit: posting issues Quote Link to comment Share on other sites More sharing options...
RevEng Posted April 8, 2021 Author Share Posted April 8, 2021 [edit - beat by Karl, but something odd seems to have happened to his post.] The font graphic data is in ROM, imported into the correct place and format via the incgraphic command. In the example I used, the character strings are in ROM. The RAM version of my example is nearly the same, except you dim a buffer "dim charbuffer=$2200" and use "memcpy screen1map charbuffer 288" (or whatever the size is) to populate it, and then plotmap the "charbuffer" ram buffer instead of the "screen1map" rom. Quote Link to comment Share on other sites More sharing options...
+Karl G Posted April 9, 2021 Share Posted April 9, 2021 I found a bB demo from the RT site that includes playfield pixel destruction, and converted it to 7800Basic. I didn't delete any of the old code, but I put comments with the tag "7800Basic" before any code I added or commented-out with a brief explanation for the change. The source zip contains the original bB example (ex_sprite_with_missile_and_pfpixel_destruction.bas) and the converted version for 7800Basic (bb7800.78b). Obviously for such a trivial case, it would have probably been easier to rewrite it, but it may serve as a useful example of the dynamic RAM "playfield", and some of the other changes that are needed for a bB project. Original bB example: Converted 7800 version: ROMs: ex_sprite_with_missile_and_pfpixel_destruction.bas.bin bb7800.78b.a78 Source zip: bb7800.zip 3 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted April 10, 2021 Share Posted April 10, 2021 On the subject of porting from bB, and also because it would be useful on its own, how feasible would it to be to add a feature to 7800Basic that would allow a user function to be run each visible zone? I was thinking it would be handy for updating e.g. a palette color or the background color for each zone. Quote Link to comment Share on other sites More sharing options...
RevEng Posted April 11, 2021 Author Share Posted April 11, 2021 Arbitrary user-interrupts (other than the current near-top, near-bottom, and offscreen ones) aren't planned in the near future. An NMI color change interrupt needs minimal overhead to be reliable - otherwise, adding more dma increases the chance of the color change not taking effect until the next scanline, to the point where the heaviest DMA limits can cause a miss in the most minimal color change code. I may change this in the future if I take on an NMI handling rewrite, but honestly I have a few different pieces I'd like in place before I consider that, to avoid painting myself into a corner. 2 Quote Link to comment Share on other sites More sharing options...
fultonbot Posted May 24, 2021 Share Posted May 24, 2021 On 4/10/2021 at 8:20 PM, RevEng said: Arbitrary user-interrupts (other than the current near-top, near-bottom, and offscreen ones) aren't planned in the near future. An NMI color change interrupt needs minimal overhead to be reliable - otherwise, adding more dma increases the chance of the color change not taking effect until the next scanline, to the point where the heaviest DMA limits can cause a miss in the most minimal color change code. I may change this in the future if I take on an NMI handling rewrite, but honestly I have a few different pieces I'd like in place before I consider that, to avoid painting myself into a corner. RevEng Can you see any way to "draw" on the screen effectively with Maria by manipulating the bitmap drawing? Like how would one approach drawing the missiles in Missile Command? Quote Link to comment Share on other sites More sharing options...
RevEng Posted May 24, 2021 Author Share Posted May 24, 2021 3 hours ago, fultonbot said: RevEng Can you see any way to "draw" on the screen effectively with Maria by manipulating the bitmap drawing? Like how would one approach drawing the missiles in Missile Command? The quick answer to arbitrary bitmap drawing is to use RAM-backed sprites. Basically you have a series of sprites that cover the screen and point at different segments of RAM, and you have line drawing routines that update that RAM. There isn't an easy way to do this in 7800basic right now. @SmittyB's Plink game uses pretty much this technique for dynamic backgrounds, though it's not doing full-screen bitmaps. (they repeat vertically) That said, I don't think Missile Command actually needs bitmap display, if you just limit the number of angles the missiles can come in at. (The 2600 version doesn't pull off arbitrary angles either, and the missile aspect of the game compares very well to the arcade). Given that approach, you can just draw the missile segments with sprites. (pulling this off quick enough would likely require the Under The Hood technique) Quote Link to comment Share on other sites More sharing options...
fultonbot Posted May 24, 2021 Share Posted May 24, 2021 24 minutes ago, RevEng said: The quick answer to arbitrary bitmap drawing is to use RAM-backed sprites. Basically you have a series of sprites that cover the screen and point at different segments of RAM, and you have line drawing routines that update that RAM. There isn't an easy way to do this in 7800basic right now. @SmittyB's Plink game uses pretty much this technique for dynamic backgrounds, though it's not doing full-screen bitmaps. (they repeat vertically) That said, I don't think Missile Command actually needs bitmap display, if you just limit the number of angles the missiles can come in at. (The 2600 version doesn't pull off arbitrary angles either, and the missile aspect of the game compares very well to the arcade). Given that approach, you can just draw the missile segments with sprites. (pulling this off quick enough would likely require pre-the Under The Hood technique) I think I'll try the 2nd method for the fun of it. 1 Quote Link to comment Share on other sites More sharing options...
+SmittyB Posted May 24, 2021 Share Posted May 24, 2021 The title screen in Plink does use a full-screen bitmap for the cyan, but even with the monochrome 320A mode the CPU time is a noticeable limiting factor to how much can be drawn in one frame. There are plenty of optimisations that can be made over what I did in Plink, and I think somebody could make a version of Missile Command with this technique, but there would have to be some clever compromises somewhere to make it playable at any real speed. There's a lot of potential in bitmapping, but I'd say it's best limited to things where frame rate isn't important. 2 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted June 11, 2021 Share Posted June 11, 2021 Possibly a dumb question, but why do 48K games compile to produce a 32K bin file? In this particular case, if I change it to actually be a 32K game, it doesn't have enough space. Edit: Nevermind. Wrong file. Quote Link to comment Share on other sites More sharing options...
+Muddyfunster Posted June 11, 2021 Share Posted June 11, 2021 I checked Danger Zone which is a 48K ROM, both the A78 and BIN are 48K. I think you might have found the Tardis compiler Karl 2 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted June 11, 2021 Share Posted June 11, 2021 6 minutes ago, Muddyfunster said: I checked Danger Zone which is a 48K ROM, both the A78 and BIN are 48K. I think you might have found the Tardis compiler Karl Or I was looking at a different version of my game. Oops. Looks like my 48K game is actually 48K, after all. Quote Link to comment Share on other sites More sharing options...
+Muddyfunster Posted August 5, 2021 Share Posted August 5, 2021 I found an interesting...issue (maybe?) when tinkering with some code today. This code works fine, but if I swap the palette entry for the plotsprite here to a variable that I imaginatively called "palette" I get a compile error. (branch out of range). if xpos1_88 >64 && xpos1_88 < 170 then plotsprite fireball 4 xpos1_88 48 : plotsprite fireball 4 xpos1_88 80 This in comparison, will not compile. As noted the only difference is using a variable for the palette. The variable is in use elsewhere without issue. if xpos1_88 >64 && xpos1_88 < 170 then plotsprite fireball palette xpos1_88 48 : plotsprite fireball palette xpos1_88 80 If this is a "known" restriction that I've overlooked - apologies Quote Link to comment Share on other sites More sharing options...
RevEng Posted August 5, 2021 Author Share Posted August 5, 2021 It's sorta known. (no need for apologies!) There's a few statements that eat a lot of rom, and as such cause branch-errors in the if...then logic. Resolving it requires a bit of re-write, and probably will grow the usage of if...then by a few bytes for each one, so I've been putting it off. For now, you can work-around by putting the rom-hungry statement on it's own line and using if...then to conditionally jump past the statement. As for the reason why plotsprite triggers the issue with a variable pallete failing but a constant one working... variable palletes use a bit more rom. plotsprite appears to be on the cusp of the if...then hungry-statement issue. 1 Quote Link to comment Share on other sites More sharing options...
+Muddyfunster Posted August 5, 2021 Share Posted August 5, 2021 Thanks Mike! 1 Quote Link to comment Share on other sites More sharing options...
+Muddyfunster Posted August 24, 2021 Share Posted August 24, 2021 On 3/10/2021 at 2:20 AM, Muddyfunster said: Nothing was offscreen and that's what confused me, the box_collision sample was 32,16 also and I have a slightly smaller other sprite at 14,13. If part was offscreen I could understand it getting a bit upset. I thought my positioning variables were off, so I hardcoded the actual values in to test it in the engine, same result, no collision on the first 16 pixels from the left. Once I split the collision check into 2 checks, it's fine. Further investigation : Here's the funny thing. The issue with 32pixel wide collision box only occurs on the first sprite of that type. If I add 3 in a line starting at 0 so they are positioned 0,32,64 then only the first 16 pixels of first sprite are ignored, rest are fine. I can consistently reproduce it. There must be something influencing the check or one of the variables elsewhere. My code chunk in full. if lava=false then goto skip_lava_col_w2 for var69 = 1 to max_lava_chunks mytempx = lava_x[var69] mytempy = lava_y[var69] if boxcollision(ship_x_hi,ship_y_hi,14,13,mytempx,mytempy,32,16) then player_explode = true next skip_lava_col_w2 I'll investigate some more to make sure nothing is contaminating the positioning vars or anything. Just had this pop up again. I was doing some tests with a box collision on a 24x40 sprite, the top 20 or so pixels are ignored unless I split the check into into 3 parts, effectively, 24x8, 24x16 and 24x16. I was checking the smallest parameter box vs the bigger parameter box (like in the example above). I tried swapping the order in which the parameters are checked so I'm checking the bigger sprites box first. It worked fine with just 1 check. I had another collision check with the same sprite that was working, when I checked, the large box was being called first, the smaller sprite second. So in summary I found that : This works : if boxcollision(boss_x_hi, boss_y_hi,24,40,mytempx_hi, mytempy_hi,4, 1) then blah blah blah This does not : if boxcollision(mytempx_hi, mytempy_hi,4, 1, boss_x_hi, boss_y_hi,24,40) then blah blah blah Not sure what that means, other than I have a solution to a problem only I was having , but I thought I'd share that incase it's helpful to anyone else. I'll be able to go back and remove the lava workaround now as well 2 Quote Link to comment Share on other sites More sharing options...
RevEng Posted August 24, 2021 Author Share Posted August 24, 2021 2 hours ago, Muddyfunster said: Just had this pop up again. I was doing some tests with a box collision on a 24x40 sprite, the top 20 or so pixels are ignored unless I split the check into into 3 parts, effectively, 24x8, 24x16 and 24x16. I was checking the smallest parameter box vs the bigger parameter box (like in the example above). I tried swapping the order in which the parameters are checked so I'm checking the bigger sprites box first. It worked fine with just 1 check. I had another collision check with the same sprite that was working, when I checked, the large box was being called first, the smaller sprite second. So in summary I found that : This works : if boxcollision(boss_x_hi, boss_y_hi,24,40,mytempx_hi, mytempy_hi,4, 1) then blah blah blah This does not : if boxcollision(mytempx_hi, mytempy_hi,4, 1, boss_x_hi, boss_y_hi,24,40) then blah blah blah Not sure what that means, other than I have a solution to a problem only I was having , but I thought I'd share that incase it's helpful to anyone else. I'll be able to go back and remove the lava workaround now as well Awesome work-around. I have an idea at what's at the heart of this, but it's not easily solved. Basically the 8-bit values can underflow near or past the 0 coordinate edges. To work around it, I add an offset, but that can only go so far before you introduce the opposite problem at the max-coordinate screen edges. So Y box checks are reliable up to heights of (256-192)/2, or 32. X box checks are reliable up to widths of (256-160)/2, or 48. Beyond that, things get unreliable at the screen edges. This could be fixed by using 16-bit math, but that would cripple the performance. I do need to document these limitations better. Really this all dawned on me some time after boxcollision was written. 3 2 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted September 9, 2021 Share Posted September 9, 2021 What can cause this compilation error? 7800basic compilation complete. User-defined 7800.asm found in current directory Read $2000 bytes of cartridge data. Invalid byte at $FFF8, should be $FF! For me, it hit when I put playsfx in an if/then statement, and went away when I re-coded it to avoid having that statement as part of the if/then statement. Quote Link to comment Share on other sites More sharing options...
RevEng Posted September 9, 2021 Author Share Posted September 9, 2021 The playsfx is one of those inflated statements that cause the if...then logic to trigger an out of range branch. Are there messages elsewhere saying the source wasn't resolvable? This particular error you've flagged is actually issued by 7800sign, which gets run post-compilation. It's noting the rom is malformed. Quote Link to comment Share on other sites More sharing options...
+Karl G Posted September 9, 2021 Share Posted September 9, 2021 1 hour ago, RevEng said: The playsfx is one of those inflated statements that cause the if...then logic to trigger an out of range branch. Are there messages elsewhere saying the source wasn't resolvable? This particular error you've flagged is actually issued by 7800sign, which gets run post-compilation. It's noting the rom is malformed. No; there were no errors prior to that one that I could see. Here is the full output: Karls-MBP:SpacePeril kdgarris$ 7800bas SpacePeril.78b Using "" flavored 7800basic binaries Location: /Users/kdgarris/Downloads/7800basic/ Version: 7800basic v0.18 (14:27:37, Mar 14 2021) Using "" flavored dasm binary. Location: /usr/local/bin/dasm Version: DASM 2.20.14 Starting build of SpacePeril.78b 7800basic v0.18 Mar 14 2021 14:27:37 *** (): INFO, GFX Block #0 starts @ $C000 stars_tile spaceventure_tiles spaceventure_tiles_tallsprite_00 spaceventure_tiles_tallsprite_01 spaceventure_tiles_tallsprite_02 spaceventure_tiles_tallsprite_03 spaceventure_tiles_tallsprite_04 spaceventure_tiles_tallsprite_05 spaceventure_tiles_tallsprite_06 spaceventure_tiles_tallsprite_07 spaceventure_tiles_tallsprite_08 spaceventure_tiles_tallsprite_09 spaceventure_tiles_tallsprite_10 spaceventure_tiles_tallsprite_11 spaceventure_tiles_tallsprite_12 spaceventure_tiles_tallsprite_13 spaceventure_tiles_tallsprite_14 spaceventure_tiles_tallsprite_15 spaceventure_tiles_tallsprite_16 spaceventure_tiles_tallsprite_17 spaceventure_tiles_tallsprite_18 asteroid_wall asteroid_wall_tallsprite_00 asteroid_wall_tallsprite_01 asteroid_wall_tallsprite_02 asteroid_wall_tallsprite_03 asteroid_wall_tallsprite_04 asteroid_wall_tallsprite_05 alphabet_8_wide shipsquare shipsquare_n shipsquare_ne shipsquare_e shipsquare_se shipsquare_s shipsquare_sw shipsquare_w shipsquare_nw pink_transponder pink_transponder_2 energy_cube attractor attractor_2 cannon cannon_2 transfigurator transfigurator_2 voidstone scavenger scavenger_2 spaceblob spaceblob_l spaceblob_r spaceblob_eat spaceblob_swallowed spaceblob_slain forcefield forcefield2 forcefield3 forcefield4 shot shot2 *** (): INFO, GFX block #0 has 320 bytes left (20 x 16 bytes) *** (): INFO, DMA hole #0 starts @ $D000 no code defined for DMA hole *** (): INFO, GFX Block #1 starts @ $E000 titletext2 titletext2_tallsprite_00 titletext2_tallsprite_01 titleship2 titleship2_tallsprite_00 titleship2_tallsprite_01 titleship2_tallsprite_02 titleship2_tallsprite_03 titlefire *** (): INFO, GFX block #1 has 1376 bytes left (86 x 16 bytes) 7800basic compilation complete. User-defined 7800.asm found in current directory Read $2000 bytes of cartridge data. Invalid byte at $FFF8, should be $FF! 7800header 0.13 Mar 14 2021 14:27:38 opened parameter file a78info.cfg 7800makecc2 v0.1 The ROM 'SpacePeril.78b.bin' is compatible with CC2. Quote Link to comment Share on other sites More sharing options...
RevEng Posted September 9, 2021 Author Share Posted September 9, 2021 Ok, can you send me the list file from a broken compile in PM? That might help me track down why dasm didn't report choking on the assembly, despite the fact it only created a malformed 8k rom. 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted September 13, 2021 Author Share Posted September 13, 2021 Looking at this, it appears that a multi-line statement with end doesn't play nice when it's part of an if...then. It trips up the preprocessor, which prematurely ends the program. I think this one is just going to be a documented limitation for now. Multi-line statements in a single-line if...then is going to be clumsy anyway, from a syntax perspective. Maybe at some point I'll take a whack at adding a blockif statement. 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.