Commit d2ef2628 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Update to cope with new pixel formats

Detail:
  s/Fonts01, s/Fonts02 - Cache the current mode flags & NColour values
  s/Blending - Font blending code improved to add support for new pixel formats. Supremacy blending code split off into seperate file as it's too big for a macro.
  s/BlendingS - New file containing the guts of the supremacy blending code. Old code only supported supremacy blending in 32bpp &TBGR modes; new code supports supremacy blending in 16bpp 4444 &TBGR, as well as alpha blending in 32bpp &TBGR and 16bpp 4444 &TBGR, and red/blue swapped modes (as well as the main blending code supporting all new RGB modes).
Admin:
  Tested on BB-xM
  Part of an implementation of the Extended Framebuffer Format Spec:
  http://www.riscosopen.org/wiki/documentation/show/Extended%20Framebuffer%20Format%20Specification


Version 3.75. Tagged as 'Manager-3_75'
parent 7c6b41fb
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "3.74"
Module_Version SETA 374
Module_MajorVersion SETS "3.75"
Module_Version SETA 375
Module_MinorVersion SETS ""
Module_Date SETS "07 May 2012"
Module_ApplicationDate SETS "07-May-12"
Module_Date SETS "07 Aug 2013"
Module_ApplicationDate SETS "07-Aug-13"
Module_ComponentName SETS "Manager"
Module_ComponentPath SETS "castle/RiscOS/Sources/Video/Render/Fonts/Manager"
Module_FullVersion SETS "3.74"
Module_HelpVersion SETS "3.74 (07 May 2012)"
Module_FullVersion SETS "3.75"
Module_HelpVersion SETS "3.75 (07 Aug 2013)"
END
/* (3.74)
/* (3.75)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 3.74
#define Module_MajorVersion_CMHG 3.75
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 07 May 2012
#define Module_Date_CMHG 07 Aug 2013
#define Module_MajorVersion "3.74"
#define Module_Version 374
#define Module_MajorVersion "3.75"
#define Module_Version 375
#define Module_MinorVersion ""
#define Module_Date "07 May 2012"
#define Module_Date "07 Aug 2013"
#define Module_ApplicationDate "07-May-12"
#define Module_ApplicationDate "07-Aug-13"
#define Module_ComponentName "Manager"
#define Module_ComponentPath "castle/RiscOS/Sources/Video/Render/Fonts/Manager"
#define Module_FullVersion "3.74"
#define Module_HelpVersion "3.74 (07 May 2012)"
#define Module_LibraryVersionInfo "3:74"
#define Module_FullVersion "3.75"
#define Module_HelpVersion "3.75 (07 Aug 2013)"
#define Module_LibraryVersionInfo "3:75"
......@@ -31,13 +31,17 @@
MACRO
$l Blend $mask, $destData, $alphaDst, $srcData, $alphaSrc, $shift
ASSERT ("$shift" <> "") :LOR: (($mask :AND: &F0000000)=0)
$l
[ NoARMT2
[ "$shift"=""
[ ("$shift"="") :LOR: (($mask :AND: &80000000)<>0)
ANDS R2, $destData, # $mask
|
MOVS R2, $destData, LSR # $shift
[ "$shift"<>""
MOVS R2, R2, LSR # $shift
]
|
MOVS R2, $destData, LSR # $shift
]
MULNE R2, $alphaDst, R2
[ "$shift"=""
......@@ -107,51 +111,77 @@ checkblend
; Assuming that the above is passed then we prepare the pixel writing vectors
; and compute suitable table data which we can use when painting the character
; data onto the screen.
;
; Several routines are used depending on the output mode and paint_blendsupr
; flag:
;
; - 8bpp modes go via a routine that uses InverseTable to convert to 15bpp and
; back
; - 16bpp 1555 and 16bpp 565 only have normal blending
; - 16bpp 4444 and 32bpp 8888 have three routines: normal, supremacy, and alpha
; - red/blue swapping in true-colour modes is handled by swapping blend_fgvalue
; - alpha/transparency mode of screen is irrelevant for normal blending;
; existing alpha/transparency of screen pixel is preserved
;
; ------------------------------------------------------------------------------
setblendingdata EntryS "R0-R3,R10"
LDR R0, plottype ; has client requested background blending?
LDR R0, plottype ; has client requested background blending?
STR R0, blend_plottype
[ :LNOT: blendingOn
TST R0, #paint_blended
BEQ %FT80
TST R0, #paint_blended
BEQ %FT80
]
LDR R10, log2bpp ; log2 depth of output device
CMP R10, #5 ; if > 32 bit per pixel then ignore
BGT %FT80
SUBS R10, R10, #3 ; convert to a valid index
BMI %FT80 ; and if < 8 bit per pixel then ignore
TST R0, #paint_blendsupr ; supremacy blending only in 32bpp
BEQ %FT40
TEQ R10, #2
ADDEQ R10, R10, #1
BNE %FT96
40 ADR R3, blend_table ; get pointer to blending functions for the depth
ADD R0, R3, R10, LSL # 4 ; index via the depth offset
LDMIA R0, { R0, R1, R2, R10 }
ADD R0, R0, R3
ADD R1, R1, R3
ADD R2, R2, R3
Push "R0-R1"
TEQ R10, #32 ; check to see what depth we are in:-
LDR R0, currentRGB_f ; get the foreground pixel colour
MOVEQ R0, R0, LSR # 8 ; if 32 bit per pixel then shift down so aligned to bit 0
ANDNE R1, R0, #&f8000000 ; if 16 bit per pixel then generate 5,5,5 from 24 bit colour
ANDNE LR, R0, #&00f80000
ORRNE R1, R1, LR, LSL # 3
ANDNE R0, R0, #&0000f800
ORRNE R0, R1, R0, LSL # 6
ORRNE R0, R0, R0, LSR # 16
MOVNE R0, R0, LSR # 1
STR R0, blend_fgvalue
LDR R10, log2bpp ; log2 depth of output device
CMP R10, #5 ; if > 32 bit per pixel then ignore
BGT %FT80
ADDEQ R10, R10, #2 ; skip the 16bpp entries
SUBS R10, R10, #3 ; convert to a valid index
BMI %FT80 ; and if < 8 bit per pixel then ignore
CMP R10, #1
LDR R2, modeflags
BNE %FT10
LDR R3, ncolour
TST R2, #ModeFlag_64k
MOVNE R10, #2
CMP R3, #4096
MOVLT R10, #3
10
ADR R3, blend_table ; get pointer to blending functions for the depth
ADD R10, R3, R10, LSL #5 ; index via the depth offset
ADD R1, R10, #8
TST R0, #paint_blendsupr ; supremacy blending?
ADDNE R1, R1, #8
TSTNE R2, #ModeFlag_DataFormatSub_Alpha ; alpha blending?
ADDNE R1, R1, #8
LDMIA R10, {R0, R10} ; get alpha table, conversion function
ADD LR, R0, R3
ADD R10, R10, R3
LDMIA R1, {R0, R1} ; get blending functions
CMP R0, #0
BEQ %FT96
ADD R0, R0, R3
ADD R1, R1, R3
ADRL R3, blend_putdata
STMIA R3, {R0, R1, LR} ; store blend functions, alpha table
LDR R0, currentRGB_f ; get the foreground pixel colour
TST R2, #ModeFlag_DataFormatSub_RGB
ANDNE R2, R0, #&FF0000
BICNE R0, R0, #&FF
ORRNE R0, R2, R0, ROR #16
[ NoARMv5
MOV LR, PC
MOV PC, R10 ; convert colour
|
BLX R10 ; convert colour
]
STR R0, blend_fgvalue
LDRB R0, currentRGB_f ; get the foreground supremacy
RSB R0, R0, #255 ; convert to alpha
......@@ -159,28 +189,23 @@ setblendingdata EntryS "R0-R3,R10"
ADDGE R0, R0, #1 ; scale to 0-&100
STR R0, blend_fgalpha
LDRB LR, bitsperpixel ; get the real pixel depth
TEQ LR, #8 ; is this 8 bit per pixel?
BNE %FT95
LDRB LR, bitsperpixel ; get the real pixel depth
TEQ LR, #8 ; is this 8 bit per pixel?
BNE %FT95
SWI XInverseTable_Calculate ; compute the inverse colour table
ADRVCL LR, blend_ctable ; it worked so store the table pointers
STMVCIA LR, { R0, R1 }
BVC %FT95
SWI XInverseTable_Calculate ; compute the inverse colour table
ADRVCL LR, blend_ctable ; it worked so store the table pointers
STMVCIA LR, { R0, R1 }
BVC %FT95
ADD SP, SP, # 4*2
80
ADRL R0, putdata_mono ; default pointers for functions etc
ADRL R1, putdataM_mono
ADR R2, outputdata
90
ADRL R3, blend_putdata ; and store the table values away
STMIA R3, { R0-R1, R2 }
PExitS
ADRL R0, putdata_mono ; default pointers for functions etc
ADRL R1, putdataM_mono
ADR R2, outputdata
ADRL R3, blend_putdata ; and store the table values away
STMIA R3, { R0-R1, R2 }
95
Pull "R0-R1"
B %BT90
PExitS
96
PullEnv
......@@ -195,31 +220,60 @@ xerr_FontBadSupremacyBlend
; used to convert from cache data into data that the blending functions
; can sensibly cope with.
;
; +0 -> offset to putdata function
; +4 -> offset to putdataM function
; +8 -> offset to alpha table
; +12 = bits per pixel (required for 8 bit blending)
; +0 -> offset to alpha table
; +4 -> offset to colour conversion function
; +8 -> offset to putdata function
; +12 -> offset to putdataM function
; +16 -> offset to putdataS function
; +20 -> offset to putdataSM function
; +24 -> offset to putdataA function
; +28 -> offset to putdataAM function
blend_table
& blend_putdata_8bpp - blend_table ; 8 bpp
& blend_putdataM_8bpp - blend_table
& alpha_table8 - blend_table
& 16 ; (trick internals into 16 bits per pixel)
& blend_putdata_16bpp - blend_table ; 16 bpp blending
& blend_putdataM_16bpp - blend_table
& alpha_table16 - blend_table
& 16
& blend_putdata_32bpp - blend_table ; 32 bpp blending
& blend_putdataM_32bpp - blend_table
& alpha_table32 - blend_table
& 32
& blend_putdataS_32bpp - blend_table ; 32 bpp supremacy blending
& blend_putdataSM_32bpp - blend_table
& alpha_table32 - blend_table
& 32
& alpha_table8 - blend_table ; 8 bpp
& blend_convert_1555 - blend_table
& blend_putdata_8bpp - blend_table
& blend_putdataM_8bpp - blend_table
& 0
& 0
& 0
& 0
& alpha_table16 - blend_table ; 16 bpp 1555 blending
& blend_convert_1555 - blend_table
& blend_putdata_1555 - blend_table
& blend_putdataM_1555 - blend_table
& 0
& 0
& 0
& 0
& alpha_table16 - blend_table ; 16 bpp 565 blending
& blend_convert_565 - blend_table
& blend_putdata_565 - blend_table
& blend_putdataM_565 - blend_table
& 0
& 0
& 0
& 0
& alpha_table16 - blend_table ; 16 bpp 4444 blending
& blend_convert_4444 - blend_table
& blend_putdata_4444 - blend_table
& blend_putdataM_4444 - blend_table
& blend_putdataS_4444 - blend_table
& blend_putdataSM_4444 - blend_table
& blend_putdataA_4444 - blend_table
& blend_putdataAM_4444 - blend_table
& alpha_table32 - blend_table ; 32 bpp blending
& blend_convert_32bpp - blend_table
& blend_putdata_32bpp - blend_table
& blend_putdataM_32bpp - blend_table
& blend_putdataS_32bpp - blend_table
& blend_putdataSM_32bpp - blend_table
& blend_putdataA_32bpp - blend_table
& blend_putdataAM_32bpp - blend_table
alpha_table8
& &00000000, &01000000, &02000000, &03000000, &04000000, &05000000, &06000000, &07000000
......@@ -233,6 +287,24 @@ alpha_table32
& &00000000, &00000100, &00000200, &00000300, &00000400, &00000500, &00000600, &00000700
& &00000900, &00000A00, &00000B00, &00000C00, &00000D00, &00000E00, &00000F00, &00001000
blend_convert_1555
ColourConv r0, r0, r1, r2, r3, 0, 5, 5, 5, 10, 5
ORR r0, r0, r0, LSL #16
MOV pc, lr
blend_convert_565
ColourConv r0, r0, r1, r2, r3, 0, 5, 5, 6, 11, 5
ORR r0, r0, r0, LSL #16
MOV pc, lr
blend_convert_4444
ColourConv r0, r0, r1, r2, r3, 0, 4, 4, 4, 8, 4
ORR r0, r0, r0, LSL #16
MOV pc, lr
blend_convert_32bpp
MOV r0, r0, LSR #8
MOV pc, lr
; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
......@@ -346,12 +418,12 @@ blend_putdataM_8bpp
; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
; Blending methods for 16 bit per pixel.
; Normal blending methods, 16bpp
MACRO
$l BlendNormal16 $mask1,$mask2,$mask3,$shift
AlignCd (Urk):MOD:16
blend_putdata_16bpp
$l
ANDS outdata, outdata, outmask ; ensure only relevant bits are set
BEQ blend_nodata
......@@ -364,17 +436,17 @@ blend_putdata_16bpp
BEQ %FT20 ; if == 0 then nothing therefore skip
RSB LR, R9, # 16 ; amount of background to be preserved
Blend &0000001f, pchar, LR, R1, R9 ; and combine together blended
Blend &000003e0, pchar, LR, R1, R9
Blend &00007c00, pchar, LR, R1, R9
Blend $mask1, pchar, LR, R1, R9 ; and combine together blended
Blend $mask2, pchar, LR, R1, R9
Blend $mask3, pchar, LR, R1, R9
20
MOVS outdata, outdata, LSR # 16 ; what is the intensity of the pixel we want to plot
BEQ %FT30 ; if == 0 then nothing therefore skip
RSB LR, outdata, # 16 ; amount of background to blend with
Blend &001f0000, pchar, LR, R1, outdata ; and do the blending
Blend &03e00000, pchar, LR, R1, outdata
Blend &7c000000, pchar, LR, R1, outdata, 26
Blend $mask1<<16, pchar, LR, R1, outdata ; and do the blending
Blend $mask2<<16, pchar, LR, R1, outdata
Blend $mask3<<16, pchar, LR, R1, outdata, $shift
30
STR pchar, [ outptr ], #4 ; write the new pixel value out
......@@ -382,9 +454,12 @@ blend_putdata_16bpp
MOV outmask, #0
Pull "R1-R3, PC"
MEND
blend_putdataM_16bpp
MACRO
$l BlendNormal16M $mask1,$mask2,$mask3,$shift
AlignCd (Urk):MOD:16
$l
ANDS outdata, outdata, outmask
BEQ blend_nodata ; nothing to be blended therefore ignore
......@@ -401,17 +476,17 @@ blend_putdataM_16bpp
BEQ %FT20 ; if == 0 then nothing therefore skip
RSB LR, R9, # 16 ; amount of background to be preserved
Blend &0000001f, pchar, LR, R1, R9 ; and combine together blended
Blend &000003e0, pchar, LR, R1, R9
Blend &00007c00, pchar, LR, R1, R9
Blend $mask1, pchar, LR, R1, R9 ; and combine together blended
Blend $mask2, pchar, LR, R1, R9
Blend $mask3, pchar, LR, R1, R9
20
MOVS R9, outdata, LSR # 16 ; what is the intensity of the pixel we want to plot
BEQ %FT30 ; if == 0 then nothing therefore skip
RSB LR, R9, # 16 ; amount of background to blend with
Blend &001f0000, pchar, LR, R1, R9 ; and do the blending
Blend &03e00000, pchar, LR, R1, R9
Blend &7c000000, pchar, LR, R1, R9, 26
Blend $mask1<<16, pchar, LR, R1, R9 ; and do the blending
Blend $mask2<<16, pchar, LR, R1, R9
Blend $mask3<<16, pchar, LR, R1, R9, $shift
30
STR pchar, [ outptr ], -R6 ; write the new pixel value out
......@@ -420,6 +495,15 @@ blend_putdataM_16bpp
Pull "outptr, R1-R3, R6-R7, LR"
B blend_nodata
MEND
blend_putdata_1555 BlendNormal16 &001F,&03E0,&7C00,26
blend_putdata_565 BlendNormal16 &001F,&07E0,&F800,27
blend_putdata_4444 BlendNormal16 &000F,&00F0,&0F00
blend_putdataM_1555 BlendNormal16M &001F,&03E0,&7C00,26
blend_putdataM_565 BlendNormal16M &001F,&07E0,&F800,27
blend_putdataM_4444 BlendNormal16M &000F,&00F0,&0F00
; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
......@@ -440,9 +524,10 @@ blend_putdata_32bpp
; outdata = &00000000-&00001000 (clear->solid)
MOV outdata, outdata, LSR # 8 ; amount of foreground to blend
; outdata = 0-16 (clear-solid)
RSB LR, outdata, # 16 ; and the amount of background
RSBS LR, outdata, # 16 ; and the amount of background
LDR pchar, [ outptr ] ; and pick up the current background pixel data
MOVEQ pchar, #0
LDRNE pchar, [ outptr ] ; and pick up the current background pixel data
blend_putdata_32bpp_common
Blend &000000FF, pchar, LR, R1, outdata ; blend them together
Blend &0000FF00, pchar, LR, R1, outdata
......@@ -482,118 +567,23 @@ blend_putdataM_32bpp
; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
; Blend into 32 bit per pixel, with supremacy blending
; almost the same as above, but with a check for background supremacy,
; and handling of foreground supremacy.
; Blend into 16/32 bit per pixel, with supremacy or alpha blending
; This generates blend_putdataS_32bpp, blend_putdataA_32bpp,
; blend_putdataSM_32bpp, blend_putdataSA_32bpp, blend_putdataS_4444,
; blend_putdataA_4444, blend_putdataSM_4444, and blend_putdataAM_4444
AlignCd (Urk):MOD:16
blend_putdataS_32bpp
GBLS routine
ANDS outdata, outdata, outmask ; ensure only relevant bits are set
BEQ blend_nodata
routine SETS "S"
Push "R1-R3, LR"
LDR R1, blend_fgvalue ; get the foreground painting colour
LDR R2, blend_fgalpha ; and the foreground alpha
; outdata = &00000000-&00001000 (clear->solid)
MOV outdata, outdata, LSR # 8 ; amount of foreground to blend
; outdata = 0-&10 (clear-solid)
MUL outdata, R2, outdata ; scale by foreground alpha
; outdata = 0-&1000 (clear-solid)
MOVS outdata, outdata, LSR #8 ; scale back to 0-&10
ADC outdata, outdata, #0 ; and round
RSB LR, outdata, # 16 ; and the amount of background
LDR pchar, [ outptr ] ; and pick up the current background pixel data
MOVS R2, pchar, LSR #24
BEQ blend_putdata_32bpp_common
ADR LR, blend_putdata_32bpp_common
; fall through into blend_putdataS_32bpp_nonopaque
; In pchar(R0) = screen data (non-opaque)
; outdata(R8) = anti-alias level 0-16 (clear-solid)
; R2 = bg supremacy (0-255) (solid-clear)
; blend_putdata's R1-R3,LR stacked
; Out: outdata and LR updated to reflect correct fg/bg weighting
; pchar's supremacy byte updated with composite supremacy
; R2,R3,outmask corrupted
; may jump out to blend_nodata if applicable
; Terminology: R,G,B,A components
; suffix t denotes top (ie text)
; b denotes bottom (ie screen background)
; c denotes composite (ie blended)
blend_putdataS_32bpp_nonopaque
; Can corrupt R2-R3 freely
; First calculate composite alpha level. FG alpha (At) is in range 0-16,
; BG alpha (Ab) is in range 255-0.
; First Ac = 1 - (1 - At) * (1 - Ab)
CMP R2, #128
ADDGT R2, R2, #1 ; R2 = 1-Ab scaled 0-&100
RSB outmask, outdata, #16; outmask = 1-At scaled 0-&10
MUL R3, R2, outmask ; R3 = (1-At)*(1-Ab) - 0-&1000
RSBS R3, R3, #4096 ; R3 = Ac (0=clear - &1000=solid)
BEQ blend32S_nodata
; Note Ac must >= At
; s := At / Ac
MOV R2, outdata, LSL #16 ; R2 = At scaled 0-&100000
DivRem outdata, R2, R3, outmask; outdata = At/Ac = s scaled 0-&100
MOVS outdata, outdata, LSR #4; s scaled 0-&10
ADC outdata, outdata, #0 ; round
MOVS R3, R3, LSR #4 ; R3 = Ac scaled 0-&100
ADC R3, R3, #0 ; round
CMP R3, #128
SUBGE R3, R3, #1 ; R3 = Ac scaled 0-&FF
RSB R3, R3, #255 ; convert to supremacy &FF-0
BIC pchar, pchar, #&FF000000
ORR pchar, pchar, R3, LSL #24 ; Place Ac in pchar
MOV R2, LR
RSB LR, outdata, #16 ; t scaled 0-&10
MOV PC, R2
blend32S_nodata
Pull "R1-R3, LR"
B blend_nodata
blend_putdataSM_32bpp
ANDS outdata, outdata, outmask
BEQ blend_nodata ; nothing to be blended therefore ignore
Push "outptr, R1-R3, R6, LR"
LDR R1, blend_fgvalue ; get the foreground painting colour
LDR R2, blend_fgalpha ; and the foreground alpha
LDR R6, linelen ; and the scaling information
LDR R9, this_ymagcnt
AlignCd (Urk):MOD:16
MOV outdata, outdata, LSR # 8 ; amount of foreground to blend
; outdata = 0-&10 (clear-solid)
MUL outdata, R2, outdata ; scale by foreground alpha
; outdata = 0-&1000 (clear-solid)
MOVS outdata, outdata, LSR #8 ; scale back to 0-&10
ADC outdata, outdata, #0 ; and round
RSB LR, outdata, # 16 ; and the amount of background
01
LDR pchar, [ outptr ] ; and pick up the current background pixel data
MOVS R2, pchar, LSR #24
BLNE blend_putdataS_32bpp_nonopaque
Blend &000000FF, pchar, LR, R1, outdata ; blend them together
Blend &0000FF00, pchar, LR, R1, outdata
Blend &00FF0000, pchar, LR, R1, outdata
STR pchar, [ outptr ], -R6 ; write the new pixel value out
GET s.BlendingS
SUBS R9, R9, #1
BNE %BT01
routine SETS "A"
Pull "outptr, R1-R3, R6, LR"
B blend_nodata
AlignCd (Urk):MOD:16
GET s.BlendingS
END
; Copyright 2013 Castle Technology Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; Blend into 16/32 bit per pixel, with supremacy or alpha blending
; This code is needed multiple times (once for supremacy, once for alpha) but
; is too big for a macro. So we GET it multiple times instead.
blend_putdata$routine._32bpp
ANDS outdata, outdata, outmask ; ensure only relevant bits are set
BEQ blend_nodata
Push "R1-R3, LR"
LDR R1, blend_fgvalue ; get the foreground painting colour
LDR R2, blend_fgalpha ; and the foreground alpha
; outdata = &00000000-&00001000 (clear->solid)
MOV outdata, outdata, LSR # 8 ; amount of foreground to blend
; outdata = 0-&10 (clear-solid)
MUL outdata, R2, outdata ; scale by foreground alpha
; outdata = 0-&1000 (clear-solid)
MOVS outdata, outdata, LSR #8 ; scale back to 0-&10
ADC outdata, outdata, #0 ; and round
RSB LR, outdata, # 16 ; and the amount of background
LDR pchar, [ outptr ] ; and pick up the current background pixel data
[ "$routine" = "S"
MOVS R2, pchar, LSR #24
|
MVNS R2, pchar, LSR #24
]
BEQ blend_putdata_32bpp_common
ADRL LR, blend_putdata_32bpp_common
; fall through into blend_putdataS_32bpp_nonopaque
; In pchar(R0) = screen data (non-opaque)
; outdata(R8) = anti-alias level 0-16 (clear-solid)
; R2 = bg supremacy (0-255) (solid-clear)
; blend_putdata's R1-R3,LR stacked
; Out: outdata and LR updated to reflect correct fg/bg weighting
; pchar's supremacy/alpha byte updated with composite supremacy/alpha
; R2,R3,outmask corrupted
; may jump out to blend_nodata if applicable
; Terminology: R,G,B,A components
; suffix t denotes top (ie text)
; b denotes bottom (ie screen background)
; c denotes composite (ie blended)
blend_putdata$routine._32bpp_nonopaque
; Can corrupt R2-R3 freely
; First calculate composite alpha level. FG alpha (At) is in range 0-16,
; BG alpha (Ab) is in range 255-0.
; First Ac = 1 - (1 - At) * (1 - Ab)
CMP R2, #128
ADDGT R2, R2, #1 ; R2 = 1-Ab scaled 0-&100
RSB outmask, outdata, #16; outmask = 1-At scaled 0-&10
MUL R3, R2, outmask ; R3 = (1-At)*(1-Ab) - 0-&1000
RSBS R3, R3, #4096 ; R3 = Ac (0=clear - &1000=solid)
BEQ blend32$routine._nodata
; Note Ac must >= At
; s := At / Ac
MOV R2, outdata, LSL #16 ; R2 = At scaled 0-&100000
DivRem outdata, R2, R3, outmask; outdata = At/Ac = s scaled 0-&100
MOVS outdata, outdata, LSR #4; s scaled 0-&10
ADC outdata, outdata, #0 ; round
MOVS R3, R3, LSR #4 ; R3 = Ac scaled 0-&100
ADC R3, R3, #0 ; round
CMP R3, #128
SUBGE R3, R3, #1 ; R3 = Ac scaled 0-&FF
[ "$routine" = "S"
ORR pchar, pchar, #&FF000000
SUB pchar, pchar, R3, LSL #24 ; Place Ac in pchar
|
BIC pchar, pchar, #&FF000000
ORR pchar, pchar, R3, LSL #24 ; Place Ac in pchar
]
MOV R2, LR
RSB LR, outdata, #16 ; t scaled 0-&10
MOV PC, R2
blend32$routine._nodata
Pull "R1-R3, LR"
B blend_nodata
blend_putdata$routine.M_32bpp
ANDS outdata, outdata, outmask
BEQ blend_nodata ; nothing to be blended therefore ignore
Push "outptr, R1-R3, R6, LR"
LDR R1, blend_fgvalue ; get the foreground painting colour
LDR R2, blend_fgalpha ; and the foreground alpha
LDR R6, linelen ; and the scaling information
LDR R9, this_ymagcnt
MOV outdata, outdata, LSR # 8 ; amount of foreground to blend
; outdata = 0-&10 (clear-solid)
MUL outdata, R2, outdata ; scale by foreground alpha
; outdata = 0-&1000 (clear-solid)
MOVS outdata, outdata, LSR #8 ; scale back to 0-&10
ADC outdata, outdata, #0 ; and round
RSB LR, outdata, # 16 ; and the amount of background
01
LDR pchar, [ outptr ] ; and pick up the current background pixel data
[ "$routine"="S"
MOVS R2, pchar, LSR #24
|
MVNS R2, pchar, LSR #24
]
BLNE blend_putdata$routine._32bpp_nonopaque
Blend &000000FF, pchar, LR, R1, outdata ; blend them together
Blend &0000FF00, pchar, LR, R1, outdata
Blend &00FF0000, pchar, LR, R1, outdata
STR pchar, [ outptr ], -R6 ; write the new pixel value out
SUBS R9, R9, #1
BNE %BT01
Pull "outptr, R1-R3, R6, LR"
B blend_nodata
blend_putdata$routine._4444
ANDS outdata, outdata, outmask ; ensure only relevant bits are set
BEQ blend_nodata
Push "R1-R3, LR"
LDR R1, blend_fgvalue ; get the foreground painting colour
LDR R2, blend_fgalpha ; and the foreground alpha
MUL outdata, R2, outdata ; scale by foreground alpha
AND R9, outdata, #&1FC0
; R9 = 0-&1000 (clear-solid)
MOVS R9, R9, LSR #8 ; scale back to 0-&10
ADC R9, R9, #0 ; and round
RSB LR, R9, # 16 ; and the amount of background
LDR pchar, [ outptr ] ; and pick up the current background pixel data
[ "$routine" = "S"
MOV R2, pchar, LSR #12
|
MVN R2, pchar, LSR #12
]
ANDS R2, R2, #15
BLNE blend_putdataSA_4444_nonopaque
CMP R9, #0
[ "$routine" = "S"
ORR pchar, pchar, #&F000
SUB pchar, pchar, R2, LSL #12 ; Place Ac in pchar
|
BIC pchar, pchar, #&F000
ORR pchar, pchar, R2, LSL #12 ; Place Ac in pchar
]
BEQ %FT10
Blend &000F, pchar, LR, R1, R9
Blend &00F0, pchar, LR, R1, R9
Blend &0F00, pchar, LR, R1, R9
10
MOVS R9, outdata, LSR #24 ; 0-&10 amount of foreground to blend
ADC R9, R9, #0 ; and round
RSB LR, R9, # 16 ; and the amount of background
[ "$routine" = "S"
MOVS R2, pchar, LSR #28
|
MVNS R2, pchar, LSR #28
]
BLNE blend_putdataSA_4444_nonopaque
CMP R9, #0
[ "$routine" = "S"
ORR pchar, pchar, #&F0000000
SUB pchar, pchar, R2, LSL #28 ; Place Ac in pchar
|
BIC pchar, pchar, #&F0000000
ORR pchar, pchar, R2, LSL #28 ; Place Ac in pchar
]
BEQ %FT10
Blend &000F0000, pchar, LR, R1, R9
Blend &00F00000, pchar, LR, R1, R9
Blend &0F000000, pchar, LR, R1, R9
10
STR pchar, [ outptr ], #4 ; write the new pixel value out
MOV outdata, #&80000000 ; set marker bit ready for next set of pixels
MOV outmask, #0
Pull "R1-R3, PC"
; In R9 = anti-alias level 0-16 (clear-solid)
; R2 = bg supremacy (0-15) (solid-clear)
; blend_putdata's R1-R3,LR stacked
; Out: R9 and LR updated to reflect correct fg/bg weighting
; R2 is composite alpha, 0-15
; R3,outmask corrupted
[ "$routine" = "A" ; This routine is the same both times, only generate it once
; Terminology: R,G,B,A components
; suffix t denotes top (ie text)
; b denotes bottom (ie screen background)
; c denotes composite (ie blended)
blend_putdataSA_4444_nonopaque
; Can corrupt R2-R3 freely
; First calculate composite alpha level. FG alpha (At) is in range 0-16,
; BG alpha (Ab) is in range 15-0.
; First Ac = 1 - (1 - At) * (1 - Ab)
CMP R2, #8
ADDGT R2, R2, #1 ; R2 = 1-Ab scaled 0-&10
RSB outmask, R9, #16; outmask = 1-At scaled 0-&10
MUL R3, R2, outmask ; R3 = (1-At)*(1-Ab) - 0-&100
RSBS R3, R3, #256 ; R3 = Ac (0=clear - &100=solid)
BEQ blend4444_nodata
; Note Ac must >= At
; s := At / Ac
MOV R2, R9, LSL #12 ; R2 = At scaled 0-&10000
DivRem R9, R2, R3, outmask ; R9 = At/Ac = s scaled 0-&100
MOVS R9, R9, LSR #4 ; s scaled 0-&10
ADC R9, R9, #0 ; round
MOVS R2, R3, LSR #4 ; R2 = Ac scaled 0-&10
ADC R2, R2, #0 ; round
CMP R2, #8
SUBGE R2, R2, #1 ; R3 = Ac scaled 0-&F
MOV R3, LR
RSB LR, R9, #16 ; t scaled 0-&10
MOV PC, R3
blend4444_nodata
; Note LR left invalid!
CMP R2, #8
MOV R9, #0
SUBGT R2, R2, #1
MOV PC, LR
]
blend_putdata$routine.M_4444
ANDS outdata, outdata, outmask
BEQ blend_nodata ; nothing to be blended therefore ignore
Push "outptr, R1-R4, R6, LR"
LDR R1, blend_fgvalue ; get the foreground painting colour
LDR R2, blend_fgalpha ; and the foreground alpha
LDR R6, linelen ; and the scaling information
LDR R4, this_ymagcnt
MUL outdata, R2, outdata ; scale by foreground alpha
01
AND R9, outdata, #&1FC0
; R9 = 0-&10 (clear-solid)
MOVS R9, R9, LSR #8 ; scale back to 0-&10
ADC R9, R9, #0 ; and round
RSB LR, R9, # 16 ; and the amount of background
LDR pchar, [ outptr ] ; and pick up the current background pixel data
[ "$routine"="S"
MOV R2, pchar, LSR #12
|
MVN R2, pchar, LSR #12
]
ANDS R2, R2, #15
BLNE blend_putdataSA_4444_nonopaque
CMP R9, #0
[ "$routine" = "S"
ORR pchar, pchar, #&F000
SUB pchar, pchar, R2, LSL #12 ; Place Ac in pchar
|
BIC pchar, pchar, #&F000
ORR pchar, pchar, R2, LSL #12 ; Place Ac in pchar
]
BEQ %FT10
Blend &000F, pchar, LR, R1, R9
Blend &00F0, pchar, LR, R1, R9
Blend &0F00, pchar, LR, R1, R9
10
MOVS R9, outdata, LSR #24 ; 0-&10 amount of foreground to blend
ADC R9, R9, #0 ; and round
RSB LR, R9, # 16 ; and the amount of background
[ "$routine" = "S"
MOVS R2, pchar, LSR #28
|
MVNS R2, pchar, LSR #28
]
BLNE blend_putdataSA_4444_nonopaque
CMP R9, #0
[ "$routine" = "S"
ORR pchar, pchar, #&F0000000
SUB pchar, pchar, R2, LSL #28 ; Place Ac in pchar
|
BIC pchar, pchar, #&F0000000
ORR pchar, pchar, R2, LSL #28 ; Place Ac in pchar
]
BEQ %FT10
Blend &000F0000, pchar, LR, R1, R9
Blend &00F00000, pchar, LR, R1, R9
Blend &0F000000, pchar, LR, R1, R9
10
STR pchar, [ outptr ], -R6 ; write the new pixel value out
SUBS R4, R4, #1
BNE %BT01
Pull "outptr, R1-R4, R6, LR"
B blend_nodata
END
......@@ -1439,6 +1439,9 @@ y_old0 # 4
x_new # 4
y_new # 4
ncolour # 4
modeflags # 4
modedata # 0
modedata_h # 4
modedata_px # 4
......@@ -1616,6 +1619,7 @@ plottype # 4 ; R2 on entry to Font_Paint
; user-supplied rubout window
align data,16
rubx0 # 4
ruby0 # 4
rubx1 # 4
......
......@@ -807,6 +807,10 @@ vduinputbuffer
DCD VduExt_NewPtX
DCD VduExt_NewPtY
DCD VduExt_NColour
DCD VduExt_ModeFlags
ASSERT modedata_h - vduoutputbuffer = . - vduinputbuffer
DCD VduExt_Log2BPP ; derive XshftFactor from this
DCD VduExt_XEigFactor
DCD VduExt_YEigFactor
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment