Jump to content
IGNORED

Pong 512 Bytes (2600)


Wickeycolumbus

Recommended Posts

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

Link to comment
Share on other sites

...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).

Link to comment
Share on other sites

...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!

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 :cool:

 

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

It might be possible if there is no scoring :ponder:

 

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...