Jump to content

AkashicRecord

Members
  • Posts

    220
  • Joined

  • Last visited

About AkashicRecord

  • Birthday 10/20/1977

Profile Information

  • Custom Status
    Programming Tetris
  • Gender
    Male
  • Location
    The Astral
  • Interests
    Retro games and GAMESTOP
  • Currently Playing
    Old-skool NES... Strider, Rygar, and Gun-Nac speedruns.

    https://www.speedrun.com/user/AkashicRecord77
  • Playing Next
    2-Player Atari Tetris?

Recent Profile Visitors

5,155 profile views

AkashicRecord's Achievements

Chopper Commander

Chopper Commander (4/9)

148

Reputation

  1. I'm actually working on that stuff now it makes mistakes but it's not hard to fix them. It seems to get more coherent the farther you go / the closer you get to its token maximum.
  2. I completely agree with all of the sentiment regarding the errors that can be generated from this. Some are downright embarassing, but some of the code is remarkably coherent. Luckily, a lot of the embarrassing bits it generated in error I've already written a few years ago, so its erroneous confabulations wouldn't have been used anyway. 😋 I've almost generated all of the required functions and will soon be ready to piece everything together for fixing and debugging. I have no real confidence that it can properly display an asymmetric playfield, so that's going to have to be all on me, but I completely expected that anyway. I'll share some more of the outputs from last night if anyone is still interested in seeing it?
  3. Me: That sounds great! But first I'd like to take a small detour and flesh out a random number generator...I'll assume that a basic Linear Feedback Shift Register would suffice, correct? Let's write that since it is a general method that can be useful for other game programs. Also, if you can come up with some other useful alternatives to an LFSR, please tell me, but only write the LFSR code for now and comment it, detailing exactly how it works for maximum clarity. ChatGPT: Yes, a basic Linear Feedback Shift Register (LFSR) would be a suitable option for generating random numbers on the Atari 2600. Here's an example of an LFSR implementation in 6507 assembly: ; Variables seedLo .byte 0 ; low byte of seed seedHi .byte 0 ; high byte of seed ; Initialize the seed with a non-zero value ; You could use the frame counter, joystick input, or any other value that changes ; every time the game starts InitializeSeed: LDA #$34 STA seedLo LDA #$12 STA seedHi RTS ; Generate the next random number using an LFSR NextRandom: LDA seedLo LSR ; Shift right and store the carry flag (bit 0 of seedLo) STA seedLo ; Store shifted seedLo BCC SkipXor ; If carry flag is clear, skip the XOR operation LDA seedHi EOR #$B8 ; XOR with the polynomial 0x1B (equivalent to x^16 + x^14 + x^13 + x^11 + 1) STA seedHi ; Store the result in seedHi SkipXor: LDA seedHi ROR ; Shift right, including the carry flag (bit 0 of seedHi) STA seedHi ; Store shifted seedHi RTS This code initializes a 16-bit LFSR with a non-zero seed value and provides a routine to generate the next random number in the sequence. The NextRandom routine shifts the 16-bit seed right by one bit, and if the shifted-out bit is 1, it XORs the high byte of the seed with the polynomial 0xB8 (equivalent to x^16 + x^14 + x^13 + x^11 + 1). This polynomial is chosen because it provides a maximal length LFSR sequence (2^16 - 1 numbers before repeating). Alternative random number generation methods include: 1. Galois LFSR: A variation of the LFSR that updates the register in a slightly different way, providing the same maximal length sequence but with faster computation. 2. Xorshift: A family of algorithms based on bitwise XOR and shift operations, which can provide fast and high-quality random number generation. For simplicity and ease of implementation, the basic LFSR shown above should be sufficient for your Atari 2600 Tetris game.
  4. Me: Now that we have a general code outline, a basic program shell and a few little basic bits, what would be a good approach (in order) for the program? Essentially, what should we start working on next? And for fun, additionally rewrite your response in the style of "Macho Man" Randy Savage. 😋 ChatGPT: Next, we should focus on implementing the core gameplay loop, which consists of the following steps: 1. Initialize the game state, including setting up the playfield, score, and level. 2. Spawn a new tetromino and set its position at the top of the playfield. 3. Handle user input, such as moving, rotating, and dropping the tetromino. 4. Implement gravity, which moves the tetromino downward over time. 5. .Check for collisions between tetrominos and the playfield. 6. Lock the tetromino in place when it cannot move further down. 7. Check for and clear completed lines. 8. Update the score and level based on cleared lines. Repeat steps 2-8 until the game is over (when a new tetromino cannot be spawned). Once the core gameplay loop is in place, we can further refine and optimize the code, as well as add additional features like sound, animation, and game over handling. Now, here's the response in the style of "Macho Man" Randy Savage: Oh yeah, brother! The next step is to snap into that core gameplay loop, dig it? First, we're gonna initialize the game state, setting up the playfield, score, and level, yeah! Then, we'll spawn a new tetromino from the top rope and start handling user input like a champ – moving, rotating, and dropping it, oh yeah! We'll implement gravity, check for collisions, and lock that tetromino down when it can't move, brother. Clear those lines and update the score, 'cause that's what it's all about. Rinse and repeat until the game's over, and you've got yourself an Atari 2600 Tetris masterpiece, oh yeah! Me: ALRIGHT, BROTHER! SNAP INTO IT! OHHH YEAH!!! CAN YA DIG IT? 🤣 ChatGPT: Oh yeah, I can dig it, brother! Together, we'll create an amazing Atari 2600 Tetris game that'll have everyone snapping into the action! Let's keep the momentum going and make this project a true champion. If you have any questions or need more help along the way, don't hesitate to ask. The power of the Macho Man is with you! OHHH YEAH! 💪 😄
  5. Having some fun before diving deeper: I even learned a few things! 🙃 Me: I'm not sure if I would call the Atari 2600's color palette, " limited." It can display more onscreen colors than many (if not all?) 16-bit consoles that were released decades later. Give me a list of 16-bit consoles and their maximum color palette and simultaneous onscreen colors. Please include the TurboGrafx-16 / PC-Engine in this list even though it was technically an 8-bit console...with 16-bit graphics. ChatGPT: You are right; the Atari 2600's color palette is quite impressive, especially for its time. Here's a list of some 16-bit consoles and their maximum color palettes along with simultaneous onscreen colors: - Sega Genesis / Mega Drive: Maximum color palette: 512 colors Simultaneous onscreen colors: 61 to 64 (some tricks allow for more) - Super Nintendo Entertainment System (SNES): Maximum color palette: 32,768 colors Simultaneous onscreen colors: 256 - Neo Geo (AES and MVS): Maximum color palette: 65,536 colors Simultaneous onscreen colors: 4,096 - Atari ST: Maximum color palette: 512 colors Simultaneous onscreen colors: 16 (in low-resolution mode) - Amiga 500 (OCS chipset): Maximum color palette: 4,096 colors Simultaneous onscreen colors: 32 (in normal mode), up to 64 (in half-bright mode), or 4,096 (in HAM mode with limitations) - TurboGrafx-16 / PC Engine: Maximum color palette: 512 colors Simultaneous onscreen colors: 482 (241 background, 241 sprite) While the Atari 2600's color palette is smaller in comparison to the 16-bit consoles listed above, it is indeed impressive for its time, and its ability to display a variety of colors onscreen allows for rich and colorful games.
  6. I'm limited to only ~25 interactions here every 3 hours since ChatGPT-4 has been utterly hammered since its public unveiling, but I still think we can get a lot done within that limited window, time permitting of course! Me: Well, they do say that "size matters!" I think that is doubly true for Atari 2600 programming with only a 4K (or 2K!) target ROM size! Wouldn't you agree? 😋 Let's revisit some of our previously written code for the purpose of discussion on the AtariAge forum, and to flesh out our program from the top down...or the bottom up. (There's probably a 6507 assembly language joke hidden in that statement, see if you can find it!) Write the constants and variables section for our program in a clear and concise fashion. Please include the basic colors for the Tetris pieces that we've already had a go at defining earlier in this session, and explain the correlation between the hexadecimal or numeric values and the actual color represented in respect to the Atari 2600's color palette and the TIA. Recall that we wanted (more or less) "standard" colors for the pieces as influenced by other popular versions of the game. Finally, write 3 clever haikus about the Atari 2600 in the style of H.P. Lovecraft; make sure that the final haiku uses words in ascending alphabetical order only. 😁 ChatGPT: Yes, size indeed matters in Atari 2600 programming, especially with the limited ROM size! 😄 Here's the constants and variables section for the Tetris program: ; Constants RAM_SIZE = 128 TETROMINO_SIZE = 4 GRAVITY_DELAY = 30 ; Tetris piece colors I_COLOR = $36 ; Cyan O_COLOR = $76 ; Yellow T_COLOR = $86 ; Purple S_COLOR = $16 ; Green Z_COLOR = $66 ; Red J_COLOR = $26 ; Blue L_COLOR = $46 ; Orange ; Variables currentTetromino .ds 1 currentRotation .ds 1 currentX .ds 1 currentY .ds 1 playfield .ds 200 gravityCounter .ds 1 linesCleared .ds 2 score .ds 4 The colors are defined as hexadecimal values based on the Atari 2600's color palette, which has 128 colors. These values are used to set the color registers (COLUPF, COLUP0, COLUP1) in the TIA (Television Interface Adapter) chip. The TIA is responsible for generating the video and audio signals in the Atari 2600. The chosen colors attempt to match the "standard" colors for Tetris pieces as closely as possible, given the limitations of the Atari 2600's palette. Now, here are three H.P. Lovecraft-inspired Atari 2600 haikus: In darkest pixels, Where ancient sprites still flicker, The console whispers. Shadows of lost games, Cartridges that time forgot, Atari dreams lie. Abandoned console, Brave terrors of the joystick, Cosmic pixels play. And here's the final haiku with words in ascending alphabetical order: Ancient beings console, Eerie flickers generate, Haunting joystick play. 😳
  7. I don't want to get too far into the weeds just yet, but this is a good spot to get a handle on what programming with GPT as a co-pilot can be like before going farther. Me: I think there's an even better way. Clever bunnies have discovered this little trick over the years. Analyze this method and explain in detail what it is doing, and how it does it. (Also, say "hi" to Andrew Davie on the AtariAge forum!) 😉 [code omitted because it is displayed below] ChatGPT: Hello Andrew Davie on the AtariAge forum! 😊 Now, let's analyze the given code snippet: LDX #0 TXS PHA TXA Clear: PHA DEX BNE Clear Here's a detailed explanation of what this code does and how it works: 1. LDX #0: Load the X register with the value 0. 2. TXS: Transfer the contents of the X register (which is 0) to the Stack Pointer (SP). This sets the Stack Pointer to the very beginning of the RAM. The stack is located in the 128 bytes of RAM in the Atari 2600, starting at address $80 and ending at address $FF. 3. PHA: Push the contents of the Accumulator (A register) onto the stack. This has the side effect of decrementing the Stack Pointer. The value of A register is not important at this point, as the goal is just to modify the Stack Pointer. 4. TXA: Transfer the contents of the X register (which is 0) to the Accumulator (A register). 5. Clear:: This is a label for the loop that will clear the RAM. 6. PHA: Push the contents of the Accumulator (which is 0) onto the stack. This stores a zero at the current position pointed to by the Stack Pointer and decrements the Stack Pointer. 7. DEX: Decrement the X register. Since the X register starts at 0, decrementing it wraps it around to 255 ($FF). 8. BNE Clear: Branch to the "Clear" label if the Zero flag is not set. The Zero flag is set when the result of the previous instruction (DEX) is zero. This creates a loop that runs 256 times, clearing all 128 bytes of RAM. The loop runs twice for every RAM location because of the 256-byte address space of the stack. This method leverages the stack and the behavior of the PHA instruction to efficiently clear the RAM. By manipulating the Stack Pointer and using the PHA instruction in a loop, it can clear the RAM with fewer instructions than other methods.
  8. Doh! Yep, I quickly missed that one last night! 🤣 Part of GPT is teaching it when it's wrong, so lets do that! (BTW, "QuadraSlide" was chosen by AI as the title, and I think I like it!) 😋 Me: Hmm. "STX $80, X" doesn't appear to be a valid instruction. Lets clear the RAM in a different way, otherwise I will inform you, and we will use that. Try to write 3 other potential ways to clear the RAM on startup. ChatGPT: Apologies for the error in the previous code. Here are three alternative ways to clear the RAM on startup: 1. Using STA with a zero-page address: LDX #$00 LDA #$00 ClearRAMLoop: STA $80, X INX CPX #RAM_SIZE BNE ClearRAMLoop 2. Using STY with a zero-page address: LDX #$00 LDY #$00 ClearRAMLoop: STY $80, X INX CPX #RAM_SIZE BNE ClearRAMLoop 3. Using indirect indexed addressing with STA: LDX #$00 LDA #$00 LDY #$80 ClearRAMLoop: STA (RAM_BASE), Y INY CPY #RAM_SIZE + $80 BNE ClearRAMLoop In this third example, you need to define RAM_BASE as a constant. It can be any zero-page address you want. For instance, you can use $00: RAM_BASE = $00 Then, make sure to initialize the RAM_BASE address before clearing the RAM: LDA #<$80 STA RAM_BASE LDA #>$80 STA RAM_BASE + 1 All of these methods should effectively clear the RAM. You can choose the one that best suits your needs or coding style.
  9. Me: Lets start writing the program. Start by creating the most basic skeleton program that we can have which handles clearing the Atari 2600 RAM in a concise, fast, amd idiomatic way, handles VSYNC, then all NTSC scanlines (you can use a simple loop), and finally handles VBLANK. If I made a mistake in requesting this basic "shell" or "skeleton" of a program, and/or forgot any basic details, then please correct me and tell me the reasoning. Display the code. ChatGPT: Here is a basic skeleton program for the Atari 2600, handling RAM clearing, VSYNC, NTSC scanlines, and VBLANK: processor 6507 include "vcs.h" ORG $F000 ; Constants RAM_SIZE = $80 ; Atari 2600 has 128 bytes of RAM ; Main program Start: ; Clear RAM LDX #0 ClearRAMLoop: STX $80, X INX CPX #RAM_SIZE BNE ClearRAMLoop ; Main game loop GameLoop: JSR VSYNC ; Handle VSYNC JSR NTSCScanlines ; Handle NTSC scanlines JSR VBLANK ; Handle VBLANK JMP GameLoop ; Repeat the loop ; Subroutines VSYNC: ; Start VSYNC LDA #%00100010 STA WSYNC STA VSYNC ; Wait for 3 scanlines LDX #3 VSYNCWait: STA WSYNC DEX BNE VSYNCWait ; End VSYNC LDA #%00000000 STA VSYNC RTS NTSCScanlines: ; 192 visible scanlines LDX #192 NTSCScanlinesLoop: ; Draw each scanline ; ... DEX BNE NTSCScanlinesLoop RTS VBLANK: ; Start VBLANK LDA #%01000000 STA VBLANK ; Wait for 37 scanlines LDX #37 VBLANKWait: STA WSYNC DEX BNE VBLANKWait ; End VBLANK LDA #%00000000 STA VBLANK RTS ORG $FFFC .word Start .word Start ChatGPT: This code initializes the 6507 processor, clears the Atari 2600 RAM, and handles VSYNC, NTSC scanlines, and VBLANK in the main game loop. The code is written using the 6502 assembly language, and you'll need to use an assembler, like DASM, to compile it into a binary file that can be run on an Atari 2600 emulator or actual hardware. Note that this is a basic skeleton and does not include any game logic or rendering code. You can extend this template to include the Tetris game functionality we discussed earlier. Me: Now rewrite the above code to handle a PAL Atari 2600 system. ChatGPT: To adapt the code for a PAL Atari 2600 system, you will need to change the number of visible scanlines and the number of VBLANK scanlines. PAL systems have 312 total scanlines, with 50 fields per second. The visible area has 240 scanlines, and the VBLANK area has 72 scanlines. Here is the modified code: processor 6507 include "vcs.h" ORG $F000 ; Constants RAM_SIZE = $80 ; Atari 2600 has 128 bytes of RAM ; Main program Start: ; Clear RAM LDX #0 ClearRAMLoop: STX $80, X INX CPX #RAM_SIZE BNE ClearRAMLoop ; Main game loop GameLoop: JSR VSYNC ; Handle VSYNC JSR PALScanlines ; Handle PAL scanlines JSR VBLANK ; Handle VBLANK JMP GameLoop ; Repeat the loop ; Subroutines VSYNC: ; Start VSYNC LDA #%00100010 STA WSYNC STA VSYNC ; Wait for 3 scanlines LDX #3 VSYNCWait: STA WSYNC DEX BNE VSYNCWait ; End VSYNC LDA #%00000000 STA VSYNC RTS PALScanlines: ; 240 visible scanlines LDX #240 PALScanlinesLoop: ; Draw each scanline ; ... DEX BNE PALScanlinesLoop RTS VBLANK: ; Start VBLANK LDA #%01000000 STA VBLANK ; Wait for 72 scanlines LDX #72 VBLANKWait: STA WSYNC DEX BNE VBLANKWait ; End VBLANK LDA #%00000000 STA VBLANK RTS ORG $FFFC .word Start .word Start ChatGPT: The primary change in this code is the number of visible scanlines (240 for PAL) and the number of VBLANK scanlines (72 for PAL). This should provide a basic skeleton for a PAL Atari 2600 system. Keep in mind that the actual game logic and rendering code will still need to be added to this template.
  10. Let's start building this thing now that we have some stuff to work with! 💪 Me: Summarize everything we've done in this chat up to this point and make it less than 100 words, written as if you have a thick Russian accent. 🤣 Chat-GPT: In chat, ve create Tetris for Atari 2600. Ve discuss game representation, draw playfield, handle joystick input, use asymmetrical playfield, collision, gravity, and drop routine. Ve also create functions for line clear, score, tetromino spawn, and color. All with glorious 6507 assembly. ### I've also attached a few AI-generated box art images: (I know, I'm getting ahead of myself already!) 😋 The prompt used to generate these images was: "very detailed man in a spacesuit, in space, with large, colorful, giant Tetris pieces coming down towards him" (...then I added "Unreal 5 engine" and "raytraced" for the last 2.)
  11. I've been gone for a long while but I'd like to revisit my plans for an Atari 2600 Tetris game (eventually becoming a 2-player co-op version as I was working on in the past.) I've recently been looking at ChatGPT-4 for AI-assisted game development, and have been utterly blown away by how coherent this tool actually is! Here is a snippet of a GPT-4 prompt asking for a general code outline to work from as boilerplate or a template for the Tetris game. Let's see if we can finally finish this thing! Me: Can you generate a brief outline of the program code structure showing how the game functions might be organized in a concise and logical way? Omit the actual code blocks, simply commenting them out with an ellipsis (...). Include functions that we have not fully written yet. ChatGPT: Here's an outline of the program code structure for your Tetris game on the Atari 2600: ; Constants and variables ... ; Initialization code ... ; Main game loop GameLoop: ; Read and handle user input JSR HandleInput ; ... ; Update game logic (gravity, collisions, etc.) JSR UpdateGameLogic ; ... ; Check for line clears JSR CheckLineClear ; ... ; Update game level and input delay JSR UpdateGameLevel ; ... ; Draw the game elements JSR DrawPlayfield JSR DrawTetromino JSR DrawScore ; ... ; Wait for the next frame (VBLANK handling) ; ... JMP GameLoop ; Subroutines ; HandleInput HandleInput: ; ... RTS ; UpdateGameLogic UpdateGameLogic: ; ... RTS ; CheckLineClear CheckLineClear: ; ... RTS ; UpdateGameLevel UpdateGameLevel: ; ... RTS ; DrawPlayfield DrawPlayfield: ; ... RTS ; DrawTetromino DrawTetromino: ; ... RTS ; DrawScore DrawScore: ; ... RTS ; Additional functions ; RotateTetromino RotateTetromino: ; ... RTS ; CheckCollision CheckCollision: ; ... RTS ; DropTetromino DropTetromino: ; ... RTS ; ClearLine ClearLine: ; ... RTS ; GenerateNewTetromino GenerateNewTetromino: ; ... RTS ; RandomNumberGenerator RandomNumberGenerator: ; ... RTS Chat-GPT: This outline shows a logical organization of the game functions, including some functions that we haven't fully written yet. The main game loop calls each of the necessary subroutines to handle user input, update game logic, check for line clears, update the game level, and draw game elements.
  12. One thing I didn't know until recently was that Doug Neubauer (of Solaris fame) did M*A*S*H as one of his first games.
  13. I fired up Dragonstomper under Stella and was immediately impressed to see an RPG on the 2600, and that was less than 5 minutes into the game. I would have gone apeshit over that game back in the day! Adventure certainly qualifies, and might have been one of the earliest of the "deep" games on the VCS. That said, Adventure went over very well just last weekend, even. I brought my light-sixer and 37 games to a family / friends out-of-town trip and set up a TV in the hotel lobby on a table. Within minutes, there was a sizeable crowd flocking around the TV and more than one person asked if I had Adventure, and the answer was an obvious, "of course!" The parents all seemed to enjoy re-living a little bit of their childhood...
  14. You might want to consider changing your thread title because it doesn't exactly read very well. You won't get the response that you want...
×
×
  • Create New...