; IconKludge.s

; Reverse engineered from IconNoDraw and IconNoFill V1.02 by Kamel Biskri.

; This source assembles with ASM-One V1.29, dunno about other assemblers ;^)


; History.

; v1.0 (11.10.96) first public release

; v1.1 (17.10.96)

; - LVOFindTask() replaced with execbase(ThisTask) in patch code, thanks to Kamel
;   Biskri for pointing out this is much faster than LVOFindTask.

; -------------------------------------------------------------

	incdir	'include:'

	include	'dos/dosextens.i'
	include	'exec/memory.i'
	include	'exec/execbase.i'


	include	'lvo/exec_lib.i'
	include	'lvo/intuition_lib.i'
	include	'lvo/graphics_lib.i'

; -------------------------------------------------------------

CALL:	MACRO
	jsr	_LVO\1(a6)
	ENDM

; -------------------------------------------------------------

	SECTION	ICONKLUDGE,CODE_P

O:	bra.b	SkipVer

	dc.b	'$VER: IconKludge 1.1 by Cliff Earl (11.10.96)',10,13,0
	EVEN

SkipVer:
	movem.l	d0-d7/a1-a6,-(sp)

	lea	O(pc),a4
	move.l	4.w,a6				; cache exec lib
	move.l	a6,_SysBase-O(a4)

	sub.l	a1,a1				; find our task ptr
	CALL	FindTask
	move.l	d0,a5
	lea	pr_MsgPort(a5),a0		; get the wb message
	CALL	WaitPort
	lea	pr_MsgPort(a5),a0
	CALL	GetMsg
	move.l	d0,_WbMsg-O(a4)

	lea	GfxName(pc),a1			; open gfx lib
	moveq	#36,d0
	CALL	OpenLibrary
	move.l	d0,_GfxBase-O(a4)
	beq.b	EXIT

	move.l	d0,a0				; check to see if already patched
	move.l	_LVORectFill+2(a0),a0
	move.l	-4(a0),d0
	cmp.l	PatchID(pc),d0
	beq.b	EXIT

	lea	IntuitionName(pc),a1		; open int lib
	moveq	#36,d0
	CALL	OpenLibrary
	move.l	d0,_IntuitionBase-O(a4)
	beq.b	EXIT

	lea	WorkbenchName(pc),a1		; get ptr to wb task
	CALL	FindTask
	move.l	d0,WbTaskPtr-O(a4)

	moveq	#Patch_SIZE,d0			; alloc mem for patches
	move.l	#MEMF_FAST!MEMF_PUBLIC!MEMF_REVERSE,d1
	CALL	AllocMem
	move.l	d0,d7
	beq.b	EXIT

	bsr.b	InstallPatches			; install em
EXIT:
	move.l	_GfxBase(pc),d0			; close gfx lib
	beq.b	.0
	move.l	d0,a1
	CALL	CloseLibrary
.0:
	move.l	_IntuitionBase(pc),d0		; close int lib
	beq.b	.1
	move.l	d0,a1
	CALL	CloseLibrary
.1:
	move.l	_WbMsg(pc),d0			; reply to the wb message if present
	beq.b	.2
	CALL	Forbid
	move.l	d0,a1
	CALL	ReplyMsg
.2:
	movem.l	(sp)+,d0-d7/a1-a6
	rts

; -------------------------------------------------------------

InstallPatches:
	CALL	Forbid

	move.l	_GfxBase(pc),a0			; save ptrs to old vectors
	move.l	_LVORectFill+2(a0),Old_RectFill-O(a4)
	move.l	_LVODraw+2(a0),Old_Draw-O(a4)

	lea	PatchCode(pc),a0		; relocate patches to himem :^)
	move.l	d7,a1
	moveq	#Patch_SIZE-1,d0
.0:
	move.b	(a0)+,(a1)+
	dbf	d0,.0

	move.l	_GfxBase(pc),a1			; change _LVODraw vector
	lea	_LVODraw.w,a0
	lea	(a1,a0),a2
	move.l	2(a2),Old_Draw-O(a4)
	move.l	d7,d0
	add.l	#Patch1_BEG,d0
	CALL	SetFunction

	move.l	_GfxBase(pc),a1			; change _LVORectFill vector
	lea	_LVORectFill.w,a0
	lea	(a1,a0),a2
	move.l	d7,d0
	add.l	#Patch2_BEG,d0
	CALL	SetFunction

	move.l	_IntuitionBase(pc),a6		; redraw wb icons borderless
	CALL	CloseWorkBench
	nop					; burp! says mr pipeline :^)
	CALL	OpenWorkBench

	move.l	_SysBase(pc),a6
	CALL	Permit
	rts

; -------------------------------------------------------------

_GfxBase:	dc.l	0
_IntuitionBase:	dc.l	0
_WbMsg:		dc.l	0

GfxName:	dc.b	'graphics.library',0
IntuitionName:	dc.b	'intuition.library',0
WorkbenchName:	dc.b	'Workbench',0
		EVEN

; -------------------------------------------------------------

PatchCode:

PatchID:	dc.b	'ATX!'

Patch2_BEG	=*-PatchCode

New_RectFill:
	cmp.l	#8,(8,sp)			; hmmmm...
	bne.b	.0

	movem.l	d0/a6,-(sp)			; make sure it's wb task
	move.l	_SysBase(pc),a6
	move.l	ThisTask(a6),d0
	cmp.l	WbTaskPtr(pc),d0
	bne.b	.1

	movem.l	(sp)+,d0/a6			; prune rect sizes
	addq	#3,d0
	subq	#3,d2
	addq	#2,d1
	subq	#2,d3
	move.l	Old_RectFill(pc),-(sp)
	rts
.1:
	movem.l	(sp)+,d0/a6
.0:
	move.l	Old_RectFill(pc),-(sp)
	rts

; -------------------------------------------------------------

	nop
	nop

Patch1_BEG	=*-PatchCode

New_Draw:
	cmp.l	#8,(8,sp)			; hmmmm...
	bne.b	.0

	movem.l	d0/a6,-(sp)			; if wb tsak then no drawing...
	move.l	_SysBase(pc),a6
	move.l	ThisTask(a6),d0
	cmp.l	WbTaskPtr(pc),d0
	bne.b	.1

	movem.l	(sp)+,d0/a6
	rts
.1:
	movem.l	(sp)+,d0/a6
.0:
	move.l	Old_Draw(pc),-(sp)
	rts

; -------------------------------------------------------------

WbTaskPtr:	dc.l	0

Old_Draw:	dc.l	0
Old_RectFill:	dc.l	0

_SysBase:	dc.l	0

Patch_SIZE	=*-PatchCode
