;
; Jet Set Wibble - Alter the Jet Set Willy engine so that it displays 
; everything upside down.
;
; Assemble this file with an assembler that can output in Intel Hex 
; format, such as z80asm.
;
; Because of the way JSW works, it's quite easy to apply any transformation
; you want to the main game screen before it's displayed. The display is
; constructed in memory and LDIRed to the screen proper once each time 
; 'round the game loop. So to tamper with it, we just need to intercept 
; the drawing code.
;
; There are two complications: The title screen, and the "Game Over" 
; screen, which are drawn directly.
; 
;
footpos	equ	85E4h
foot_top equ	0E0h

	org	840Ch	;Bypass colour card
	jp	87CAh	
;
; The title screen is done by drawing it normally to the screen 
; and then flipping it over.
;
	org	88A8h
	call	fltitle
;
; This is the point in the main game loop where the screen bitmap is drawn.
;
	org	89F5h
	call	flbits
	jr	8A00h
;
; This is the point in the main game loop where the screen attributes
; get drawn.
;
	org	8A26h
	call	flattr
	jr	8A31h
;
; The death sequence works by:
; * Drawing the screen as normal
; * Then flipping it over
; * Then drawing the foot at the bottom and moving it upwards.
;
	org	8C6Eh
	call	dead1	
;
; Upside-down version of the foot sprite
;
	org	8C80h
	ld	de,rspr_foot
;
; The sound made by the foot is based on the foot's Y-coordinate. 
; So this needs to be adjusted when the foot is going the other way.
;
	org	8C88h
	call	footsnd
	nop
;
;Colouring in the barrel. This is now at the top of the screen.
;
	org	8CB3h
	ld	(580Fh),a
	ld	(5810h),a
	ld	(582Fh),a
	ld	(5830h),a
;
; The foot now moves up, not down.
;
	ld	a,(footpos)
	sub	4
	ld	(footpos),a
	cp	1Ch

	org	8CD1h
	ld	de,484Ah	;The "Game over" text 

	org	8CDDh	
	ld	de,4852h	;is now a little lower

	org	8CEFh
	ld	(594Ah),a	;and so 
	org	8CF7h
	ld	(594Bh),a	;are
	org	8CFFh
	ld	(594Ch),a	;its
	org	8D07h
	ld	(594Dh),a	;attributes.
	org	8D0Fh
	ld	(5952h),a
	org	8D17h
	ld	(5953h),a
	org	8D1Fh
	ld	(5954h),a
	org	8D27h
	ld	(5955h),a
;
; Patch space; in the original JSW, this memory is unused.
;
	org	9718h	
dead1:	call	9456h		;Original code to draw the barrel.
	call	flscr		;Flip the screen over
	ld	a,foot_top	;and move the foot to the bottom of the 
	ld	(FOOTPOS),a	;screen.
	ret	
;
; Work out the sound for the foot. When coming down from the top, the 
; value used is ~(FOOTPOS); to make it come out right here,
; we have to return ~(foot_top - FOOTPOS).
;
footsnd:
	ld	a,(FOOTPOS)
	ld	e,a
	ld	a,foot_top	;-10h
	sub	e
	cpl
	ret
;
; Flip the title screen
;
fltitle:
	call	flscr
	ld	hl,85FBh	;In-game tune
	ret
;
; Flip the screen over.
;
flscr:	ld	hl,4FE0h
	ld	de,4000h
fsc0:	ld	b,64		;Swap 64 lines of bits
fsc1:	call	fline
	djnz	fsc1
	ld	hl,59E0h
	ld	de,5800h
	ld	b,8		;and 8 lines of attributes.
fsc2:	call	fline
	djnz	fsc2
	ret
;
; Copy from JSW buffer at 6000h to screen at 4000h, flipping upside-down on
; the way.
;
flbits:
	ld	hl,6FE0h
	ld	de,4000h
fli0:	ld	b,128
fli1:	call	aline
	djnz	fli1
	ret
;
; Copy attributes from JSW buffer at 5E00h to screen at 5800h, flipping 
; upside-down on the way.
;
flattr:	ld	hl,5DE0h
	ld	de,5800h
	ld	b,16
fli2:	call	aline
	djnz	fli2
	ret
;
; Copy 32 bytes from HL to DE.
; At the end, DE is old DE + 32
;         and HL is old HL - 32
;
aline:	push	bc
	ld	bc,32
	ldir
	ld	bc,-64
	add	hl,bc
	pop	bc
	ret
;
; Like aline, but exchanges the bytes at the source & target positions.
;
fline:	push	bc
	ld	bc,32
fline1:	ld	a,(de)
	ldi
	dec	hl
	ld	(hl),a
	inc	hl
	ld	a,c
	or	a
	jr	nz,fline1
	ld	bc,-64
	add	hl,bc
	pop	bc
	ret
;
; Sprite for the upside-down foot.
;
rspr_foot:
	DEFB	3DH,76H
	DEFB	43H,8DH
	DEFB	80H,02H
	DEFB	80H,01H
	DEFB	84H,09H
	DEFB	88H,35H
	DEFB	48H,42H
        DEFB      20H,80H
	DEFB	20H,80H
	DEFB      10H,80H,10H,80H,10H,80H,10H,80H,10H,80H,10H,80H,10H,80H
;
;Software Projects fixes:
;    *  Moving an invisible object from the First Landing to The Hall (42183,11)
	org	42183
	defb	11


;    * Changing a block in the Banyan Tree to a walk-through type (56876,4)

	org	56876
	defb	4

;    * The Attic bug fix Poke (59901,82).

	org	59901
	defb	82

;    * Removing a killer object from the Conservatory Roof (60231,0),

	org	60231
	defb	0

	end
