;############## Calcuzap by Patrick Davidson - sprite movement routines ; Each routine will first redraw the object at its new position and then ; erase the vacated area. The direction-specific routines should not be ; called if the distance to move is 0 or greater than the height/width ; of the sprite. ;############## Move down (A = distance, HL->X) move_down: ld b,(hl) ; B = X coordinate inc hl push hl push af add a,(hl) ; A = new Y coordinate ld (hl),a inc hl #ifdef TI84CE ld de,(hl) #else ld e,(hl) inc hl ld d,(hl) ; DE = image pointer #endif ld l,a push bc push de call Draw_Sprite pop hl ; HL -> image pointer pop bc ; B = X coordinate inc hl ; HL -> width ld d,(hl) ; D = width pop af ; A = height of erased region ld e,a ; E = height of erased region pop hl ; HL = Y coordinate ld a,(hl) sub e ; A = top of erased region (old Y) ld c,a jp Erase_Rectangle ;############## Move up and left (B=-distance.X, C = -distance.Y) ; ; NNNNNNNNNNNNNNNNNNNNNNNNNNN ; NNNNNNNNNNNNNNNNNNNNNNNNNNN ; NNNNNNNNNNNNNNNNNNNNNNNNNNN ; NNNNNNNNNNNNNNNNNNNNNNNNNNN22222 ; NNNNNNNNNNNNNNNNNNNNNNNNNNN22222 ; NNNNNNNNNNNNNNNNNNNNNNNNNNN22222 ; NNNNNNNNNNNNNNNNNNNNNNNNNNN22222 ; NNNNNNNNNNNNNNNNNNNNNNNNNNN22222 ; 111111111111111111111111111 | ; 111111111111111111111111111 C ; 111111111111111111111111111 | ; <-b-><------------ WIDTH ------> ; ; erase rectangle 1 has upper left corner (original X, original Y + height - distance) ; erase rectangle 1 has size (sprite width, distance.Y) ; erase rectangle 2 has upper left corner (original X + width + distance.X, original Y) ; erase rectangle 2 has size (-distance.X, height - distance.Y) move_up_left: call move_up_diagonal push af ; push original Y coordinate add a,(hl) ; add height to Y (erase from bottom) sub e push bc ; push original X coordinate push de ; push distance push hl ; push image pointer inc hl ld d,(hl) ; D = width of sprite = width of 1 call Erase_Rectangle_A pop de ; DE = image pointer pop hl ; H = X distance, L = Y distance pop bc ; B = original X ld a,(de) sub l ; A = rectangle 2 height ld c,a ; C = rectangle 2 height inc de ld a,(de) ; A = width of sprite ld e,c ; *E = rectangle 2 height add a,b add a,h ; A = rectangle 2 X ld b,a ; *B = rectangle 2 X ld a,h ; A = -width neg ; A = rectangle 2 width ld d,a ; *D = rectangle 2 width pop af ; A = original Y coordinate jp Erase_Rectangle_A ;############## Move up and right (B = distance.X, C = -distance.Y) ; ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN ; 22222NNNNNNNNNNNNNNNNNNNNNNNNNNNNN ; 22222NNNNNNNNNNNNNNNNNNNNNNNNNNNNN ; 22222NNNNNNNNNNNNNNNNNNNNNNNNNNNNN | ; 22222NNNNNNNNNNNNNNNNNNNNNNNNNNNNN C ; 22222NNNNNNNNNNNNNNNNNNNNNNNNNNNNN | ; 11111111111111111111111111111 ; 11111111111111111111111111111 ; 11111111111111111111111111111 ; <-------------- WIDTH ------><-b-> ; ; erase rectangle 1 has upper left corner (original X, original Y + height - distance) ; erase rectangle 1 has size (sprite width, distance.Y) ; erase rectangle 2 has upper left corner (original X, original Y) ; erase rectangle 2 has size (distance.X, height - distance.Y) move_up_right: call move_up_diagonal push af ; push original Y coordinate add a,(hl) ; A = bottom (Y coordinate of 1) sub e push bc ; push original X coordinate push de ; push distance push hl ; push image pointer inc hl ld d,(hl) ; D = width of sprite = width of 1 call Erase_Rectangle_A pop de ; DE = image pointer pop hl ; H = X distance, L = Y distance pop bc ; *B = original X = rectangle 2 X ld a,(de) sub l ; A = rectangle 2 height ld c,a ; C = rectangle 2 height inc de ld a,(de) ; A = width of sprite ld e,c ; *E = rectangle 2 height ld d,h ; *D = rectangle 2 width pop af ; A = original Y coordinate jp Erase_Rectangle_A ;############## Move down and left (B = -distance.X, C = distance.Y) ; ; <-b-><-------------- WIDTH ------> ; 11111111111111111111111111111 ; 11111111111111111111111111111 ; 11111111111111111111111111111 ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN22222 ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN22222 ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN22222 ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN22222 ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN22222 ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN | ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN C ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN | ; ; erase rectangle 1 has upper left corner (original X, original Y) ; erase rectangle 1 has size (sprite width, distance.Y) ; erase rectangle 2 has upper left corner (original X + width + distance.X, original Y + distance.Y) ; erase rectangle 2 has size (-distance.X, height - distance.Y) move_down_left: call move_down_diagonal push af ; push original Y coordinate push bc ; push original X coordinate push de ; push distance push hl ; push image pointer inc hl ld d,(hl) ; D = width of sprite = width of 1 call Erase_Rectangle_A pop de ; DE = image pointer pop hl ; H = X distance, L = Y distance pop bc ; B = original X ld a,(de) sub l ; A = rectangle 2 height ld c,a ; C = rectangle 2 height inc de ld a,(de) ; A = width of sprite ld e,c ; *E = rectangle 2 height add a,b add a,h ; A = rectangle 2 X ld b,a ; *B = rectangle 2 X ld a,h ; A = -width neg ; A = rectangle 2 width ld d,a ; *D = rectangle 2 width pop af ; A = original Y coordinate add a,l ; *A = rectangle 2 Y jp Erase_Rectangle_A move_down_diagonal: push bc ; push input distance ld a,(hl) push af ; push original X add a,b ; A = new X coordinate ld (hl),a ; save new X coordinate ld b,a inc hl ld a,(hl) push af ; push original Y add a,c ; A = new Y coordinate ld (hl),a inc hl #ifdef TI84CE ld de,(hl) #else ld e,(hl) inc hl ld d,(hl) ; DE = image pointer #endif ld l,a push de ; push image pointer call Draw_Sprite pop hl ; HL = image pointer pop af ; A = original Y coordinate = Y of 1 pop bc ; B = original X coordinate = X of 1 pop de ; D = X distance, E = Y distance = height of 1 ret move_up_diagonal: ld a,c neg ld c,a push bc ; push input distance neg ld c,a ld a,(hl) push af ; push original X add a,b ; A = new X coordinate ld (hl),a ; save new X coordinate ld b,a inc hl ld a,(hl) push af ; push original Y add a,c ; A = new Y coordinate ld (hl),a inc hl #ifdef TI84CE ld de,(hl) #else ld e,(hl) inc hl ld d,(hl) ; DE = image pointer #endif ld l,a push de ; push image pointer call Draw_Sprite pop hl ; HL = image pointer pop af ; A = original Y coordinate = Y of 1 pop bc ; B = original X coordinate = X of 1 pop de ; D = X distance, E = Y distance = height of 1 ret ;############## Move down and right (B = distance.X, C = distance.Y) ; ; <-------------- WIDTH ------><-b-> ; 11111111111111111111111111111 ; 11111111111111111111111111111 ; 11111111111111111111111111111 ; 22222NNNNNNNNNNNNNNNNNNNNNNNNNNNNN ; 22222NNNNNNNNNNNNNNNNNNNNNNNNNNNNN ; 22222NNNNNNNNNNNNNNNNNNNNNNNNNNNNN ; 22222NNNNNNNNNNNNNNNNNNNNNNNNNNNNN ; 22222NNNNNNNNNNNNNNNNNNNNNNNNNNNNN ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN | ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN C ; NNNNNNNNNNNNNNNNNNNNNNNNNNNNN | ; ; erase rectangle 1 has upper left corner (original X, original Y) ; erase rectangle 1 has size (sprite width, distance.Y) ; erase rectangle 2 has upper left corner (original X, original Y + distance.Y) ; erase rectangle 2 has size (distance.X, height - distance.Y) move_down_right: call move_down_diagonal push af ; push original Y coordinate push bc ; push original X coordinate push de ; push distance push hl ; push image pointer inc hl ld d,(hl) ; D = width of sprite = width of 1 call Erase_Rectangle_A pop de ; DE = image pointer pop hl ; H = X distance, L = Y distance pop bc ; *B = original X = rectangle 2 X ld a,(de) sub l ; A = rectangle 2 height ld c,a ; C = rectangle 2 height inc de ld a,(de) ; A = width of sprite ld e,c ; *E = rectangle 2 height ld d,h ; *D = rectangle 2 width pop af ; A = original Y coordinate add a,l ; *A = rectangle 2 Y jp Erase_Rectangle_A ;############## Move up (A = -distance, HL->X, 0 distance OK here) move_up: ld b,(hl) ; B = X coordinate inc hl push af push hl add a,(hl) ; A = new Y coordinate ld (hl),a inc hl #ifdef TI84CE ld de,(hl) #else ld e,(hl) inc hl ld d,(hl) ; DE = image pointer #endif ld l,a push bc push de call Draw_Sprite pop hl ; HL -> image pointer pop bc ; B = X coordinate (final value for erase) ld c,(hl) ; C = height inc hl ld d,(hl) ; D = width (final value for erase) pop hl ; HL -> Y coordinate ld a,(hl) ; A = new Y coordinate add a,c ; A = bottom Y coordinate ld c,a ; C = Y coordinate (final value for erase) pop af ; A = -height of movement neg ret z ld e,a ; E = height (final value for erase) jp Erase_Rectangle ;############## Move right (A = distance, HL->X) move_right: push hl push af ; push distance add a,(hl) ld b,a ; B = new X coordinate ld (hl),a ld b,(hl) inc hl ld a,(hl) ; A = coordinate inc hl #ifdef TI84CE ld de,(hl) #else ld e,(hl) inc hl ld d,(hl) ; DE = image pointer #endif ld l,a push de call Draw_Sprite pop hl ; HL -> image pop de ; D = distance/width (final value for erase) ld e,(hl) ; E = height (final value for erase) pop hl ; HL -> X ld a,(hl) ; A = new X sub d ld b,a ; B = old X (final value for erase) inc hl ld c,(hl) jp Erase_Rectangle ;############## Move left (A = -distance, HL->X) move_left: push hl push af ; push distance add a,(hl) ld b,a ; B = new X coordinate ld (hl),a ld b,(hl) inc hl ld a,(hl) ; A = coordinate inc hl #ifdef TI84CE ld de,(hl) #else ld e,(hl) inc hl ld d,(hl) ; DE = image pointer #endif ld l,a push de call Draw_Sprite pop hl ; HL -> image pop af ; A = -distance/width neg ; A = distance/width ld d,a ; D = width (final value for erase) ld e,(hl) ; E = height (final value for erase) inc hl ld c,(hl) ; C = sprite width pop hl ; HL -> X ld a,(hl) ; A = new X add a,c ; A = past the edge X ld b,a ; B = X (final value for erase) inc hl ld c,(hl) jp Erase_Rectangle Draw_Sprite: jp Draw_Sprite_Packed