Sprite transparent pixels issue

Post programming questions related to the CPC Here!
Post Reply
Kitsune Mifune
Posts: 28
Joined: Tue Oct 22, 2019 6:46 am
Location: Glasgow
Contact:

Sprite transparent pixels issue

Post by Kitsune Mifune » Mon Nov 18, 2019 1:10 pm

Been getting on rather well (albeit slowly) with my game, but I've run into a small issue with the sprites.

I thieved a piece of code from the CPC forums to use in the draw routine. It checks for transparent pixels in the sprite frame and doesn't draw them. It works really well, and I actually know what's going on in the code (in theory), but there are still some blue pixels around the edge of the sprite that it seems to have missed and they are still showing. The picture below shows what's happening:

Image

It seems to be skipping over a horizontal pixel byte, because it looks like it's every second byte that is being checked when it reaches the actual player pixels. I'm sure that one Mode 0 pixel is one byte, but it looks like it's taking it as two per byte.

This is the code I'm using. As always, many thanks in advance!

Code: Select all

DRAW2SCREEN:		
		ld a,(SPRITE_HEIGHT)			; Load sprite height value to 'a'
		ld b,a					; Height (LINES)
Spritenextline:
	push hl
		ld a,(SPRITE_WIDTH)			; Width (BYTES)
		ld c,a					; Bytes per line
	SpriteNextByte:
		ld a,(de)        			; Read sprite pixels	
		inc de            			; Update sprite pixel pointer	
		or a            			; Zero (i.e. fully transparent?)
		jr z,NO_MASK    			; If yes, then skip
		ld (hl),a        			; If no, then write byte to screen
	NO_MASK:
		inc hl           			; Increase destination (Screen) Address
		dec c 					; Repeat for next byte
		jr nz,SpriteNextByte
	pop hl

		call GetNextLine			; Scr Next Line (Alter HL to move down a line)
		djnz SpriteNextLine			; Repeat for next line
		
RET
Programming: 90% failures, 10% victories, and 100% hair loss!

User avatar
akuyou
Posts: 328
Joined: Mon Apr 22, 2019 3:19 am

Re: Sprite transparent pixels issue

Post by akuyou » Wed Nov 20, 2019 11:19 pm

Yes, this is to be expected - a mode 0 pixel is one NIBBLE (4 bits... 0-15) - so there are TWO Mode 0 pixels per byte - if both aren't zero then you'll get the blue outline you're seeing.

This is the same transparency method ChibiAkumas used by the way! the black borders around the characters worked well in that case, as it made them look 'cartooney'

I think you have two options

1. Redraw the sprites so the effect is less noticable (maybe make color 0 black?)

2. Change the code and use a different transparency routine... a 'Look up table' is a commonly used method - you can create a 256 byte table of 'Masks' to remove the background (via AND command) - looking up the byte value from your sprite to work out the correct mask to remove the non zero bytes, then OR in your sprite over the top... It's not something I've used, but games like Operation Wolf can be seen doing it in disassembly.
Chibi Akuma(s) Comedy-Horror 8-bit Bullet Hell shooter! // 「チビ悪魔」可笑しいゴシックSTG ! // Work in Progress: ChibiAliens

Interested in CPU's :Z80,6502,68000,6809,ARM,8086,RISC-V
Learning: 65816,ARM,8086,6809

Kitsune Mifune
Posts: 28
Joined: Tue Oct 22, 2019 6:46 am
Location: Glasgow
Contact:

Re: Sprite transparent pixels issue

Post by Kitsune Mifune » Thu Nov 21, 2019 9:15 am

Thank Keith.

I tried setting the background colour to black, and it was definitely an improvement, but it's a bit too blocky for my eyes. I'll look in to another way of removing the transparency. I've not used LUTs much, so maybe this will be a good exercise.
Programming: 90% failures, 10% victories, and 100% hair loss!

User avatar
akuyou
Posts: 328
Joined: Mon Apr 22, 2019 3:19 am

Re: Sprite transparent pixels issue

Post by akuyou » Fri Nov 22, 2019 10:29 pm

You've probably figured it out by now, but I though I'd cover this in my tutorials at some point so...

I've added a new file to the Z80 sources.7z on my webiste 'CPC_Bitmap_Transparent.asm'

This will show a sprite 3 times, once with no transparency, once with 'zero byte' as above... and the final with the lookuptable
screencap.jpg
screencap.jpg (9.22 KiB) Viewed 90 times
Here's the code I used to build the LUT:

Code: Select all

ld hl,TranspLUT
	ld (hl),%11111111	;Both pixels kept
BuildLutAgain:
	inc l
	jr z,LUTdone		;Done all 256
	ld a,l
	and %01010101		;Right Pixel Mask
	jr nz,BuildLut2
	ld (hl),%01010101
	jr BuildLutAgain
