Jump to content
IGNORED

how do you manage sprites in split up kernals?


Steril707

Recommended Posts

Lets say i have my screen built up with split up kernals, like, a sky, a mid area with some mountains and then the ground, and i want my sprite(s) to be able to get displayed within all of these, and being able to wander from one to the other without hassle.

 

It seems a couple of games are doing this, Pitfall for instance, where the kernal is splitted up into several stripes. Yet Pitfall Harry can fall from the "ground strip" into the cellar without problems it seems, and go up again.

 

I tried to check out the disassembly provided by Thomas, but to be honest, i couldn't make heads or tails out of it on this topic, so i would be extremely happy about any pointers into the right direction.

Link to comment
Share on other sites

Pitfall! uses 9 different kernels for each area on the screen. So when moving down a ladder, Harry starts getting drawn in e.g. kernel #7 and continues to be drawn in kernel #8.

 

There are several options how to achieve this:

1. use a global counter which is used in all kernels (at least those where Harry appears). Then you can use the same checks and pointers to the graphics in all kernels. This is done in Pitfall!

2. use local counters and pointers for each kernel, which may be easier to understand and implement, but use a lot of RAM

Link to comment
Share on other sites

Pitfall! uses 9 different kernels for each area on the screen. So when moving down a ladder, Harry starts getting drawn in e.g. kernel #7 and continues to be drawn in kernel #8.

 

There are several options how to achieve this:

1. use a global counter which is used in all kernels (at least those where Harry appears). Then you can use the same checks and pointers to the graphics in all kernels. This is done in Pitfall!

2. use local counters and pointers for each kernel, which may be easier to understand and implement, but use a lot of RAM

 

 

Danke!!! :) Glaub ich habs kapiert.

Link to comment
Share on other sites

Out of curiosity, does 'split-up kernels' mean that different kernels are drawn for different frames? For example, Frame 1: Draw top of screen, Frame 2: Draw middle of screen, Frame 3: Draw bottom of screen, Frame 4: Draw top of screen again, etc.? If so, how many splits can you have before you start getting screen flicker?

That would cause immediate flicker. :)

 

No, all kernels are drawn sequentially during one frame.

Link to comment
Share on other sites

Hey Thomas, me again with one more question: I have managed to get the Sprites into the right position, having one Skipdraw being executed in "Kernal 1" and another one in Kernal2 each with their own P_Y s. That works quite fine, as soon as the Sprite from Kernal2 jumps up into Kernal1, it disappears from Kernal2 and appears in Kernal1 so it looks like its the same Sprite, BUT:

At the line that splits both kernals apart, the Sprite starts looking like a big square, instead of a small guy.

 

What do i have to do with the Sprite pointer? I have to admit i dont quite understand the spritepointer part of Skipdraw yet, so any advice would be helpful.

 

Sorry, that I cannot post the appropriate code at the moment (i am not at my place).

 

thanks, Michael

Link to comment
Share on other sites

At the line that splits both kernals apart, the Sprite starts looking like a big square, instead of a small guy.

Maybe you miss updating the sprite between the kernels?

 

Sorry, that I cannot post the appropriate code at the moment (i am not at my place).

Without code, I am bound to speculations (see above).

Link to comment
Share on other sites

One way is to use Flipdraw. No line counter required, easy pointer setup, and simple rules on where to place graphics data (the actual sprite data itself can't wrap a page unless you synchronize the kernel with STA WSYNC.)

 

Flipdraw is totally self-contained and can be placed in multiple places across several mini-kernels as long as your branches don't cross page boundaries.

 

Search for Flipdraw here to find code examples.

Edited by batari
Link to comment
Share on other sites

The ability to move sprites smoothly between kernel sections is a major mark of refinement. Of course, some games by nature do not particularly require this (e.g. Strat-O-Gems), and many--perhaps most--games require it for one player sprite but not the other. Sometimes a game's graphics can be arranged so as to 'justify' a gap between zones. In PitFall!, for example, between the 'log zone' and the 'scorpion zone' are a few scan lines which appear 'in front of' the player.

 

Ideally when using multiple kernels, each kernel will finish with enough time to enter the next one without losing a scan line. That isn't always possible, though, especially with zones requiring horizontal motion. In such cases, it may be necessary to have a special 'kernel' which is responsible for just one scan line, or to 'integrate' kernel-ish code within the setup routine for the next few scan lines. In a few cases, it may even be necessary to compute, outside the kernel, what GRPx etc. values will be required on certain scan lines and store them, so that when those scan lines roll around you can simply "LDA watertop_GRP0 / sta GRP0" without having to do any sort of skipdraw/switchdraw/flipdraw/etc.

 

In Toyshop Trouble, the main screen is drawn using about five iterations of a 32-line loop (the loop begins and ends in the middle, so it's not exactly 5). Each loop is split into 16-line 'zones'. The first zone is responsible for setting toy Y positions and drawing the paint pots and conveyors; the second zone is responsible for drawing the toys. In both zones, Y counts from 15 to 0.

 

Every scan line in the first zone starts with something like:

  sta WSYNC
 lda (shape0a),y
 sta GRP0
 lda (color0),y
 sta COLUP0
 dey

If part of the player is in that zone, shape0 will point to 16 bytes of RAM which hold the shape data for that zone; otherwise it will point to 16 bytes of zeroes in ROM. Color0 will point into the first of two copies of a 16-byte color table in ROM. Although player 0 will only be visible on 17 scan lines, the color will repeat every 16 lines (the elf's hat and shoes are the same color, so that works nicely).

 

The first zone does many different tasks, each of which takes well under a scan line to complete. Among those tasks are setting up the shape0b pointer (which will be used in the other zone). The last things the top zone does before starting in with the other zone are loading the shape0a pointer as appropriate for the next upper zone (17 lines later) and resetting Y to 15. It then does a WSYNC and falls into the lower zone.

 

The lower zone runs a 15-scan-line loop to draw the toy shapes. Each line starts with code like the above, but without the WSYNC (the loop is counted out to 76 cycles/line) and using (shape0b) instead of (shape0a). After the loop exits, the code does one last update of GRP0/COLUP0 using (shape0b),y and (color0),y and restarts the earlier loop.

 

This approach to handling player motion can be somewhat RAM-hungry (if two 16-byte shape tables are used in RAM) or code-hungry (if each shape in ROM has 15 bytes of zeros before and after it) but it makes it possible to have single-line color and shape resolution for the player character even in a kernel that is otherwise jammed to the gills with code.

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