Jump to content

The Southsider

  • entries
    81
  • comments
    767
  • views
    138,547

Juno Update


cd-w

1,419 views

It has been some time since I last posted an update on my Juno First game. The project has been on hold for a while, but it has not been abandoned completely. One of the reasons that it stalled is because I wasn't completely happy with the kernel. My aim for the game was to have full colour sprites that are updated on every line (1LK). This should make the game visually superior to similar games (such as Beamrider), but it is quite a challenge to achieve!

 

I managed to get the kernel working, except in one case, which would cause the gridline to jump in an annoying way. The source of the problem is that the alien sprites need to be repositioned at various places on the screen, and this repositioning takes a screen line to accomplish. This repositioning can clash with the drawing of the gridline, as there isn't enough time to do both. In most of the screen this wasn't a problem, as I just delayed the repositioning by 1 line when this happened (with a gap of two screen lines between aliens). However, at the bottom of the screen the ship also needs to be drawn every screen line and this trick doesn't work. My solution was to draw the gridline immediately after repositioning in this case, but this causes the gridline to be drawn one line further down, and leads to the annoying jumping effect.

 

For a long time, I tried to re-arrange things to avoid the jumping problem. I managed to get within a few cycles of a solution by resorting to some loop unrolling, but I just couldn't make it fit! However, I recently read this post in batari's blog and was inspired to have another go. The suggestion in this post is that it isn't always necessary to waste a complete line on repositioning the sprites, since most of the repositioning code is just waiting for the correct position. Instead, it is possible to implement a series of mini-kernels that each reposition the sprite in a different horizontal position, and also have some spare time to do extra work! However, this technique is difficult to implement and requires a lot of ROM space.

 

In Juno First, the aliens don't go completely to the edges of the screen, so there are ten different horizontal sprite positions. Therefore, 10 mini-kernels are required to implement the technique. I used the following code to jump to the correct mini-kernel:

 

; Set pointer at beginning of kernel
	lda #>ReposFunctions
	sta JPTR+1

; Jump to correct minikernel
	ldx XPOSITION
	lda ReposTable,X   
	sta JPTR
	jmp (JPTR)

 

The jumping code costs only 15 cycles, but it requires a fairly large table of pointer values. In Juno First, there are 15 pointers required for each of the 10 mini-kernels:

 

ReposTable
	DS.B	15, #<Repos0
	DS.B	15, #<Repos1
	DS.B	15, #<Repos2
	DS.B	15, #<Repos3
	DS.B	15, #<Repos4
	DS.B	15, #<Repos5
	DS.B	15, #<Repos6
	DS.B	15, #<Repos7
	DS.B	15, #<Repos8
	DS.B	15, #<Repos9
EndReposTable

 

Within each kernel it is necessary to hit the RESPx register at exactly the right time and also to set the HMPx value. I accomplished this with the following code fragments. Obviously, the cycle on which RESPx is hit, and the sbc# value must be changed in each mini-kernel.

 

ReposX
; Reposition Sprite (Coarse)
	sta.w RESP1   ; Must happen on exactly the right cycle (20/25/30/35/40/45/50/55/60/65)
	...
; Fine Tuning (X contains sprite position)
	txa 
	sec	  
	sbc #30   ; Change value for each mini-kernel: 15/30/45/60/75/90/105/120/135/150
	sta HMP1   ; Can happen anywhere before HMOVE
	...
; Move Sprite
	sta WSYNC
	sta HMOVE 
EndReposX

 

Anyway, to cut a long story short, I managed to get this technique working in Juno First after a lot of tweaking. The results are attached to this message. The kernel now takes a whole 4K bank and is the most convoluted bit of code that I ever hope to write! However, it has got rid of the annoying jumping gridline, so I am pleased with the results. I have also made a number of other tweaks to the Juno code since my last posting:

  • Homing bullets are now implemented (although slightly buggy)!
  • All the different alien types have their own movement and firing patterns.
  • You have three warps (shown by the W's at the bottom of the screen). Pressing Select will make your ship disappear for a short time (handy for avoiding bullets).
  • There is a nice reverse-explosion when the ship appears on the screen.
  • You have to hit fire to start the game, and to resume after you die.

The game now has all of the important features that I planned to include, although there is still a lot of polishing to do. I'm not going to make any rash predictions about when I will get this finished, as at least the following tasks have still to be completed:

  • Implement lots of levels with different alien types.
  • Make something happen when you pick up an astronaut!
  • Add some cool sound effects!
  • Add a title screen and high score table (see previous post).
  • Add more polish if there is space, e.g. music, attract mode, colour schemes, etc.

As always, let me know if you find any bugs or have any suggestions. The game works in both Stella and Z26 (use phosphor mode), but I haven't tested it on real hardware. I will strongly resist any changes to the kernel now, except if there are any bugs :)

 

Chris

9 Comments


Recommended Comments

For Leprechaun I ended up breaking the repositioning routine into three separate chunks. I can't recall offhand why three worked best. It was also inline, no jump table. But, then again, I couldn't dedicate 4K to the kernel (actually 365 bytes).

Link to comment

Very cool! It's great to see you working on this again.

 

Let me know when you're ready to work on the title screen, and what you need for it. :)

Link to comment

For Leprechaun I ended up breaking the repositioning routine into three separate chunks. I can't recall offhand why three worked best. It was also inline, no jump table. But, then again, I couldn't dedicate 4K to the kernel (actually 365 bytes).

 

Thanks - I wasn't aware of anyone else using this technique, except for the RRampage demo that was posted some time ago. I will take a peek at your code and see if there are any ways that I can optimise mine.

 

Chris

Link to comment

For Leprechaun I ended up breaking the repositioning routine into three separate chunks. I can't recall offhand why three worked best.

Two or three chunks are useful, more usually have to much overhead for determining which chunk to select. Unless you have a table approach.

Link to comment

Looks great! Glad I was able to help in some way. My own kernel has not progressed much past the planning stage - too many other distractions.

Link to comment

I don't see any need to have a different kernel for every position. If you only have a small amount of stuff to get done on a scan line in addition to the positioning, simply separate out the cases of early positioning (in which case you can do the other stuff you need to do after), or late positioning (in which case you do the other stuff before). Splitting things more different ways gives you more opportunities to do other work during the scan line, but would often be overkill.

Link to comment
Guest
Add a comment...

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