BuildLut2
	ld a,l
	and %10101010		;Left Pixel Mask
	jr nz,BuildLutAgain
	ld (hl),%10101010
	jr BuildLutAgain
LUTdone:
And to show the sprite:

Code: Select all

DrawSpriteT:
	ld de,TestSprite	;Sprite Source
	ld ixh,64			;Lines (Height)
	ld bc,TranspLUT
SpriteNextLineT:
	push hl
		ld ixl,8	;Bytes per line (Width)

SpriteNextByteT:
		ld a,(de)	;Get Sprite Byte
		ld c,a		;Change Low Byte of LUT
		ld a,(bc)	;Get Mask for Sprite Byte
		and (hl)	;Mask current pixel out of back

		or c		;Or in new pixel
		ld (hl),a	;Save to screen
	
		inc de		;INC Source (Sprite) Address
		inc hl		;INC Dest (Screen) Address

		dec ixl 	;Repeat for next byte
		jr nz,SpriteNextByteT
	pop hl
	call &BC26		;Scr Next Line (Alter HL to move down a line)
	dec ixh
	jr nz,SpriteNextLineT	;Repeat for next line
	ret
Chibi Akuma(s) Comedy-Horror 8-bit Bullet Hell shooter! // 「チビ悪魔」可笑しいゴシックSTG ! // Work in Progress: ChibiAliens

Interested in CPU's :Z80,6502,68000,6809,ARM,8086,RISC-V
Learning: 65816,ARM,8086,6809

Kitsune Mifune
Posts: 28
Joined: Tue Oct 22, 2019 6:46 am
Location: Glasgow
Contact:

Re: Sprite transparent pixels issue

Post by Kitsune Mifune » Sun Nov 24, 2019 9:40 am

This is great! It works beautifully. Thank you.

I had made some ham-fisted attempt at another transparency method, but I wasn't really getting anywhere.

Would this work with a flipped image? I only ask because I'm literally just about to try and attempt a sprite flipping routine, so may as well try and work it into that too, and I assume some tweaking will be needed for the reversed bits.

Excellent stuff though. I understand LUTs a little better now just seeing how this works. :)
Programming: 90% failures, 10% victories, and 100% hair loss!

User avatar
akuyou
Posts: 328
Joined: Mon Apr 22, 2019 3:19 am

Re: Sprite transparent pixels issue

Post by akuyou » Sun Nov 24, 2019 11:12 am

There's no reason this wouldn't work combined with the 'flip image' lookup table..

This code will work with any sprite that's got color 0 as transparent.... you'd just need to 'chain' this lookup code with the 'flipping' lookup code you have
*** Update! - Example attached! ***
CPC_Bitmap_FlipTransp.7z
(1.19 KiB) Downloaded 5 times
You may be a bit short of registers at that point!... By the way, are you familiar with the 'stack misuse' trick, using the stack pointer for fast data reading, rather than just temporary storage... I only mention it because your game looks to be using pretty big sprites, and all fast CPC games will probably use it (OPWolf and my ChibiAkumas both did)

I covered it to some extent in my Z80 tutorials... it's tricky, so it's not something you need to worry about now, but you'll probably want to use it in your final game...
https://www.chibiakumas.com/z80/index.php#Lesson8

You'll also want to lookup unwrapped loops, if you've not come across them yet when you're looking for 'super speedy sprites'.
Chibi Akuma(s) Comedy-Horror 8-bit Bullet Hell shooter! // 「チビ悪魔」可笑しいゴシックSTG ! // Work in Progress: ChibiAliens

Interested in CPU's :Z80,6502,68000,6809,ARM,8086,RISC-V
Learning: 65816,ARM,8086,6809

Kitsune Mifune
Posts: 28
Joined: Tue Oct 22, 2019 6:46 am
Location: Glasgow
Contact:

Re: Sprite transparent pixels issue

Post by Kitsune Mifune » Sun Nov 24, 2019 12:44 pm

Excellent! I'll have a look at that Stack trick.

I've pretty much resigned myself to the fact that the game is going to be slow, but as long as it's comparable to the original Amstrad Final Fight conversion in terms of speed then I'll be happy, and any little tricks to boost speed will be great. The original was actually fairly decent in terms of speed, it was just the jumping which was slow. I know it was a rush job, and it's actually running Richard Aplin's Double Dragon II code underneath, and I think that saved on some CPU load by slicing the sprites horizontally so that there's less transparent pixels to check (or something).

Anyway, I'll report back once I've figured out how to actually flip the sprites. I've got a 30 byte piece of code off of a French website that I'm trying out, so fingers crossed it works and I can incorporate the masking code.

Thanks again for the help!

If I can remember my YouTube password I'll try to jump on one of the Saturday live streams at some point when I'm not in the studio recording rubbish bands.
Programming: 90% failures, 10% victories, and 100% hair loss!

Post Reply

Return to “Amstrad CPC Assembly Programming”