Jump to content

CPC464Kid

New Members
  • Posts

    16
  • Joined

  • Last visited

Profile Information

  • Gender
    Male
  • Location
    United Kingdom

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

CPC464Kid's Achievements

Space Invader

Space Invader (2/9)

18

Reputation

  1. Makes sense, thanks Andrew. I'd just need to be careful to keep the maximum length sensible to allow for more turns after the snake grows, and I guess the player will also make more turns when the snake is longer as there would then be less free screen space. Otherwise I could run out of memory when the player tries to change direction!
  2. True, most of time you won't be making many turns. I guess the issue is also being able to support the extreme cases where somebody keeps twisting and turning. The edge cases are always the problem ? I like the ideas though. I think I'll start by converting what I've got to use movement values and see how that goes. I'm finding that small incremental changes are the way to got with 6502 because otherwise it's hard to figure out where you've broken something!!!
  3. Interesting idea, but I still think I will need to store the "move directions" (2 bits per segment) that you suggested before. I don't think it would be possible to find the adjacent set-pixel without storing all the movements. Or at least I don't think my brain could cope with trying to find the correct one! That's what I meant with the trade off as I'm now planning to store movements rather than the snake itself, but if the PF gets too big I won't be able to store enough movements. I will think about this properly when I've got more free time and start refactoring the code. Thanks for all the ideas, you definitely need to think outside the box with the 2600. I'm more used to C and C++ applications where nobody cares about memory anymore!
  4. Thanks Andrew, that is true. Although currently I'm actually only using two bytes per row (my rows are 8 scan lines deep), with a further 6 temporary variables used inside the kernel to keep track of what to load into the PF registers for the current and next row. The values for the next row are built up during spare cycles in the current row from these two bytes etc. Effectively I've got a 16x16 bit table that represents my playfield (excluding the side walls) and the actual PF data is temporary (changing every 8 scan lines). I might need to think about storing the data in a format that fits the PF registers instead to get full screen width. I guess it would be a trade off between RAM consumed for the playfield and RAM available for the snake to grow! I'll see what I can do ? Perhaps just extending it from 16 PF pixels wide to 24 PF pixels would be a good trade off. Although making it full screen would be a good technical challenge!
  5. Yes, your right with 149 I do find myself at cycle 74 on the return. I was just checking that it returned on the same scan line, but of course that doesn't leave enough time for WSYNC ? The calling code would have to take that into account and skip the WSYNC if the X position were greater than 134. Another option would be to WSYNC and HMOVE within the subroutine before returning (if you don't need to move multiple things at once). Or if using a timer during vertical sync it wouldn't matter of course. Good discussion!
  6. Cool, good to know thanks. I think that is another bug as it's supposed to only put the dots on empty squares, but I'll look at that another day!
  7. cool, I look forward to seeing that ?
  8. Hi Dennis, I've just checked with Stella and when A = 0 the scan cycle (CPU cycle) is 23 when the PC is pointing at the RTS instruction. The position is set to 6 and HM is also 6 (meaning we do eventually end up with position 0 as requested). The timing of the reset is exactly the same, but the subroutine can return right after because HMP0 has already been set. An adjustment is also made for balls and missiles. At the other side of the screen when I set A to 149 it just returns in time. At 150 it starts to spill over onto an extra scan line. Not too bad I think ?
  9. Thanks for the encouragement @Armscar Coder. When I get a bit further it would be useful to have somebody test on real hardware. I've managed to resist buying a 2600 from eBay because I know it won't look great on my modern(ish) TV, and I need to stop filling my house with such things!
  10. Now fixed with replacement rom attached above! Thanks again for spotting this James @ZeroPage Homebrew
  11. Thanks James, well spotted. I knew about moving left before you start and that was just lazy programming, but the other cases I hadn't considered. Just had a quick look and I think it's because I am checking the joystick and updating the direction every frame, but only moving every 10 frames. So if you change direction very quickly it gets confused. I will fix this!
  12. Thanks @Andrew Davie that's a brilliant idea. I never thought about it that way, but of course your right ? I still need 1 bit of storage for every playfield square because the kernel needs to know what PF bits to set on each line (I'm currently using 32 bytes for this), but my 70 odd free bytes would still give a body length of 280. Obviously I'll also need to make the playing area bigger but your idea gives a lot of scope for improving things. I'll try using this technique. A two player version would also be cool.
  13. It looks really good and was fun to play - very professional effort. Reminded me a little of Paperboy or Trashman. I managed to score 12576 ?
  14. Updates Playfield is now 1/3 wider (24x16) and the maximum snake length is more than double at 200+ segments, all thanks to @Andrew Davie's very cleaver storage optimisation idea (I am now using just 2 bits for each segment by storing movement values instead of locations). Known issues / bugs Random number generator does not yet cover the extra screen area (it still works with a 16x16 grid). The score will now wrap around if you exceed 99 ? Hi, I'd like to share my first Atari project which is a little snakes game. I'm sure this has been done before, but as I wrote one years ago for Windows it seemed like a good place to start. The major challenges were finding enough memory to maintain a long (ish) snake and having to manipulate the playfield registers on every scanline whilst also drawing a couple of sprites. I originally started using a linked list to maintain the snakes body (requiring two bytes per segment), but quickly started running out of RAM. This is the most obvious algorithm for a computer, but clearly not for the 2600. I now just use an ordered list (one byte per segment) which is reshuffled whenever the snake moves to maintain the order. This is very inefficient, but the CPU has nothing else to do at the end of a frame so actually makes sense. I'm starting to get into the mindset of programming this thing! The playfield is limited to a 16x16 grid for obvious reasons (4-bits for X and 4-bits for Y allow any position to be represented by 1 byte). The maximum size of the snake is around 75 segments long which makes things reasonably challenging I hope. I've not added a proper "Game Over" or "You Win" sequence yet, but it will re-start if you die and stop moving if you win (by scoring 70 points). Just push the joystick to start the game! ROM file attached and also available on my github page with the source: https://github.com/RobinSergeant/2600-Snakes Comments and suggestions welcome. It's been a fun learning exercise for me and I've really enjoyed doing some retro coding. snakes.bin
  15. I also used a mask for the Snakes game I'm currently writing. Please see source code on github: https://github.com/RobinSergeant/2600-Snakes I have an 8 line kernel, but it uses so many cycles manipulating the playfield to draw the snake that I didn't have time for conditions. Hence, the snake's head is drawn with a mask (the mask is 0 when the head should not be visible.). Most of the RAM is needed to store the snake data as well and so I ended up storing temporary variables like the mask on top of my stack ? This actually works quite well as I cannot call any subroutines in the kernel section anyway! Something else you can do is try to make use of every spare cycle towards the end of the scanline to set things up for the next line. Pre-load all your registers etc. I did most of my logic here because my game doesn't use much of the screen. So using less of the horizontal real estate is another good option. It gives you more times to set things up at the start and free time at the end of each line. Not using WSYNC also helps save 3 cycles when things get really tight.
×
×
  • Create New...