Jump to content

Sknarp

New Members
  • Content Count

    79
  • Joined

  • Last visited

Posts posted by Sknarp


  1. I can replace the quoted in the above post with

    Quote

    setscorepointers
     SLEEP 77
    wastetime
     rts

    scorepointerset
     sta WSYNC
     rts

    to free up the scorepointers variables, but I feel like this is a really inefficient way of doing it. Could really use some ASM god to chime in here please.


  2. It does free up the three score vars for whatever use you want, unfortunately it does not free up the 6 scorepointer vars because that's the one part I have yet to figure out (see below). As far as cycles are concerned, about 3-4k of asm is being completely removed, and while some of it was conditional (such as if const debug was set) a lot of it just always was executed. I replaced all of that with something like 3 WSYNCs over the course of the kernel, not entirely sure what the effect on cycle count would mean (should be faster?) Not sure how to measure it.

    All that remains of the score code (with my added comments, sorry if they aren't 100% accurate) if someone can figure out how to skip all of this (Sleep? WSYNC again?) then those 6 additional vars could be free space in the mem map as well. Best I can figure this is what allows for the tens places in each section of the score?

    Quote

    setscorepointers
     lax score+2               ;simply loads the score vars
     jsr scorepointerset       ;one at a time
     sty scorepointers+5       ;jumps to scorepointerset
     stx scorepointers+2       ;and back here to do same thing with next var
     lax score+1               ;note that the score vars arent changed, just scorepointers vars are
     jsr scorepointerset
     sty scorepointers+4
     stx scorepointers+1
     lax score
     jsr scorepointerset
     sty scorepointers+3
     stx scorepointers
    wastetime
     rts

    scorepointerset
     and #$0F         ; score is in A and X, makes the the lowest four digits zero
     asl              ;   over the course of these shifts the 16s place digit becomes
     asl              ;   the 128s place                         
     asl              ; now shifted the number left 3, so we now should have  a000 0000
     adc #<scoretable ; ???.What is scoretable?   
     tay              ; move A (shifted: a000 0000) to Y  
     txa              ; move X(unshifted) to A
     and #$F0         ; makes the 4 highest values of A zero (0000 aaaa)
     lsr              ; shifts right once, now we should have 0000 0aaa
     adc #<scoretable ; ???? this again.What/where is scoretable?
     tax              ; move A  to X
     rts              ; X will store to scorepointer, Y will store to scorepointer+3

     

     


  3. Yeah I can see a couple of things, when you use lda you're undoing the prior randomization stored in the accumulator . Also, the jsr's all loop to one another. Even if your randomization works the program flow could theoretically end up looping forever. It would be better to have a routine with a predictable execution time, like any of the examples already posted.


  4. Saved another 124 bytes by replacing 10 if-then statements with 1 on-goto and shortening labels in the

    part of the code that changes the playfields. This was something I had been meaning to do for a while,

    but got sidetracked with trickier optimizations.

    I still have to program the second game mode, win conditions, and reset switch support. Right now there

    are 10 screens (not counting the title), I'd like that number to be 20 or 30 so I have a lot more pixel

    drawing to do. Currently at 960b free.

    Title screen, shows how CTRLPF manipulation can be used to get around MSK limitations.

    WIP_02_TITLE.thumb.png.07f99faa6c7749a8dcc9d80b05f0a3b6.png


  5. Reclaiming bytes via kernel

     

    558b free

     

    Spoiler

    So in the previous post I mentioned that I had 558b free and that I was sure I could reclaim more. First off, that 558b was with the debugscore on, which uses 190 bytes more than no options, or 170 bytes more than the noscore option. So if I was to set it to const noscore=1 then I would have 728 (558+170) bytes free. I don't plan on using the score at all so that's the best I can do right? Well, not if we actually dig into the multisprite kernel and see that a lot of that space is being used for the score routines, which we don't need. After a bit of trial and error and  a few extra STA WSYNCs, I was able to make a scoreless MSK. In total this saved 86 bytes! Free space: 814 (728+86)

     

    814b free

     

    So that saved some bytes, but here's another idea, which DOES NOT save any bytes, but this shows how I went about testing it.

    Reclaiming bytes via RAM sprites
     

    Spoiler

     

     rem EXAMPLE ONE
     rem drawing an arrow to player0 sprite in ROM
       player0:
       %00000000
       %00010000
       %00111111
       %11111111
       %00111111
       %00010000
       %00000000
    end
     
     rem EXAMPLE TWO
     rem using RAM s-y
     s=0 : y=0 :  player0pointerhi=0
     t=16 : x=16
     u=63 : w=63
     v=255
     player0pointerlo = $E9
     player0height=7

     rem EXAMPLE THREE
     rem using ram s-y and in ASM
     asm
     lda #0
     sta s
     sta y
     sta player0pointerhi
     lda #7
     sta player0height
     lda #16
     sta t
     sta x
     lda #63
     sta u
     sta w
     lda #233
     sta player0pointerlo
     lda #255
     sta v
    end

     

    So the second and third example both work just as well as example one, and I was willing to remove "LDA #255" since it would have sped up the routine and would only have caused there to have been two dots in the middle of the arrow, I could live with that. The problem was simply that doing this doesn't save any ROM at all... I believe this is because of the images being stored as bytes that need to be page aligned, so this doesn't circumvent that requirement. I scrapped this idea because it's not useful in this application.


  6. SUCCESS!

    I figured out what the problem was, the scorepointerset and setscorepointer routines are either required by or factored in to the screen drawing. I was able to remove everything else and ended up with a working scoreless multisprite kernel. As far as I'm aware, any options will have no effect on this kernel, so you don't need to set noscore, and setting something like debug will do nothing.

    Quote

     748  bytes free with fixed MSK
     728  bytes free with const noscore defined
     814  bytes free with noscore_MSK


    This is a savings of 64-86 bytes!

    noscore_multisprite_kernel.asm

    • Like 1

  7. On 7/29/2019 at 10:29 PM, Sknarp said:

     If you want to compile this you'll need the modified includes in the same directory, otherwise there's not enough free space.

    WIPsourceAA.bas 18.82 kB · 20 downloads multisprite_kernel.asm 15.49 kB · 18 downloads score_graphics.asm 929 B · 18 downloads

    Final version and source above. Might still have alignment issues that need to be fixed, but this is the most complete version as far as I know.

     

    WIP_01_ATAX.thumb.png.3350945553c36626ceb6b04e28dfd793.png

     

    ATAX-ATAX is my newest project. I've been working on it for about 8 days so far, so I figured I should try to keep track of my development. I still have quite a lot to do. This is going to be a 4k game, but I'm confident that that won't be a limiting factor in this project. If you're curious why I think 4k will be plenty of room:


     

    Spoiler

     

    ---BITS!---
    There's several places where I only need 1 bit: The player0 has four directions to

    move in, we can assign each one to a bit for four bits total. The player0's reflected

    property can be stored in one bit. Player1 needs a 1 bit flag for his missile's

    direction of movement and one bit to control it turning around when it reaches the

    edge of the sceen, we can use one bit per flag for a total of two bits. This adds up

    to seven bits, I put all seven bits in one variable, and made sure that single unused

    bit is being masked in all operations, so that unused bit can still be utilized for

    something else later.

    ---Shared sprite data---
    Four of the five enemies have the same sprite, so I just have one copy of the sprite

    data and use an indexed loop to set the other three pointers to that one, saving a lot

    of bytes that would have been used by the three redundant sprites.

    ---Understanding NUSIZ and CTRLPF---
    So I wasted time reverse-engineering the NUSIZ and CTRLPF options when all this

    information already exists somewhere online. Anyway, once I understood what each bit

    was being used for I found that using binary made it much easier to work with. Doesn't

    save much, just makes the work go by faster.

    ---ASM init's---
    I've been rewriting all the variable inits to optimized ASM. Overall a lot of LDA's

    can be removed or changed to shifts and while each change is small it can add up.

    ---A world without BCD---
    I've stripped every single BCD number out, in effect everywhere that used a BCD

    previously now uses a binary number which overall means a pretty big savings in bytes.

    ---Low cost logic---
    I use things that have reliable values to drive multiple events, rather than waste by

    using a seperate variable for each action. On the title screen a single 1-byte counter

    is being used to fade in the title screen, play/stop playing a sound effect, and

    restrain the fire button at the same time. This same counter is being used in the main

    loop for an enemy respawn timer, to adjust the probability of player1 attacking, and

    to slow down the speed at which player0 takes damage at the same time.

    ---simple math only plz---
    I take the time to make sure the math is simple... most of the numbers are divisable

    by two. Actual divison is used sparingly and always in powers of two. I use bit

    shifts. The same logic is applied to the vast majority of my comparisons, I focus on

    checking for zero or nonzero instead of comparing to numbers whenever possible.

    ---simplified AI---
    I control one of the five enemies with one bit for it's AI. The other four enemies are

    controlled with one loop, with just a few lines of code outside of the loop to allow

    one of them to shoot missiles.

     

     

     

    So anyway, I've got the sprites displaying correctly, I have a good chunk of game logic in place, and at this point I'm up to ten screens and have 558b left. I am sure I can reclaim more bytes, and that i can fit plenty more in. I'll try to keep updating as things happen instead of as a retrospective.

    • Like 2

  8. On 3/16/2019 at 10:20 PM, OldSchoolRetroGamer said:

    What Flomojo said above, as well......

     

    At the time these were made not all TV's were color. It is not so much choosing to play in B&W, if you happen to be using the console on a B&W display (again very common back in the day) you would select the option so the games would simply look better on a black and white display. The output is tweaked to have better contrast etc. Not to dissimilar to old movies and TV shows that were filmed in black and white but knowing they would be viewed on B&W Television the actors and sets were actually very odd looking "color" palettes. For example, the old Superman series George Reeves wore a brown for red, gray for blue and white for yellow suit. This looked odd to people on set of course expecting the famous red, white , yellow suite but made for a more outstanding look on TV's that could only display B&W. Sadly, I am old enough to know this first hand but for reference and to verify what has been said already

     

    http://nerdlypleasures.blogspot.com/2015/03/the-forgotten-switch-atari-2600s-b.html

    Immediately made me think of the Addams Family set

    iizvpc1k9dv11.jpg

    • Like 3

  9. Quote

     p0dir=0

     if joy0up then p0dir=1
     if joy0down then p0dir = 2
     if joy0left then p0dir=3
     if joy0right then p0dir = 4
     if p0dir = 1 then player0y=player0y-1
     if p0dir = 2 then player0y=player0y+1
     if p0dir = 3 then player0x = player0x-1
     if p0dir = 4 then player0x = player0x+1

    Just make sure you dim p0dir to a variable first, something like dim p0dir = a


  10. What I think orange808 meant was if I am not using the score at all that I should remove all the score code from the multisprite asm so I can gain back the bytes that it wastes (I think this is what they meant anyway and it is a good idea)

    I attempted to do this, but now I have an issue where sprites, ball, missiles all have a strange x offset problem (worse the closer to the bottom of the screen it gets). If this can be fixed then a completely scoreless kernel could save about 70 bytes on one where the code is just being skipped.(not to mention the parts of the mem map that could be freed up) Here is what I have, right now you have to use const noscore=1 and since score is completely removed you can't use this kernel for debug or cyclescore either.

    multisprite_kernel_scoreless.asm


  11. Sorry, I thought since it's an asm question it belonged with other asm questions. I'm a little confused...

    There's no mention anywhere of what "the fix" is that I could find- except a different post that as I mentioned said to add two PLAs before the jmp. Is this all the fix is, or is the fix something else completely?

    I'm not using any modifications here, I've reverted back to stock when the above mentioned (pla) fix didn't change anything.

    Sending you a PM with the files you requested.

     

    EDIT: Thank you Karl G for reviewing this and sending me a fixed asm- I also think I probably forgot at some point to move the newest modded include into the same directory *facepalm* so it wouldn't have changed anything anyway.

    • Like 1

  12. Hello, I've been looking for a solution to this for over a day-

    const noscore =1

    in

    multisprite kernel

    This is documented as being broken, I found a post where Karl G said he "found a fix" but the only other mentions are one suggestion to modify multisprite_kernel.asm with 2 pla's, which I  tried and did nothing, and a custom multisprite.h, which I downloaded and tried and did nothing.

    Description for those unfamiliar:
    When setting const noscore in multisprite kernel games you end up with screen rolls, playern's flying off the screen, general chaos. obviously something is very wrong with the noscore jump in the MSK. There are a million little nuances to this kernel, I can deal with/work around/fix most of them, but this one is stumping me.

    I'm currently using a 4k rom, so no need for bankswitching stuff, if that makes a difference in how this can be fixed. Any help?

     

    EDIT: I ended up removing all the score related code from the kernel. I have managed to free up the roughly 70bytes (86 bytes)  Also frees up 10 vars (score and scorepointers) also you do not need to use const noscore so that saves you a few bytes itself. (Roughly 108 bytes in total savings)

    The ASM on THIS post is the most recent version
     

    SansScore_multisprite_kernel.asm


  13. If I have the option, I'll go physical. It's nice to hold something in your hands and not just have your physical money disappear into digital content. Besides that there are usually limitations on digital copies, like only being able to have them on so many different platforms, requiring an internet connection despite already having the full game, etc. Even if those aren't an issue, the simple fact that console companies keep trying to kill off the second-hand games market is a sore spot for me. I like being able to trade disks with others, something digital copies deprive us of.
    If I don't have the option, digital is fine. I own several digital games because the physical version was simply too difficult or too expensive to acquire. It's also the most reasonable way to share indie/homebrew games (my games.niche website is all digital only for this reason, no cost for media overhead). I was tempted to select "don't care" because if digital is the cheapest/easiest/only way to get a game, it's perfectly fine.
    Streaming? I think you'll have a hard time finding anyone who's excited to stream games, unless they work for google stadia. One possible reason is that streaming a game makes it feel like you don't own it at all, but that's just speculation.


  14. Chiming in with some specific incompatibilities on the Atari FB9 w/ composite outputs. I did a search and saw this requested in several places but not actually posted. Here's some of the ones I've found.

     

    Demos seem to run slower than intended:

    4kra VCS
    Sphaera stellarum

     

    Games that (I assume use multipsrite kernel) have a syncing issue that causes problems:

    Bit Quest
    Halo 2600

     

    Games that just don't run at all:

    Alien Pinball

    FNAF 2600
    Gizzle Wap and the.... blizzard
    Reindeer Rescue
    Stay Frosty

    Stratogems_DX
    Toyshop Trouble
    Pitfall II Lost Caverns
    Zippy the Porcupine
    Probably anything over a certain file size...

     

    Games that function oddly:
    SC games like SC Space Invaders (I believe this is a known glitch, haven't tried patched versions)
    Princess Rescue (The enemy AI stops working at a seemlingly random point during play)
    AVGN the game (The title screen is off sync, otherwise fine)
    Cosmic Ark and any game that uses the "starfield effect" (Plays fine, but the starfield effect isn't present- instead the stars just appear as long strips)


  15. CHANGELOG

     

    Original WIP (alpha):
     

    Spoiler

     

    Level 3 and onward: left side of screen has pfpixels randomly flipped on each new room loaded
    Level 6 and onward: Obstruction added to right side.
    Level 9 and onward: Second right playfield obstruction

    Level 12 and onward: Final large obstruction (stretching into the middle play area)

    Level 15 and onward: Extra enemies on shooting screens equal to level / 4 ( so 4 extra spawns at level 16 and so on)

    Level 20: Crazy rainbow strobing starts

    Level 22: Reverse-moving scanline added as distraction

    Level 23: scanline doubles in width

    Level 24: scanline doubles again

    Level 25: playfield becomes invisible

    There's no ending, it's just survival/score based like classic Atari. You use up/down on the titlescreen to select a starting level from 1-15, and then press fire or hit the select switch to start playing. 

     

     

     

    Beta:
     

    Spoiler

    Level select increased from 1-15 to 1-255
    gem and enemy spawns are more balanced and more directly based on the level
    party lights no longer make jarring noises
    enemy movement slightly more random
    hitting an enemy with your shot now resets the shooting delay
    "invisible" levels given a more fair lightning-flash effect
    health bar & game over added
    BW switch can be used to disable the constant HP drain
    Reset switch returns you to title from game/game over
    small tweaks to the score handling and coloring
    CRT has 4-directional sprites
    fixed a glitch that occasionally caused an enemy room to be empty

    Final:
     

    Spoiler

    Boss rooms added + boss attack & sfx
    reworked the level #s for playfield changes
    fixed mistake of repeated sprite data in the source
    reworked timing of certain counters
    small tweaks to random-driven events
    moved the HP drain toggle to left difficulty switch
    reached the maximum for a 4k ROM

     

    Final version added to first post.

     

     

    • Like 1

  16. This is a great question, agree it's probably different for everyone but the OP did seem to only ask for personal opinions.
    I would be willing to call anything that you can't just go and buy at a store today to be retro, but if that's way too inclusive then I'd say that in this particular case, bits would make the most sense to go by, as in essence, at it's lowest level, the number of bits available determine how much can be done at any given time. That being said, it's still super fun to mess around with limited older consoles because the limitations are what force creativity.

    • Confused 1

  17. Hello, setting up an IDE is usually the first big hurdle, so I'll offer some points to go over:
    1. Directory: I always like to keep programming stuff as close to the C dir as possible to limit on long directory names, for example I use for visual BB
    C:/Atari2600/Visualbb

    bb itself I have in
    C:/Atari2600/bataribasic
    I've always found this practice helpful in the long run

    1b. Directory spaces: As mentioned visualbb doesn't seem to like spaces anywhere in the file path, so when you label your folder try to avoid uses spaces anywhere.
    2. Follow the installation guide- I just set up visualbb recently and as I recall you had to: install an emulator, install bb, possibly move a few specific files, run an installation file (presumably to set registry values), set paths within visualbb itself, and THEN you can start using it. (There's also warnings everywhere not to cheap out and use the tinkernut installer- it's outdated and will cause issues)
    3. When you start, start with some extremely simple, small program, like just drawing a specified screen.
    4. If you start running into errors that make no sense (like blank characters being marked as syntax errors- which they are NOT actually the error almost assuredly) then rem out or take your code and drop it into a text file, then go back and refer to point 3 and  add code back in one small section at a time, when the compilation finally breaks again you can then focus on the last chunk that you added and you'll find where the mistake is a lot easier that way.

    5. It's okay to add one line or change one variable and do a recompile, this way you can see right away when something breaks, and if it's not an easy fix, you can just delete it and be back to having a working program again.

    6. invisible binaries? If your file path has a space in it somewhere, sometimes visualbb will SEEM to be working fine, you can even compile and test run code, but when you go to the bin directory nothing will be there. It seems like this is because when you click the run button from the IDE it actually compiles and runs a temporary file, which is deleted the moment you close it. So refer to point 1b to make sure that the compile actually works as intended.


  18. Help CRT, the chromatic alien life form, to find his way through 255 levels of increasing difficulty. Collect Rainbow Gems for power, defeat Evil Things that want to suck all the color out of existence, and bring color to the universe. Thank you to Zeropage Homebrew for giving me some ideas on things I could fix, and thank you Karl G for providing the statusbaronly mini-kernel.

     

    Final Version:
    Gem rooms: 25 points each, restore HP (40% chance)
    Mob rooms: 100 points each, chases player (40% chance)
    Boss rooms: 500 points and full HP upon kill, uses a beam attack (20% chance)

    level 2: pfpixels flip randomly each new level
    level 4: permanent wall 1 (right)
    level 6: permanent wall 2 (right)
    level 8: permanent wall 3 (center)
    level 10: permanent wall 4 (left)
    level 16: rainbow strobing playfields
    level 18: 1 pixel reverse scanline
    level 20: 2 pixel reverse scanline
    level 22: 4 pixel reverse scanline
    level 24: playfield flashes visible/invisible
    Enemies: 1 to 3 + (level/4) enemy spawns
    Gems: 4 + (level/4) gem spawns
    Bosses: 4 to 5 + (level/2) Boss HP


    Main screen: select level from 1-255 using up/down, start with fire or select.
    Game: move with up/down/left/right, shoot with fire, collect gems, kill enemies, advance to the next room when the north wall opens up. Reset switch returns to title screen. Left Difficulty Switch toggles the constant HP drain.
    Game Over: use the Reset Switch to return to title

     

    *Not Recommended for people with photo-sensitive epilepsy*

     

    CRT_Final.bin

    • Like 3

  19. Yeah.. I stuffed about as much as I could into 4k with my current skillset. (EDIT: Better example of a 4k game)

    This is abandoned, no updates are planned. I've uploaded the source BAS so you can play around with it yourself.

    Title screen, win screen, platformer, 10 screens, two unique deaths, and a few bleeps and bloops.
    Press Down to charge a higher jump. Press Fire to jump. Left/Right self explanatory.

     

     

    PNPJ_Fixed.bin

    PixelNinja.bas

    • Like 3
×
×
  • Create New...