mirror of
https://github.com/jmarshall23/CnC_Remastered_Collection.git
synced 2026-08-12 08:00:55 +02:00
Used additional Chronoshift code to remove legacy assembly for stamp/icon rendering.
This commit is contained in:
@@ -547,6 +547,7 @@ set(src_redalert
|
|||||||
./RedAlert/TEXTBTN.H
|
./RedAlert/TEXTBTN.H
|
||||||
./RedAlert/THEME.CPP
|
./RedAlert/THEME.CPP
|
||||||
./RedAlert/THEME.H
|
./RedAlert/THEME.H
|
||||||
|
./RedAlert/TILESET.CPP
|
||||||
./RedAlert/TOGGLE.CPP
|
./RedAlert/TOGGLE.CPP
|
||||||
./RedAlert/TOGGLE.H
|
./RedAlert/TOGGLE.H
|
||||||
./RedAlert/TOOLTIP.CPP
|
./RedAlert/TOOLTIP.CPP
|
||||||
|
|||||||
@@ -0,0 +1,288 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @author CCHyper
|
||||||
|
* @author OmniBlade
|
||||||
|
*
|
||||||
|
* @brief Low level functions for loading and rendering C&C terrain tilesets.
|
||||||
|
*
|
||||||
|
* @copyright Chronoshift 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.
|
||||||
|
* A full copy of the GNU General Public License can be found in
|
||||||
|
* LICENSE
|
||||||
|
*/
|
||||||
|
#include "FUNCTION.H"
|
||||||
|
#include "gbuffer.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using std::memcpy;
|
||||||
|
|
||||||
|
class GraphicViewPortClass;
|
||||||
|
|
||||||
|
#define TD_TILESET_CHECK 0x20
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief union is to handle the parts of the header which vary between TD and RA format tiles.
|
||||||
|
*/
|
||||||
|
struct IconControlType
|
||||||
|
{
|
||||||
|
uint8_t* Get_Icon_Data()
|
||||||
|
{
|
||||||
|
if (td.icons == TD_TILESET_CHECK) {
|
||||||
|
return reinterpret_cast<uint8_t*>(this) + td.icons;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return reinterpret_cast<uint8_t*>(this) + ra.icons;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* Get_Icon_Map()
|
||||||
|
{
|
||||||
|
if (td.icons == TD_TILESET_CHECK) {
|
||||||
|
return reinterpret_cast<uint8_t*>(this) + td.map;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return reinterpret_cast<uint8_t*>(this) + ra.map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t width; // always 24 (ICON_WIDTH)
|
||||||
|
int16_t height; // always 24 (ICON_HEIGHT)
|
||||||
|
int16_t count; // count of cells in set, not same as images
|
||||||
|
int16_t allocated; // is treated like a bool, always 0 in the file?
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int32_t size; // filesize
|
||||||
|
int32_t icons; // always 0x00000020
|
||||||
|
int32_t palettes; // seems to always be 0x00000000
|
||||||
|
int32_t remaps; // unknown, bitfield?
|
||||||
|
int32_t trans_flag; // array of images length, unknown
|
||||||
|
int32_t map; // image index for each cell
|
||||||
|
} td;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int16_t map_width; // tile width in cells
|
||||||
|
int16_t map_height; // tile height in cells
|
||||||
|
int32_t size; // filesize
|
||||||
|
int32_t icons; // always 0x00000028
|
||||||
|
int32_t palettes; // seems to always be 0x00000000
|
||||||
|
int32_t remaps; // unknown, bitfield?
|
||||||
|
int32_t trans_flag; // array of images length, unknown
|
||||||
|
int32_t color_map; // terrain type index, ra only
|
||||||
|
int32_t map; // image index for each cell
|
||||||
|
} ra;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static int IconEntry;
|
||||||
|
static void* IconData;
|
||||||
|
static IconControlType* LastIconset;
|
||||||
|
static uint8_t* StampPtr;
|
||||||
|
static uint8_t* TransFlagPtr;
|
||||||
|
static uint8_t* MapPtr;
|
||||||
|
static int IconWidth;
|
||||||
|
static int IconHeight;
|
||||||
|
static int IconSize;
|
||||||
|
static int IconCount;
|
||||||
|
|
||||||
|
void __cdecl Init_Stamps(IconControlType* iconset)
|
||||||
|
{
|
||||||
|
if (iconset && LastIconset != iconset) {
|
||||||
|
IconCount = (iconset->count);
|
||||||
|
IconWidth = (iconset->width);
|
||||||
|
IconHeight = (iconset->height);
|
||||||
|
LastIconset = iconset;
|
||||||
|
IconSize = IconWidth * IconHeight;
|
||||||
|
|
||||||
|
// TD and RA tileset headers are slightly different, so check a constant that only exists in one type.
|
||||||
|
if ((iconset->td.icons) == TD_TILESET_CHECK) {
|
||||||
|
MapPtr = reinterpret_cast<uint8_t*>(iconset) + (iconset->td.map);
|
||||||
|
StampPtr = reinterpret_cast<uint8_t*>(iconset) + (iconset->td.icons);
|
||||||
|
TransFlagPtr = reinterpret_cast<uint8_t*>(iconset) + (iconset->td.trans_flag);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MapPtr = reinterpret_cast<uint8_t*>(iconset) + (iconset->ra.map);
|
||||||
|
StampPtr = reinterpret_cast<uint8_t*>(iconset) + (iconset->ra.icons);
|
||||||
|
TransFlagPtr = reinterpret_cast<uint8_t*>(iconset) + (iconset->ra.trans_flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cdecl Buffer_Draw_Stamp2(GraphicViewPortClass& viewport, IconControlType* tileset, int icon, int x, int y, const void* remapper)
|
||||||
|
{
|
||||||
|
if (!tileset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LastIconset != tileset) {
|
||||||
|
Init_Stamps(tileset);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t icon_index = MapPtr != nullptr ? MapPtr[icon] : icon;
|
||||||
|
|
||||||
|
if (icon_index < IconCount) {
|
||||||
|
|
||||||
|
int32_t fullpitch = viewport.Get_Full_Pitch(); //(viewport.Get_Pitch() + viewport.Get_XAdd() + viewport.Get_Width());
|
||||||
|
uint8_t* dst = x + y * fullpitch + (uint8_t*)(viewport.Get_Offset());
|
||||||
|
int32_t blitpitch = fullpitch - IconWidth;
|
||||||
|
uint8_t* src = &StampPtr[IconSize * icon_index];
|
||||||
|
|
||||||
|
if (remapper) {
|
||||||
|
const uint8_t* remap = static_cast<const uint8_t*>(remapper);
|
||||||
|
for (int i = 0; i < IconHeight; ++i) {
|
||||||
|
for (int j = 0; j < IconWidth; ++j) {
|
||||||
|
uint8_t cur_byte = remap[*src++];
|
||||||
|
|
||||||
|
if (cur_byte) {
|
||||||
|
*dst = cur_byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
++dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += blitpitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (TransFlagPtr[icon_index]) {
|
||||||
|
for (int i = 0; i < IconHeight; ++i) {
|
||||||
|
for (int j = 0; j < IconWidth; ++j) {
|
||||||
|
uint8_t cur_byte = *src++;
|
||||||
|
|
||||||
|
if (cur_byte) {
|
||||||
|
*dst = cur_byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
++dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += blitpitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (int32_t i = 0; i < IconHeight; ++i) {
|
||||||
|
memcpy(dst, src, IconWidth);
|
||||||
|
dst += fullpitch;
|
||||||
|
src += IconWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cdecl Buffer_Draw_Stamp_Clip2(GraphicViewPortClass& viewport, IconControlType* tileset, int icon, int x, int y, const void* remapper, int left, int top, int right, int bottom)
|
||||||
|
{
|
||||||
|
if (!tileset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LastIconset != tileset) {
|
||||||
|
Init_Stamps(tileset);
|
||||||
|
}
|
||||||
|
|
||||||
|
int icon_index = MapPtr != nullptr ? MapPtr[icon] : icon;
|
||||||
|
|
||||||
|
if (icon_index < IconCount) {
|
||||||
|
int blit_height = IconHeight;
|
||||||
|
int blit_width = IconWidth;
|
||||||
|
uint8_t* src = &StampPtr[IconSize * icon_index];
|
||||||
|
int width = left + right;
|
||||||
|
int xstart = left + x;
|
||||||
|
int height = top + bottom;
|
||||||
|
int ystart = top + y;
|
||||||
|
|
||||||
|
if (xstart < width && ystart < height && IconHeight + ystart > top && IconWidth + xstart > left) {
|
||||||
|
if (xstart < left) {
|
||||||
|
src += left - xstart;
|
||||||
|
blit_width -= left - xstart;
|
||||||
|
xstart = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
int src_pitch = IconWidth - blit_width;
|
||||||
|
|
||||||
|
if (blit_width + xstart > width) {
|
||||||
|
src_pitch += blit_width - (width - xstart);
|
||||||
|
blit_width = width - xstart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top > ystart) {
|
||||||
|
blit_height = IconHeight - (top - ystart);
|
||||||
|
src += IconWidth * (top - ystart);
|
||||||
|
ystart = top;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blit_height + ystart > height) {
|
||||||
|
blit_height = height - ystart;
|
||||||
|
}
|
||||||
|
|
||||||
|
int full_pitch = viewport.Get_Full_Pitch(); //(viewport.Get_Pitch() + viewport.Get_XAdd() + viewport.Get_Width());
|
||||||
|
uint8_t* dst = xstart + ystart * full_pitch + (uint8_t*)(viewport.Get_Offset());
|
||||||
|
int dst_pitch = full_pitch - blit_width;
|
||||||
|
|
||||||
|
if (remapper) {
|
||||||
|
const uint8_t* remap = static_cast<const uint8_t*>(remapper);
|
||||||
|
for (int i = 0; i < blit_height; ++i) {
|
||||||
|
for (int j = 0; j < blit_width; ++j) {
|
||||||
|
uint8_t cur_byte = remap[*src++];
|
||||||
|
if (cur_byte) {
|
||||||
|
*dst = cur_byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
++dst;
|
||||||
|
}
|
||||||
|
dst += dst_pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (TransFlagPtr[icon_index]) {
|
||||||
|
for (int i = 0; i < blit_height; ++i) {
|
||||||
|
for (int j = 0; j < blit_width; ++j) {
|
||||||
|
uint8_t cur_byte = *src++;
|
||||||
|
if (cur_byte) {
|
||||||
|
*dst = cur_byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
++dst;
|
||||||
|
}
|
||||||
|
src += src_pitch;
|
||||||
|
dst += dst_pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (int i = 0; i < blit_height; ++i) {
|
||||||
|
memcpy(dst, src, blit_width);
|
||||||
|
dst += full_pitch;
|
||||||
|
src += IconWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void __cdecl Buffer_Draw_Stamp_Clip(void const* this_object, void const* icondata, int icon, int x_pixel, int y_pixel, void const* remap, int min_x, int min_y, int max_x, int max_y) {
|
||||||
|
Buffer_Draw_Stamp_Clip2(*((GraphicViewPortClass*)this_object), (IconControlType*)icondata, icon, x_pixel, y_pixel, remap, min_x, min_y, max_x, max_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void __cdecl Buffer_Draw_Stamp(void const* thisptr, void const* icondata, int icon, int x_pixel, int y_pixel, void const* remap) {
|
||||||
|
Buffer_Draw_Stamp2(*((GraphicViewPortClass*)thisptr), (IconControlType*)icondata, icon, x_pixel, y_pixel, remap);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* Get_Icon_Set_Map(void* temp)
|
||||||
|
{
|
||||||
|
if (temp != nullptr) {
|
||||||
|
if ((static_cast<IconControlType*>(temp)->td.icons) == TD_TILESET_CHECK) {
|
||||||
|
return static_cast<uint8_t*>(temp) + (static_cast<IconControlType*>(temp)->td.icons);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return static_cast<uint8_t*>(temp) + (static_cast<IconControlType*>(temp)->ra.icons);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
@@ -1689,523 +1689,6 @@ fini:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
;***********************************************************
|
|
||||||
|
|
||||||
;***********************************************************
|
|
||||||
; DRAW_STAMP
|
|
||||||
;
|
|
||||||
; VOID cdecl Buffer_Draw_Stamp(VOID *icondata, WORD icon, WORD x_pixel, WORD y_pixel, VOID *remap);
|
|
||||||
;
|
|
||||||
; This routine renders the icon at the given coordinate.
|
|
||||||
;
|
|
||||||
; The remap table is a 256 byte simple pixel translation table to use when
|
|
||||||
; drawing the icon. Transparency check is performed AFTER the remap so it is possible to
|
|
||||||
; remap valid colors to be invisible (for special effect reasons).
|
|
||||||
; This routine is fastest when no remap table is passed in.
|
|
||||||
;*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void __cdecl Buffer_Draw_Stamp(void const *this_object, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap)
|
|
||||||
{
|
|
||||||
unsigned int modulo = 0;
|
|
||||||
unsigned int iwidth = 0;
|
|
||||||
unsigned char doremap = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
PROC Buffer_Draw_Stamp C near
|
|
||||||
|
|
||||||
ARG this_object:DWORD ; this is a member function
|
|
||||||
ARG icondata:DWORD ; Pointer to icondata.
|
|
||||||
ARG icon:DWORD ; Icon number to draw.
|
|
||||||
ARG x_pixel:DWORD ; X coordinate of icon.
|
|
||||||
ARG y_pixel:DWORD ; Y coordinate of icon.
|
|
||||||
ARG remap:DWORD ; Remap table.
|
|
||||||
|
|
||||||
LOCAL modulo:DWORD ; Modulo to get to next row.
|
|
||||||
LOCAL iwidth:DWORD ; Icon width (here for speedy access).
|
|
||||||
LOCAL doremap:BYTE ; Should remapping occur?
|
|
||||||
*/
|
|
||||||
|
|
||||||
__asm {
|
|
||||||
|
|
||||||
pushad
|
|
||||||
cmp [icondata],0
|
|
||||||
je proc_out
|
|
||||||
|
|
||||||
; Initialize the stamp data if necessary.
|
|
||||||
mov eax,[icondata]
|
|
||||||
cmp [LastIconset],eax
|
|
||||||
je short noreset
|
|
||||||
push eax
|
|
||||||
call Init_Stamps
|
|
||||||
pop eax // Clean up stack. ST - 12/20/2018 10:42AM
|
|
||||||
noreset:
|
|
||||||
|
|
||||||
; Determine if the icon number requested is actually in the set.
|
|
||||||
; Perform the logical icon to actual icon number remap if necessary.
|
|
||||||
mov ebx,[icon]
|
|
||||||
cmp [MapPtr],0
|
|
||||||
je short notmap
|
|
||||||
mov edi,[MapPtr]
|
|
||||||
mov bl,[edi+ebx]
|
|
||||||
notmap:
|
|
||||||
cmp ebx,[IconCount]
|
|
||||||
jae proc_out
|
|
||||||
mov [icon],ebx ; Updated icon number.
|
|
||||||
|
|
||||||
; If the remap table pointer passed in is NULL, then flag this condition
|
|
||||||
; so that the faster (non-remapping) icon draw loop will be used.
|
|
||||||
cmp [remap],0
|
|
||||||
setne [doremap]
|
|
||||||
|
|
||||||
; Get pointer to position to render icon. EDI = ptr to destination page.
|
|
||||||
mov ebx,[this_object]
|
|
||||||
mov edi,[ebx]GraphicViewPortClass.Offset
|
|
||||||
mov eax,[ebx]GraphicViewPortClass.Width
|
|
||||||
add eax,[ebx]GraphicViewPortClass.XAdd
|
|
||||||
add eax,[ebx]GraphicViewPortClass.Pitch
|
|
||||||
push eax ; save viewport full width for lower
|
|
||||||
mul [y_pixel]
|
|
||||||
add edi,eax
|
|
||||||
add edi,[x_pixel]
|
|
||||||
|
|
||||||
; Determine row modulo for advancing to next line.
|
|
||||||
pop eax ; retrieve viewport width
|
|
||||||
sub eax,[IconWidth]
|
|
||||||
mov [modulo],eax
|
|
||||||
|
|
||||||
; Setup some working variables.
|
|
||||||
mov ecx,[IconHeight] ; Row counter.
|
|
||||||
mov eax,[IconWidth]
|
|
||||||
mov [iwidth],eax ; Stack copy of byte width for easy BP access.
|
|
||||||
|
|
||||||
; Fetch pointer to start of icon's data. ESI = ptr to icon data.
|
|
||||||
mov eax,[icon]
|
|
||||||
mul [IconSize]
|
|
||||||
mov esi,[StampPtr]
|
|
||||||
add esi,eax
|
|
||||||
|
|
||||||
; Determine whether simple icon draw is sufficient or whether the
|
|
||||||
; extra remapping icon draw is needed.
|
|
||||||
cmp [BYTE PTR doremap],0
|
|
||||||
je short istranscheck
|
|
||||||
|
|
||||||
;************************************************************
|
|
||||||
; Complex icon draw -- extended remap.
|
|
||||||
; EBX = Palette pointer (ready for XLAT instruction).
|
|
||||||
; EDI = Pointer to icon destination in page.
|
|
||||||
; ESI = Pointer to icon data.
|
|
||||||
; ECX = Number of pixel rows.
|
|
||||||
;;; mov edx,[remap]
|
|
||||||
mov ebx,[remap]
|
|
||||||
xor eax,eax
|
|
||||||
xrowloop:
|
|
||||||
push ecx
|
|
||||||
mov ecx,[iwidth]
|
|
||||||
|
|
||||||
xcolumnloop:
|
|
||||||
lodsb
|
|
||||||
;;; mov ebx,edx
|
|
||||||
;;; add ebx,eax
|
|
||||||
;;; mov al,[ebx] ; New real color to draw.
|
|
||||||
xlatb
|
|
||||||
or al,al
|
|
||||||
jz short xskip1 ; Transparency skip check.
|
|
||||||
mov [edi],al
|
|
||||||
xskip1:
|
|
||||||
inc edi
|
|
||||||
loop xcolumnloop
|
|
||||||
|
|
||||||
pop ecx
|
|
||||||
add edi,[modulo]
|
|
||||||
loop xrowloop
|
|
||||||
jmp short proc_out
|
|
||||||
|
|
||||||
|
|
||||||
;************************************************************
|
|
||||||
; Check to see if transparent or generic draw is necessary.
|
|
||||||
istranscheck:
|
|
||||||
mov ebx,[IsTrans]
|
|
||||||
add ebx,[icon]
|
|
||||||
cmp [BYTE PTR ebx],0
|
|
||||||
jne short rowloop
|
|
||||||
|
|
||||||
;************************************************************
|
|
||||||
; Fast non-transparent icon draw routine.
|
|
||||||
; ES:DI = Pointer to icon destination in page.
|
|
||||||
; DS:SI = Pointer to icon data.
|
|
||||||
; CX = Number of pixel rows.
|
|
||||||
mov ebx,ecx
|
|
||||||
shr ebx,2
|
|
||||||
mov edx,[modulo]
|
|
||||||
mov eax,[iwidth]
|
|
||||||
shr eax,2
|
|
||||||
loop1:
|
|
||||||
mov ecx,eax
|
|
||||||
rep movsd
|
|
||||||
add edi,edx
|
|
||||||
|
|
||||||
mov ecx,eax
|
|
||||||
rep movsd
|
|
||||||
add edi,edx
|
|
||||||
|
|
||||||
mov ecx,eax
|
|
||||||
rep movsd
|
|
||||||
add edi,edx
|
|
||||||
|
|
||||||
mov ecx,eax
|
|
||||||
rep movsd
|
|
||||||
add edi,edx
|
|
||||||
|
|
||||||
dec ebx
|
|
||||||
jnz loop1
|
|
||||||
jmp short proc_out
|
|
||||||
|
|
||||||
;************************************************************
|
|
||||||
; Transparent icon draw routine -- no extended remap.
|
|
||||||
; ES:DI = Pointer to icon destination in page.
|
|
||||||
; DS:SI = Pointer to icon data.
|
|
||||||
; CX = Number of pixel rows.
|
|
||||||
rowloop:
|
|
||||||
push ecx
|
|
||||||
mov ecx,[iwidth]
|
|
||||||
|
|
||||||
columnloop:
|
|
||||||
lodsb
|
|
||||||
or al,al
|
|
||||||
jz short skip1 ; Transparency check.
|
|
||||||
mov [edi],al
|
|
||||||
skip1:
|
|
||||||
inc edi
|
|
||||||
loop columnloop
|
|
||||||
|
|
||||||
pop ecx
|
|
||||||
add edi,[modulo]
|
|
||||||
loop rowloop
|
|
||||||
|
|
||||||
; Cleanup and exit icon drawing routine.
|
|
||||||
proc_out:
|
|
||||||
popad
|
|
||||||
//ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
;***********************************************************
|
|
||||||
; DRAW_STAMP_CLIP
|
|
||||||
;
|
|
||||||
; VOID cdecl MCGA_Draw_Stamp_Clip(VOID *icondata, WORD icon, WORD x_pixel, WORD y_pixel, VOID *remap, LONG min_x, LONG min_y, LONG max_x, LONG max_y);
|
|
||||||
;
|
|
||||||
; This routine renders the icon at the given coordinate.
|
|
||||||
;
|
|
||||||
; The remap table is a 256 byte simple pixel translation table to use when
|
|
||||||
; drawing the icon. Transparency check is performed AFTER the remap so it is possible to
|
|
||||||
; remap valid colors to be invisible (for special effect reasons).
|
|
||||||
; This routine is fastest when no remap table is passed in.
|
|
||||||
;*
|
|
||||||
*/
|
|
||||||
void __cdecl Buffer_Draw_Stamp_Clip(void const *this_object, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap, int min_x, int min_y, int max_x, int max_y)
|
|
||||||
{
|
|
||||||
unsigned int modulo = 0;
|
|
||||||
unsigned int iwidth = 0;
|
|
||||||
unsigned int skip = 0;
|
|
||||||
unsigned char doremap = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
ARG this_object:DWORD ; this is a member function
|
|
||||||
ARG icondata:DWORD ; Pointer to icondata.
|
|
||||||
ARG icon:DWORD ; Icon number to draw.
|
|
||||||
ARG x_pixel:DWORD ; X coordinate of icon.
|
|
||||||
ARG y_pixel:DWORD ; Y coordinate of icon.
|
|
||||||
ARG remap:DWORD ; Remap table.
|
|
||||||
ARG min_x:DWORD ; Clipping rectangle boundary
|
|
||||||
ARG min_y:DWORD ; Clipping rectangle boundary
|
|
||||||
ARG max_x:DWORD ; Clipping rectangle boundary
|
|
||||||
ARG max_y:DWORD ; Clipping rectangle boundary
|
|
||||||
|
|
||||||
LOCAL modulo:DWORD ; Modulo to get to next row.
|
|
||||||
LOCAL iwidth:DWORD ; Icon width (here for speedy access).
|
|
||||||
LOCAL skip:DWORD ; amount to skip per row of icon data
|
|
||||||
LOCAL doremap:BYTE ; Should remapping occur?
|
|
||||||
*/
|
|
||||||
__asm {
|
|
||||||
pushad
|
|
||||||
cmp [icondata],0
|
|
||||||
je proc_out
|
|
||||||
|
|
||||||
; Initialize the stamp data if necessary.
|
|
||||||
mov eax,[icondata]
|
|
||||||
cmp [LastIconset],eax
|
|
||||||
je short noreset2
|
|
||||||
push eax
|
|
||||||
call Init_Stamps
|
|
||||||
pop eax // Clean up stack. ST - 12/20/2018 10:42AM
|
|
||||||
noreset2:
|
|
||||||
|
|
||||||
; Determine if the icon number requested is actually in the set.
|
|
||||||
; Perform the logical icon to actual icon number remap if necessary.
|
|
||||||
mov ebx,[icon]
|
|
||||||
cmp [MapPtr],0
|
|
||||||
je short notmap2
|
|
||||||
mov edi,[MapPtr]
|
|
||||||
mov bl,[edi+ebx]
|
|
||||||
notmap2:
|
|
||||||
cmp ebx,[IconCount]
|
|
||||||
jae proc_out
|
|
||||||
mov [icon],ebx ; Updated icon number.
|
|
||||||
|
|
||||||
; Setup some working variables.
|
|
||||||
mov ecx,[IconHeight] ; Row counter.
|
|
||||||
mov eax,[IconWidth]
|
|
||||||
mov [iwidth],eax ; Stack copy of byte width for easy BP access.
|
|
||||||
|
|
||||||
; Fetch pointer to start of icon's data. ESI = ptr to icon data.
|
|
||||||
mov eax,[icon]
|
|
||||||
mul [IconSize]
|
|
||||||
mov esi,[StampPtr]
|
|
||||||
add esi,eax
|
|
||||||
|
|
||||||
; Update the clipping window coordinates to be valid maxes instead of width & height
|
|
||||||
; , and change the coordinates to be window-relative
|
|
||||||
mov ebx,[min_x]
|
|
||||||
add [max_x],ebx
|
|
||||||
add [x_pixel],ebx ; make it window-relative
|
|
||||||
mov ebx,[min_y]
|
|
||||||
add [max_y],ebx
|
|
||||||
add [y_pixel],ebx ; make it window-relative
|
|
||||||
|
|
||||||
; See if the icon is within the clipping window
|
|
||||||
; First, verify that the icon position is less than the maximums
|
|
||||||
mov ebx,[x_pixel]
|
|
||||||
cmp ebx,[max_x]
|
|
||||||
jge proc_out
|
|
||||||
mov ebx,[y_pixel]
|
|
||||||
cmp ebx,[max_y]
|
|
||||||
jge proc_out
|
|
||||||
; Now verify that the icon position is >= the minimums
|
|
||||||
add ebx,[IconHeight]
|
|
||||||
cmp ebx,[min_y]
|
|
||||||
jle proc_out
|
|
||||||
mov ebx,[x_pixel]
|
|
||||||
add ebx,[IconWidth]
|
|
||||||
cmp ebx,[min_x]
|
|
||||||
jle proc_out
|
|
||||||
|
|
||||||
; Now, clip the x, y, width, and height variables to be within the
|
|
||||||
; clipping rectangle
|
|
||||||
mov ebx,[x_pixel]
|
|
||||||
cmp ebx,[min_x]
|
|
||||||
jge nominxclip
|
|
||||||
; x < minx, so must clip
|
|
||||||
mov ebx,[min_x]
|
|
||||||
sub ebx,[x_pixel]
|
|
||||||
add esi,ebx ; source ptr += (minx - x)
|
|
||||||
sub [iwidth],ebx ; icon width -= (minx - x)
|
|
||||||
mov ebx,[min_x]
|
|
||||||
mov [x_pixel],ebx
|
|
||||||
|
|
||||||
nominxclip:
|
|
||||||
mov eax,[IconWidth]
|
|
||||||
sub eax,[iwidth]
|
|
||||||
mov [skip],eax
|
|
||||||
|
|
||||||
; Check for x+width > max_x
|
|
||||||
mov eax,[x_pixel]
|
|
||||||
add eax,[iwidth]
|
|
||||||
cmp eax,[max_x]
|
|
||||||
jle nomaxxclip
|
|
||||||
; x+width is greater than max_x, so must clip width down
|
|
||||||
mov eax,[iwidth] ; eax = old width
|
|
||||||
mov ebx,[max_x]
|
|
||||||
sub ebx,[x_pixel]
|
|
||||||
mov [iwidth],ebx ; iwidth = max_x - xpixel
|
|
||||||
sub eax,ebx
|
|
||||||
add [skip],eax ; skip += (old width - iwidth)
|
|
||||||
nomaxxclip:
|
|
||||||
; check if y < miny
|
|
||||||
mov eax,[min_y]
|
|
||||||
cmp eax,[y_pixel] ; if(miny <= y_pixel), no clip needed
|
|
||||||
jle nominyclip
|
|
||||||
sub eax,[y_pixel]
|
|
||||||
sub ecx,eax ; height -= (miny - y)
|
|
||||||
mul [IconWidth]
|
|
||||||
add esi,eax ; icon source ptr += (width * (miny - y))
|
|
||||||
mov eax,[min_y]
|
|
||||||
mov [y_pixel],eax ; y = miny
|
|
||||||
nominyclip:
|
|
||||||
; check if (y+height) > max y
|
|
||||||
mov eax,[y_pixel]
|
|
||||||
add eax,ecx
|
|
||||||
cmp eax,[max_y] ; if (y + height <= max_y), no clip needed
|
|
||||||
jle nomaxyclip
|
|
||||||
mov ecx,[max_y] ; height = max_y - y_pixel
|
|
||||||
sub ecx,[y_pixel]
|
|
||||||
nomaxyclip:
|
|
||||||
|
|
||||||
; If the remap table pointer passed in is NULL, then flag this condition
|
|
||||||
; so that the faster (non-remapping) icon draw loop will be used.
|
|
||||||
cmp [remap],0
|
|
||||||
setne [doremap]
|
|
||||||
|
|
||||||
; Get pointer to position to render icon. EDI = ptr to destination page.
|
|
||||||
mov ebx,[this_object]
|
|
||||||
mov edi,[ebx]GraphicViewPortClass.Offset
|
|
||||||
mov eax,[ebx]GraphicViewPortClass.Width
|
|
||||||
add eax,[ebx]GraphicViewPortClass.XAdd
|
|
||||||
add eax,[ebx]GraphicViewPortClass.Pitch
|
|
||||||
push eax ; save viewport full width for lower
|
|
||||||
mul [y_pixel]
|
|
||||||
add edi,eax
|
|
||||||
add edi,[x_pixel]
|
|
||||||
|
|
||||||
; Determine row modulo for advancing to next line.
|
|
||||||
pop eax ; retrieve viewport width
|
|
||||||
sub eax,[iwidth]
|
|
||||||
mov [modulo],eax
|
|
||||||
|
|
||||||
; Determine whether simple icon draw is sufficient or whether the
|
|
||||||
; extra remapping icon draw is needed.
|
|
||||||
cmp [BYTE PTR doremap],0
|
|
||||||
je short istranscheck2
|
|
||||||
|
|
||||||
;************************************************************
|
|
||||||
; Complex icon draw -- extended remap.
|
|
||||||
; EBX = Palette pointer (ready for XLAT instruction).
|
|
||||||
; EDI = Pointer to icon destination in page.
|
|
||||||
; ESI = Pointer to icon data.
|
|
||||||
; ECX = Number of pixel rows.
|
|
||||||
mov ebx,[remap]
|
|
||||||
xor eax,eax
|
|
||||||
xrowloopc:
|
|
||||||
push ecx
|
|
||||||
mov ecx,[iwidth]
|
|
||||||
|
|
||||||
xcolumnloopc:
|
|
||||||
lodsb
|
|
||||||
xlatb
|
|
||||||
or al,al
|
|
||||||
jz short xskip1c ; Transparency skip check.
|
|
||||||
mov [edi],al
|
|
||||||
xskip1c:
|
|
||||||
inc edi
|
|
||||||
loop xcolumnloopc
|
|
||||||
|
|
||||||
pop ecx
|
|
||||||
add edi,[modulo]
|
|
||||||
add esi,[skip]
|
|
||||||
loop xrowloopc
|
|
||||||
jmp short proc_out
|
|
||||||
|
|
||||||
|
|
||||||
;************************************************************
|
|
||||||
; Check to see if transparent or generic draw is necessary.
|
|
||||||
istranscheck2:
|
|
||||||
mov ebx,[IsTrans]
|
|
||||||
add ebx,[icon]
|
|
||||||
cmp [BYTE PTR ebx],0
|
|
||||||
jne short rowloopc
|
|
||||||
|
|
||||||
;************************************************************
|
|
||||||
; Fast non-transparent icon draw routine.
|
|
||||||
; ES:DI = Pointer to icon destination in page.
|
|
||||||
; DS:SI = Pointer to icon data.
|
|
||||||
; CX = Number of pixel rows.
|
|
||||||
mov ebx,ecx
|
|
||||||
mov edx,[modulo]
|
|
||||||
mov eax,[iwidth]
|
|
||||||
|
|
||||||
;
|
|
||||||
; Optimise copy by dword aligning the destination
|
|
||||||
;
|
|
||||||
loop1c:
|
|
||||||
push eax
|
|
||||||
//rept 3 // No rept in inline asm. ST - 12/20/2018 10:43AM
|
|
||||||
test edi,3
|
|
||||||
jz aligned
|
|
||||||
movsb
|
|
||||||
dec eax
|
|
||||||
jz finishedit
|
|
||||||
|
|
||||||
test edi,3
|
|
||||||
jz aligned
|
|
||||||
movsb
|
|
||||||
dec eax
|
|
||||||
jz finishedit
|
|
||||||
|
|
||||||
test edi,3
|
|
||||||
jz aligned
|
|
||||||
movsb
|
|
||||||
dec eax
|
|
||||||
jz finishedit
|
|
||||||
|
|
||||||
//endm
|
|
||||||
aligned:
|
|
||||||
mov ecx,eax
|
|
||||||
shr ecx,2
|
|
||||||
rep movsd
|
|
||||||
mov ecx,eax
|
|
||||||
and ecx,3
|
|
||||||
rep movsb
|
|
||||||
|
|
||||||
finishedit:
|
|
||||||
add edi,edx
|
|
||||||
add esi,[skip]
|
|
||||||
pop eax
|
|
||||||
|
|
||||||
dec ebx
|
|
||||||
jnz loop1c
|
|
||||||
jmp short proc_out
|
|
||||||
|
|
||||||
;************************************************************
|
|
||||||
; Transparent icon draw routine -- no extended remap.
|
|
||||||
; ES:DI = Pointer to icon destination in page.
|
|
||||||
; DS:SI = Pointer to icon data.
|
|
||||||
; CX = Number of pixel rows.
|
|
||||||
rowloopc:
|
|
||||||
push ecx
|
|
||||||
mov ecx,[iwidth]
|
|
||||||
|
|
||||||
columnloopc:
|
|
||||||
lodsb
|
|
||||||
or al,al
|
|
||||||
jz short skip1c ; Transparency check.
|
|
||||||
mov [edi],al
|
|
||||||
skip1c:
|
|
||||||
inc edi
|
|
||||||
loop columnloopc
|
|
||||||
|
|
||||||
pop ecx
|
|
||||||
add edi,[modulo]
|
|
||||||
add esi,[skip]
|
|
||||||
loop rowloopc
|
|
||||||
|
|
||||||
; Cleanup and exit icon drawing routine.
|
|
||||||
proc_out:
|
|
||||||
popad
|
|
||||||
//ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VOID __cdecl Buffer_Draw_Line(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color);
|
VOID __cdecl Buffer_Draw_Line(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color);
|
||||||
VOID __cdecl Buffer_Fill_Rect(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color);
|
VOID __cdecl Buffer_Fill_Rect(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color);
|
||||||
VOID __cdecl Buffer_Remap(void * thisptr, int sx, int sy, int width, int height, void *remap);
|
VOID __cdecl Buffer_Remap(void * thisptr, int sx, int sy, int width, int height, void *remap);
|
||||||
|
|||||||
Reference in New Issue
Block a user