Jump to content
IGNORED

New game project: Jetpac


Vorticon

Recommended Posts

Here's a tested Forth Assembler version. :thumbsup:

 

 

variable BITMSK   $8000 BITMSK !
 
asm: doRLE ( rleSrcAddress vdpDestAddress -- )
    *sp+ r0 mov,                \ get vdp address
    r0 $4000 ori,               \ set vdp write bit
    r0 swpb,                    \ get low byte
    r0 $8c02 @@ movb,           \ write to vdp address reg
    r0 swpb,                    \ get high byte
    r0 $8c02 @@ movb,           \ write to vdp address reg
   
    r0 6144 li,                 \ counter
    r1 clr,
   
    r9 $8c00 li,                \ vdp write register
   
    *sp+ r8 mov,                \ get pointer to rle data
   
    begin,
        r8 *+ r1 movb,              \ get control byte
        BITMSK @@ r1 coc,           \ packed or unpacked?
        eq if,
            \ packed
            r1 $7f00 andi,          \ get count
            r1 swpb,                \ move to low byte
            r1 r0 s,                \ update counter
            begin,
                r8 ** r9 ** movb,   \ write a byte
                r1 dec,             \ decrement counter
            eq until,               \ loop if not finished
            r8 inc,                 \ point to next control byte
        else,
            \ unpacked sequence - r1 contains count
            r1 swpb,                \ move count to low byte
            r1 r0 s,                \ update counter
            begin,
                r8 *+ r9 ** movb,   \ write a byte
                r1 dec,
            eq until,
        endif,
   
        r0 r0 mov,                  \ check count
    eq until,                       \ loop if not finished
;asm
Link to comment
Share on other sites

Like all the code in Convert9918, it's going to be really, really ugly. ;)

 

 

 

// Inputs:
// pbuf - pointer to bytes to be packed
// nSize - pointer to integer to receive the final packed size (does not need to be initialized)
// InSize - size of the input buffer to be packed
// Returns:
// An oversized malloc'd buffer containing the RLE'd data - caller must free.
// The int at nSize is filled in with the number of valid bytes in the returned memory.
unsigned char *CTIPicViewDlg::RLEEncode(unsigned char *pbuf, int *nSize, int InSize) {
	int nOffset=0;
	int nOutputSize=0;
	unsigned char *pRet = (unsigned char*)malloc(InSize*2);	// worst case
	while (nOffset < InSize) {
		// decide whether to do a run or data
		if ((pbuf[nOffset]==pbuf[nOffset+1]) && (pbuf[nOffset] == pbuf[nOffset+2])) {
			// worth doing an RLE run
			// work out for how far!
			int i=nOffset+3;
			while (pbuf[i] == pbuf[nOffset]) {
				i++;
				if (i>=InSize) break;
				if (i-nOffset >= 127) break;
			}
			pRet[nOutputSize++] = 0x80|(i-nOffset);
			pRet[nOutputSize++] = pbuf[nOffset];
			nOffset=i;
		} else {
			// not worth doing RLE -- see for how long
			int i=nOffset+1;
			while ((pbuf[i]!=pbuf[i+1]) || (pbuf[i] != pbuf[i+2])) {
				i++;
				if (i>=InSize) break;
				if (i-nOffset >= 127) break;
			}
			pRet[nOutputSize++] = i-nOffset;
			for (int c=0; c<i-nOffset; c++) {
				pRet[nOutputSize++] = pbuf[nOffset+c];
			}
			nOffset=i;
		}
	}
	*nSize = nOutputSize;
	if (cmdFileIn[0] == '\0') printf("RLE compress table from %d to %d bytes\n", InSize, nOutputSize);
	return pRet;
}

 

 

The function doesn't know or care what type of data is passed it, it's just taking a pointer to a memory array of bytes. It's straight forward enough - it looks at the next three bytes. If they are the same, it will encode it as a run of that single byte, otherwise it will encode a run of data. Once it makes that decision, both paths look ahead to see how many bytes before the pattern breaks (ie: for a run of the same byte, the first different byte, and for a run of data, the first place where 3 bytes the same are found). Both cases also stop if they reach the end of data or count up to 127, which is the maximum count. Once determined, it fills in the output data.

 

I didn't account for the common case of getting one more byte out of a run by letting 0 mean 1... 0 means 0, so count bytes of >00 and >80 are meaningless in this one. ;)

  • Like 2
Link to comment
Share on other sites

 

The trick is you change the clock based on which side of the screen it's on. :)

 

Exactly. Lets say you have a sprite with horizontal position X that can also be negative (X >= -32). A position of -16 means that the sprite is just out of screen to the left and a position of 256 means that it's just out of screen to the right. To convert this into a sprite attribute you decide on an arbitrary breakpoint, say 128, below which you adjust the attribute and set the early clock (EC):

 

IF X < 128

ATTR_X = X + 32

ATTR_EC = 1

ELSE IF X > 255

ATTR_X = 0

ATTR_EC = 1

ELSE

ATTR_X = X

ATTR_EC = 0

ENDIF

  • Like 2
Link to comment
Share on other sites

IIRC, the early clock is a setting for each sprite, right? Why not just directly manipulate the sprite table?

 

It is, indeed, a setting for each sprite in the Sprite Attribute Table—4 bytes for each of 32 sprites. The MSb (80h) of the 4th byte sets or resets the early clock for that sprite.

 

...lee

Link to comment
Share on other sites

The early clock would make collision detection with background a real pita as you'd have to correct for the early clock before checking background characters.

 

It would be best implemented at the TF kernel level rather than the application level. The kernel could account for early clock and do the horizontal correction such that it's transparent to the application. The application does not want a sudden jump in horizontal coordinates by 32 pixels. It needs a logical horizontal coordinate system implementation on top of the physical system. Perfectly doable with relatively little impact.

Link to comment
Share on other sites

TF doesn't use early clock. I've never used it ever! At what point should it be switched on?

 

I would think it is not a good idea to set the early clock when the sprite is visible because it will jump 32 pixels left at the moment it is set—unless you can change its position fast enough to not notice it, which I doubt is probably possible in TF.

 

...lee

 

[EDIT: I'm too slow!]

Edited by Lee Stewart
Link to comment
Share on other sites

  • 3 weeks later...

Good news! Willsy's sound player works like a charm, so we are back in business :) I have also corrected the monster spawning issue pointed out by Asmusr-M. Just waiting on the last 2 sound effects from OLD CS1 and the game will be officially done. I should be posting the version 1.0 binary pretty soon. Yay!

  • Like 5
Link to comment
Share on other sites

  • 2 weeks later...

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