
; PsychoEffect module
; This module provides one useful SWI PsychoEffect_Fade, where
;R0 = address to read source from
;R1 = address to write faded data to
;R2 = size of source
;R3 = output brightness
;R4 = width of screen in bytes

;The brightness can range from 0-60.  0 produces a black output, and
;60 produces an untouched full brightness image.  If the brightness is
;not a multiple of 4 a dithered image is produced.

;Code written by Andy Southgate 1994/95.  Permission to use freely, alter
;and recompile in any shape or form, and incorporate into your own
;code is granted.

;This source should be compiled with ExtAsm, and needs the file LinFade in
;the path Effects:

#name Effects
#type &ffa
#base 0

DCD 0
DCD 0
DCD 0
DCD 0
DCD title
DCD help
DCD commandtable
DCD &4C380
DCD swicode
DCD switab
DCD 0
.title
DCB "PsychoEffect",0
.help
DCB "Psychosis Effects		1.00 (24 Jan 1995)",0
ALIGN
.commandtable
DCB "PsychoEffect",0
ALIGN
DCD 0
DCD 0
DCD 0
DCD effectshelp

DCD 0; *** END Marker ***
.effectshelp
DCB 27,0," provides special effects for games.  It provides the SWI:",10,13,13
DCB 34,"PsychoEffect_Fade",34,",adr_from,adr_to,size,fade,width",10,13,13
DCB "adr_from",9,"source address",10,13
DCB " adr_to ",9,9,"output address",10,13
DCB "size",9,9,"size of memory block to fade",10,13
DCB "fade",9,9,"fade level. 0 is darkest (output is black), 60 is lightest",10,13
DCB 9,9,"(image is unfaded)",10,13
DCB "width",9,9,"width of screen mode - used for dithering.",10,13,13
DCB "Andy Southgate 1995 - use freely",0
ALIGN

.switab
DCB "PsychoEffect",0
DCB "Fade",0
DCB "FadeTable",0
DCB 0 ;*** END MARKER ***
ALIGN
.swicode
LDR R12,[R12]
CMP R11,#0
BEQ fadeswi
CMP R11,#1
BEQ fadetableswi
B unknownswierr

.fadetableswi
ADR R0,fadetable
MOV PC,R14

.fadeswi
STMFD R13!,{R0-R10,R14}
CMP R3,#61
LDMGEFD R13!,{R0-R10,R14}
BGE bigfadeerr
CMP R4,R2
LDMGTFD R13!,{R0-R10,R14}
BGT badwidtherr
CMP R4,#31
MOVLT R4,#320
TST R4,#15
LDMNEFD R13!,{R0-R10,R14}
BNE badwidtherr

MOV R10,R4
ADR R5,fadetable
AND R6,R3,#3
BIC R3,R3,#3
ADD R5,R5,R3,LSL #6
CMP R6,#1
BEQ dither1
CMP R6,#2
BEQ dither2
CMP R6,#3
BEQ dither3

.loop
LDMIA R0!,{R6-R9}
fade R6
fade R7
fade R8
fade R9
STMIA R1!,{R6-R9}
SUBS R2,R2,#16
BGT loop
.fadeins
LDMFD R13!,{R0-R10,PC}

.dither1
.loop4
STMFD R13!,{R2}
MOV R2,R10
.loop4b
LDMIA R0!,{R6-R9}
difade1 R6
difade1 R7
difade1 R8
difade1 R9
STMIA R1!,{R6-R9}
SUBS R2,R2,#16
BGT loop4b
MOV R2,R10
.loop4c
LDMIA R0!,{R6-R9}
difade1b R6
difade1b R7
difade1b R8
difade1b R9
STMIA R1!,{R6-R9}
SUBS R2,R2,#16
BGT loop4c
LDMFD R13!,{R2}
SUBS R2,R2,R10,LSL #1
BGT loop4
B fadeins

.dither2
.loop5
STMFD R13!,{R2}
MOV R2,R10
.loop5b
LDMIA R0!,{R6-R9}
difade2 R6
difade2 R7
difade2 R8
difade2 R9
STMIA R1!,{R6-R9}
SUBS R2,R2,#16
BGT loop5b
MOV R2,R10
.loop5c
LDMIA R0!,{R6-R9}
difade2b R6
difade2b R7
difade2b R8
difade2b R9
STMIA R1!,{R6-R9}
SUBS R2,R2,#16
BGT loop5c
LDMFD R13!,{R2}
SUBS R2,R2,R10,LSL #1
BGT loop5
B fadeins

