Redefine or simulate new X/Y origin

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

Redefine or simulate new X/Y origin

Post by Kitsune Mifune » Sat Nov 02, 2019 11:45 am

I'm trying to write a piece of code which will simulate a new X/Y origin point at the bottom left of the sprite's frame instead of the top left. I remembered from my Amos days that the "hotspot" (origin) could be redefined to be bottom left, or bottom centre, or top right etc, and I assume it's just a piece of code which uses the real origin (top left) as a starting point and then does some magic to trick it into re-positioning according to where the simulated one is set.

My animation routine would work much better if the origin was at the bottom left of the sprite instead of the top left as it would keep the "feet" nicely lined up when different sized frames are used. Keeping every frame the same size would work, but it would also be a dreadful waste of memory and processing power as there would be huge big empty bits of blank space in the frame which the CPU would have to spend time masking out.

I've had a sniff around the internet and I couldn't find anything on the topic.

I realise that under the hood, the sprites will always be drawn from the top left, and that's fine, I'm not trying to change that - just get a new point from which to set them which will always keep the bottom of the frame the same level. I'm currently trying to write some code that will make a new reference point from which to calculate the X/Y by finding out and storing the bottom left coordinate and using that as a reference, but I'm failing rather spectacularly at it (also, no idea how this will affect up/down movement).

I think my logic is sound, because I keep looking at the code and seeing nothing wrong with it, and if that's the case it must be a placement problem within the draw routine (which is just a modified version of the "Simple sprites on the CPC" lesson).

If I've missed an easier way (or even a sneaky firmware way) to do this then then please feel free to inform me, because I'd like to post a progress video in the Show and Tell, but I'd rather get this issue sorted first.

Thanks!

Code: Select all

ORIGIN_BOTTOMLEFT:

push hl						; Preserve 'hl' as it's used elsewhere
	ld hl,(PLAYER_YPOS)			; Take current Y-Position (Top left of frame)
	ld bc,(SPRITE_HEIGHT)			; Take the current height of the frame
	or a
	sbc hl,bc				; Subtract the frame height from the Y-Position and this...
						; ...will give us a coordinate at the bottom left of the frame

	ld (PLAYER_YPOS_BTMLFT),hl 		; Transfer the new co-ordinate value to a label-variable
	
	ld hl,(PLAYER_YPOS_BTMLFT_PREV)		; Take PREVIOUS frames's bottom left Y-Position
	ld bc,(SPRITE_HEIGHT)			; Take the height of the CURRENT frame

	add hl,bc				; Add the CURRENT sprite's height to the bottom left... 
							; ...coordinate of the PREVIOUS frame
							
	ld (PLAYER_YPOS),hl			; Transfer new draw coordinate to PLAYER_YPOS

	ld hl,(PLAYER_YPOS_BTMLFT)		; Store the bottom left coordinate to use in next frame
	ld (PLAYER_YPOS_BTMLFT_PREV),hl

pop hl
RET
Programming: 90% failures, 10% victories, and 100% hair loss!

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

Re: Redefine or simulate new X/Y origin

Post by akuyou » Sun Nov 03, 2019 6:51 am

Your theory sounds correct to me - I don't think there's a better way to do it, or a firmware call to help you.

I'd be tempted to do this either during sprite drawing subtracting the lines before the screenpos is calculated, rather than storing a pair of values for each sprite (one bottomleft and one regular)

You say the code isn't working... what is it doing?
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: 33
Joined: Tue Oct 22, 2019 6:46 am
Location: Glasgow
Contact:

Re: Redefine or simulate new X/Y origin

Post by Kitsune Mifune » Sun Nov 03, 2019 9:39 am

I was just about to try what you said and....now I don't know how I came by this, but I was reading the Amos manual on hotspots and it just said that the calculation was made by adding simple values onto the top left X/Y coordinates, so I wrote this piece of much, much simpler code - and it works!

In fact it works beautifully, plus it's faster!

I just made a call to the code before the position was plotted and replaced the variables PLAYER_YPOS and PLAYER_XPOS with PLAYER_YHOT and PLAYER_XHOT in the plotting code.

Complete and total fluke, but it's exactly what I've been looking for, plus I can also place the new origin at the bottom centre or even the middle of the sprite if I wanted. The animation is way more efficient now that it's not shifting around all those extra pixels too, even if they are meant to be the 'transparent' ones.

I feel a bit silly now going through all that mess with the last bit of code (I was at it for 4 days), but I hope this will come in handy for other people too.

Code: Select all

XYORIGIN_BCENTRE:

	ld a,(SPRITE_HEIGHT)	; Get curent sprite's height and load to 'a'
	ld b,a			; Transfer value to 'b'
	ld a,(PLAYER_YPOS)	; Get player's current Y-Position and load to 'a'
	add b			; add the sprite's height to the Y-Position (add 'b' to 'a')
	ld (PLAYER_YHOT),a	; Store the newly calculated value from 'a' in a new variable

	ld a,(SPRITE_WIDTH/2)	; Get curent sprite's width and divide by 2, then load to 'a'
	ld b,a			; transfer value to 'b'
	ld a,(PLAYER_XPOS)	; Get player's current X-Position and load to 'a'
	add b			; add half of the sprite's width to the X-Position (add 'b' to 'a')
	ld (PLAYER_XHOT),a	; Store the newly calculated value from 'a' in a new variable
RET
Programming: 90% failures, 10% victories, and 100% hair loss!

Post Reply

Return to “Amstrad CPC Assembly Programming”