; Seven Kingdoms: Ancient Adversaries
;
; Copyright 1997,1998 Enlight Software Ltd.
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see .
;
;Filename : IB_TR.ASM
;Description : Blt a bitmap to the display surface buffer with color key transparency and color remapping handling
INCLUDE IMGFUN.inc
INCLUDE COLCODE.inc
.CODE
;-------- BEGIN OF FUNCTION IMBbltTransRemap ----------
;
; Put an non-compressed bitmap on image buffer.
; It handles color key transparency. The color key code is 255.
;
; T - Transparency key
; C - color remapping
;
; Syntax : IMBbltTransRemap( imageBuf, pitch, x, y, bitmapBuf, colorTable )
;
; char *imageBuf - the pointer to the display surface buffer
; int pitch - pitch of the display surface buffer
; int x,y - where to put the image on the surface buffer
; char *bitmapPtr - the pointer to the bitmap buffer
; char *colorTable - a 256-entry color remapping table
;
;-------------------------------------------------
;
; Format of the bitmap data :
;
; width
; height
; bitmap image
;
;-------------------------------------------------
PUBLIC IMGbltTransRemap
IMGbltTransRemap PROC imageBuf, pitch, x, y, bitmapPtr, colorTable
LOCAL bitmapWidth
STARTPROC
MOV EAX, imageBuf ; store the address of the image buffer to a variable
MOV image_buf, EAX
;------ get the bitmap width and height -----;
MOV AX , DS
MOV ES , AX
MOV ESI, bitmapPtr
XOR EAX, EAX
LODSW ; get bitmap width
MOV EBX, EAX
LODSW ; get bitmap height
MOV ECX, EAX
MOV EDX, pitch ; EDX = lineDiff
SUB EDX, EBX ; lineDiff = pitch - bitmap_width
MOV bitmapWidth, EBX
MOV EBX, colorTable ; store it in register for fast access
CLD ; clear direction flag for MOVSB
;------- pixels copying loop --------;
CALC_ADDR EDI, x, y, pitch ; Get the offset to the image buffer address
@@moreLines:
PUSH ECX
MOV ECX, bitmapWidth ; ECX is the line pixel counter
XOR EAX, EAX ; clear EAX as it will be used below
SHR ECX, 2
JZ SHORT @@nextScan
;-----------------------------------------------------------------------//
; The idea here is to not branch very often so we unroll the loop by four
; and try to not branch when a whole run of pixels is either transparent
; or not transparent.
;
; There are two loops. One loop is for a run of pixels equal to the
; transparent color, the other is for runs of pixels we need to store.
;
; When we detect a "bad" pixel we jump to the same position in the
; other loop.
;
; Here is the loop we will stay in as long as we encounter a "transparent"
; pixel in the source.
;-----------------------------------------------------------------------//
align 4
@@same:
mov al, ds:[esi]
PRE_REMAP
cmp al, TRANSPARENT_CODE
jne short @@diff0
@@same0:
mov al, ds:[esi+1]
PRE_REMAP
cmp al, TRANSPARENT_CODE
jne short @@diff1
@@same1:
mov al, ds:[esi+2]
PRE_REMAP
cmp al, TRANSPARENT_CODE
jne short @@diff2
@@same2:
mov al, ds:[esi+3]
PRE_REMAP
cmp al, TRANSPARENT_CODE
jne short @@diff3
@@same3:
add edi,4
add esi,4
dec ecx
jnz short @@same
jz short @@nextScan
;-----------------------------------------------------------------------//
; Here is the loop we will stay in as long as
; we encounter a "non transparent" pixel in the source.
;-----------------------------------------------------------------------//
align 4
@@diff:
mov al, ds:[esi]
PRE_REMAP
cmp al, TRANSPARENT_CODE
je short @@same0
@@diff0:
POST_REMAP
mov es:[edi], al
mov al, ds:[esi+1]
PRE_REMAP
cmp al, TRANSPARENT_CODE
je short @@same1
@@diff1:
POST_REMAP
mov es:[edi+1], al
mov al, ds:[esi+2]
PRE_REMAP
cmp al, TRANSPARENT_CODE
je short @@same2
@@diff2:
POST_REMAP
mov es:[edi+2], al
mov al, ds:[esi+3]
PRE_REMAP
cmp al, TRANSPARENT_CODE
je short @@same3
@@diff3:
POST_REMAP
mov es:[edi+3], al
add edi,4
add esi,4
dec ecx
jnz short @@diff
jz short @@nextScan
;-----------------------------------------------------------------------//
; We are at the end of a scan, check for odd leftover pixels to do
; and go to the next scan.
;-----------------------------------------------------------------------//
align 4
@@nextScan:
mov ecx,bitmapWidth ; bitmap width
and ecx,11b ; if its pixel count is an odd number
jnz short @@oddStuff
;-----------------------------------------------------------------------//
; move on to the start of the next line
;-----------------------------------------------------------------------//
@@nextScan1:
add edi, edx ; edx = lineDiff
pop ecx
dec ecx
jz @@end
jmp @@moreLines
;-----------------------------------------------------------------------//
; If the width is not a multiple of 4 we will come here to clean up
; the last few pixels
;-----------------------------------------------------------------------//
@@oddStuff:
inc ecx
@@oddLoop:
dec ecx
jz short @@nextScan1
mov al, ds:[esi]
inc esi
PRE_REMAP
inc edi
cmp al, TRANSPARENT_CODE
je short @@oddLoop
POST_REMAP
mov es:[edi-1], al
jmp short @@oddLoop
@@end: ENDPROC
IMGbltTransRemap ENDP
;----------- END OF FUNCTION IMGbltTransRemap ----------
END