.dither3
.loop6
STMFD R13!,{R2}
MOV R2,R10
.loop6b
LDMIA R0!,{R6-R9}
difade3 R6
difade3 R7
difade3 R8
difade3 R9
STMIA R1!,{R6-R9}
SUBS R2,R2,#16
BGT loop6b
MOV R2,R10
.loop6c
LDMIA R0!,{R6-R9}
difade3b R6
difade3b R7
difade3b R8
difade3b R9
STMIA R1!,{R6-R9}
SUBS R2,R2,#16
BGT loop6c
LDMFD R13!,{R2}
SUBS R2,R2,R10,LSL #1
BGT loop6
B fadeins




.white
.loop2
LDR R4,[R0],#4
STR R4,[R1],#4
SUBS R2,R2,#4
BGT loop2
B fadeins
.black
MOV R4,#0
.loop3
STR R4,[R1],#4
SUBS R2,R2,#4
BGT loop3
B fadeins


macro fade m0
{
LDRB R3,[R5,m0,LSR #24]
MOV m0,m0,LSL #8
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
LDRB R4,[R5,m0,LSR #24]
ORR m0,R4,R3,LSL #8
}
macro difade1 m0
{
LDRB R3,[R5,m0,LSR #24]
MOV m0,m0,LSL #8
ADD R5,R5,#256
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
SUB R5,R5,#256
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
LDRB R4,[R5,m0,LSR #24]
ORR m0,R4,R3,LSL #8
}

macro difade1b m0
{
LDRB R3,[R5,m0,LSR #24]
MOV m0,m0,LSL #8
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
ADD R5,R5,#256
LDRB R4,[R5,m0,LSR #24]
ORR m0,R4,R3,LSL #8
SUB R5,R5,#256
}

macro difade2 m0
{
LDRB R3,[R5,m0,LSR #24]
MOV m0,m0,LSL #8
ADD R5,R5,#256
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
SUB R5,R5,#256
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
ADD R5,R5,#256
LDRB R4,[R5,m0,LSR #24]
ORR m0,R4,R3,LSL #8
SUB R5,R5,#256
}
macro difade2b m0
{
ADD R5,R5,#256
LDRB R3,[R5,m0,LSR #24]
MOV m0,m0,LSL #8
SUB R5,R5,#256
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
ADD R5,R5,#256
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
SUB R5,R5,#256
LDRB R4,[R5,m0,LSR #24]
ORR m0,R4,R3,LSL #8
}
macro difade3 m0
{
LDRB R3,[R5,m0,LSR #24]
MOV m0,m0,LSL #8
ADD R5,R5,#256
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
LDRB R4,[R5,m0,LSR #24]
ORR m0,R4,R3,LSL #8
SUB R5,R5,#256
}
macro difade3b m0
{
ADD R5,R5,#256
LDRB R3,[R5,m0,LSR #24]
MOV m0,m0,LSL #8
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
SUB R5,R5,#256
LDRB R4,[R5,m0,LSR #24]
ORR R3,R4,R3,LSL #8
MOV m0,m0,LSL #8
ADD R5,R5,#256
LDRB R4,[R5,m0,LSR #24]
ORR m0,R4,R3,LSL #8
SUB R5,R5,#256
}
              	
.err
ORR R14,R14,#1<<28
MOVS PC,R14

.unknownswierr
ADR R0,unknownswitext
B err
.bigfadeerr
ADR R0,bigfadetext
B err
.badwidtherr
ADR R0,badwidthtext
B err
.unknownswitext
DCD &666
DCB "Psychosis Effects : Unknown SWI",0
ALIGN
.bigfadetext
DCD &666
DCB "Psychosis Effects : Too big a fade number",0
ALIGN
.badwidthtext
DCD &666
DCB "Psychosis Effects : Bad R4 - must be a multiple of 32 and  31<R4<R2",0
ALIGN

.fadetable
INCBIN Effects:LinFade
