Wickeycolumbus Posted February 14, 2009 Share Posted February 14, 2009 I've been seeing a lot of 1K mini games lately, and I wanted to take a stab at making a game with a small amount of ROM. I managed to squeze Pong into only 511 bytes (one byte to spare!). It is 2 player only (no room for AI) and uses joysticks and no sound (no room for that either). It took me a couple of hours to complete. Here is the Binary and Source. Enjoy! Pong512Bytes.bin Pong512Bytes.asm.zip Quote Link to comment Share on other sites More sharing options...
gambler172 Posted February 14, 2009 Share Posted February 14, 2009 Hi Rick Great..... greetings Walter Quote Link to comment Share on other sites More sharing options...
supercat Posted February 14, 2009 Share Posted February 14, 2009 ...and no sound (no room for that either). Sound doesn't have to take a whole lot of space. Perhaps as few as four bytes. Possibly even three. If you add a "STA AUDV0" someplace each frame when the bottom four bits of the accumulator are zero but before you handle your ball bouncing logic, you can then use a read-modify-write instruction on AUDV0 to produce a click. If you use INC AUDV0, you'll produce a level-ten click (clearing the zero flag and not affecting any others). If you do "LSR AUDV0" you'll get a level-8 click and the carry flag will be set (if you're lucky, the two-byte LSR instruction will let you avoid an SEC). If you replace AUDV0 with AUDV1 everywhere, the LSR will clear the carry. Not that such clicks would be considered 'great sound effects' by any stretch, but they'd be cheap to code. If you could somewhere squeeze in storing 4 to AUDCx and AUDFx, the clicks would be replaced by high-frequency beeps (at a cost of another four bytes). Quote Link to comment Share on other sites More sharing options...
GameboyReviewer Posted February 14, 2009 Share Posted February 14, 2009 This game is brilliant dude I never thought I would see this in my life time, gold dude Quote Link to comment Share on other sites More sharing options...
Wickeycolumbus Posted February 14, 2009 Author Share Posted February 14, 2009 ...and no sound (no room for that either). Sound doesn't have to take a whole lot of space. Perhaps as few as four bytes. Possibly even three. If you add a "STA AUDV0" someplace each frame when the bottom four bits of the accumulator are zero but before you handle your ball bouncing logic, you can then use a read-modify-write instruction on AUDV0 to produce a click. If you use INC AUDV0, you'll produce a level-ten click (clearing the zero flag and not affecting any others). If you do "LSR AUDV0" you'll get a level-8 click and the carry flag will be set (if you're lucky, the two-byte LSR instruction will let you avoid an SEC). If you replace AUDV0 with AUDV1 everywhere, the LSR will clear the carry. Not that such clicks would be considered 'great sound effects' by any stretch, but they'd be cheap to code. If you could somewhere squeeze in storing 4 to AUDCx and AUDFx, the clicks would be replaced by high-frequency beeps (at a cost of another four bytes). I currently only have one byte free, but Im sure I can find a few so I can add some sound. I will try to free some later tonight This game is brilliant dude I never thought I would see this in my life time, gold dude Thanks! Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted February 14, 2009 Share Posted February 14, 2009 Now someone do Pong in 256 bytes. Quote Link to comment Share on other sites More sharing options...
Wickeycolumbus Posted February 14, 2009 Author Share Posted February 14, 2009 Now someone do Pong in 256 bytes. It might be possible if there is no scoring Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted February 14, 2009 Share Posted February 14, 2009 You can save space by cutting out the extra WSYNC's following the positioning subroutine calls. As far as that goes, the can be cut from the end of the subroutine as well (performing a single WSYNC/HMOVE after all sprite positioning). The subroutine doesn't really need to be a subroutine...it could be a loop instead (fetching initial horizontal positions from a table)...or at least a BRK interrupt. Anyway, after the subroutine or loop has executed once for game setup, clear HMCLR and HM positioning to move the ball horizontally for the remainder of the round. Also, the 4 reads to SWCHA can be reduced to one. Use LSR/BCC to test the bits after altering the order they are checked. Resetting the stack pointer to the missiles and ball means that you can push processor status to enable or disable them after a comparison. It shouldn't take much space to code in a paddle version, tho. The 2 CX reads can be done with BIT instead (to use BMI/BPL for bit7, and BVS/BVC for bit6). The 50-byte score gfx stretch can be reduced to 21 bytes and a 10-byte lookup table. Quote Link to comment Share on other sites More sharing options...
Wickeycolumbus Posted February 14, 2009 Author Share Posted February 14, 2009 I did some of the optimizations Nukey mentioned and was able to add sound (with 2 bytes to spare!). I am going to try a 256 byte version now Also I used an lax to position P1 on pixel 1, but it seems that dasm had trouble assembling it (I am using V2.20.07) so I simply inserted a '.byte $AF,$01' and that did not work either. It is now '.byte $AF,$00,$01' and it seems to work. The 50-byte score gfx stretch can be reduced to 21 bytes and a 10-byte lookup table. How would I go about doing that? Pong512BytesSound.bin Pong512BytesSound.asm.zip Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted February 14, 2009 Share Posted February 14, 2009 How would I go about doing that? Overlapping graphics is the key. Check my 1k games code for example. Quote Link to comment Share on other sites More sharing options...
Wickeycolumbus Posted February 15, 2009 Author Share Posted February 15, 2009 I'm working on a 256 Byte version How would I go about doing that? Overlapping graphics is the key. Check my 1k games code for example. Thank you, I will hopefully I can include that in the next version. Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted February 15, 2009 Share Posted February 15, 2009 BTW because ram is in such low use, you could write a self-modifying kernel that places itself in ram...then just update the specific bytes for the missile paddle enable/disable, then execute it by jumping there. The downside is that the initial kernel would probably need to be transferred from ROM (so it would have to be weighed which method yields the most leftover ROM). HMBL is still the easiest way to update the ball. You only need to keep track of the vertical location of when to enable it...and have the collision registers dictate which value to use for HMBL. No collision after a given number of frames results in a win for the last missile that the ball struck. Quote Link to comment Share on other sites More sharing options...
supercat Posted February 16, 2009 Share Posted February 16, 2009 It might be possible if there is no scoring How about showing the 'score' using something like the horizontal positions of the player sprites? Reset them both to zero, and then bump a sprite 8 pixels right when a player scores. Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted February 16, 2009 Share Posted February 16, 2009 Pitfall! does something similar to display lives. It starts off with %11011011 in a variable, the LSR's it 3 times when a deadly collision occurs. Branching on zero does the rest. So you could have a 5-point game (to keep a pixel between each "point") by setting carry and rolling it into an initially-empty variable. When a carry occurs on the opposite end of the byte, that player has won. Quote Link to comment Share on other sites More sharing options...
Wickeycolumbus Posted February 16, 2009 Author Share Posted February 16, 2009 It might be possible if there is no scoring How about showing the 'score' using something like the horizontal positions of the player sprites? Reset them both to zero, and then bump a sprite 8 pixels right when a player scores. That is not currently possible. I reuse part of the game logic for the horizontal positions of the players like this: ;; In the variable declarations Ball_X equ $E8 ;; the Positioning loop lda Ball_X ldy #4 Pos_Loop sta WSYNC sta HMCLR Div_Loop sbc #15 bcs Div_Loop eor #7 asl asl asl asl sta HMP0,Y sta RESP0,Y sta WSYNC sta HMOVE lda Positions,X inx dey bne Pos_Loop ;;Then finally in the game logic ldy #70 ;80 Positions sty Ball_X sty Ball_Y sty Game So using 'sty Ball_X' as the horizontal positions is the same as .byte $84,$E8 which positions the missiles to the appropriate positions. Quote Link to comment Share on other sites More sharing options...
vdub_bobby Posted February 18, 2009 Share Posted February 18, 2009 The 1/2K version is very cool, but: a) it is currently almost unplayable since the paddles move too slowly, and b) you need more than one angle! It's more like a tech demo than a game. Quote Link to comment Share on other sites More sharing options...
Wickeycolumbus Posted February 18, 2009 Author Share Posted February 18, 2009 The 1/2K version is very cool, but: a) it is currently almost unplayable since the paddles move too slowly, and Yes, I have to update that as I did in the 1/4K version. b) you need more than one angle! It may be possible to have more than one angle and AI if I add onto the 256 Byte version and not try to incorporate that into the current 512 Byte version. 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.