Linear_Scale_To_Linear ported to C

This commit is contained in:
Justin Marshall
2020-06-06 17:19:43 -07:00
parent 26df6c8074
commit d5698bc9f2
+56 -745
View File
@@ -1870,757 +1870,68 @@ BOOL __cdecl Linear_Blit_To_Linear( void *this_object, void * dest, int x_pixel,
USES eax,ebx,ecx,edx,esi,edi
*/
// Ran out of registers so had to use ebp. ST - 12/19/2018 6:22PM
#pragma warning (push)
#pragma warning (disable : 4731)
BOOL __cdecl Linear_Scale_To_Linear(void *this_object, void *dest, int src_x, int src_y, int dst_x, int dst_y, int src_width, int src_height, int dst_width, int dst_height, BOOL trans, char *remap)
// jmarshall - ported to c
void Nearest_CopyImage(byte* source, int sourceX, int sourceY, int sourceWidth, byte* dest, int destX, int destY, int destWidth, int width, int height)
{
/*
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int _x = x;
int _y = y;
int destPos = (destWidth * (_y + (destY))) + (_x + (destX));
int sourcePos = (sourceWidth * (_y + (sourceY))) + (_x + (sourceX));
;*===================================================================
;* Define the arguements that our function takes.
;*===================================================================
ARG this_object:DWORD ; pointer to source view port
ARG dest:DWORD ; pointer to destination view port
ARG src_x:DWORD ; source x offset into view port
ARG src_y:DWORD ; source y offset into view port
ARG dst_x:DWORD ; dest x offset into view port
ARG dst_y:DWORD ; dest y offset into view port
ARG src_width:DWORD ; width of source rectangle
ARG src_height:DWORD ; height of source rectangle
ARG dst_width:DWORD ; width of dest rectangle
ARG dst_height:DWORD ; width of dest height
ARG trans:DWORD ; is this transparent?
ARG remap:DWORD ; pointer to table to remap source
;*===================================================================
;* Define local variables to hold the viewport characteristics
;*===================================================================
local src_x0 : dword
local src_y0 : dword
local src_x1 : dword
local src_y1 : dword
local dst_x0 : dword
local dst_y0 : dword
local dst_x1 : dword
local dst_y1 : dword
local src_win_width : dword
local dst_win_width : dword
local dy_intr : dword
local dy_frac : dword
local dy_acc : dword
local dx_frac : dword
local counter_x : dword
local counter_y : dword
local remap_counter :dword
local entry : dword
*/
int src_x0;
int src_y0;
int src_x1;
int src_y1;
int dst_x0;
int dst_y0;
int dst_x1;
int dst_y1;
int src_win_width;
int dst_win_width;
int dy_intr;
int dy_frac;
int dy_acc;
int dx_frac;
int counter_x;
int counter_y;
int remap_counter;
int entry;
__asm {
;*===================================================================
;* Check for scale error when to or from size 0,0
;*===================================================================
cmp [dst_width],0
je all_done
cmp [dst_height],0
je all_done
cmp [src_width],0
je all_done
cmp [src_height],0
je all_done
mov eax , [ src_x ]
mov ebx , [ src_y ]
mov [ src_x0 ] , eax
mov [ src_y0 ] , ebx
add eax , [ src_width ]
add ebx , [ src_height ]
mov [ src_x1 ] , eax
mov [ src_y1 ] , ebx
mov eax , [ dst_x ]
mov ebx , [ dst_y ]
mov [ dst_x0 ] , eax
mov [ dst_y0 ] , ebx
add eax , [ dst_width ]
add ebx , [ dst_height ]
mov [ dst_x1 ] , eax
mov [ dst_y1 ] , ebx
; Clip Source Rectangle against source Window boundaries.
mov esi , [ this_object ] ; get ptr to src
xor ecx , ecx
xor edx , edx
mov edi , [esi]GraphicViewPortClass.Width ; get width into register
mov eax , [ src_x0 ]
mov ebx , [ src_x1 ]
shld ecx , eax , 1
inc edi
shld edx , ebx , 1
sub eax , edi
sub ebx , edi
shld ecx , eax , 1
shld edx , ebx , 1
mov edi,[esi]GraphicViewPortClass.Height ; get height into register
mov eax , [ src_y0 ]
mov ebx , [ src_y1 ]
shld ecx , eax , 1
inc edi
shld edx , ebx , 1
sub eax , edi
sub ebx , edi
shld ecx , eax , 1
shld edx , ebx , 1
xor cl , 5
xor dl , 5
mov al , cl
test dl , cl
jnz all_done
or al , dl
jz clip_against_dest
mov bl , dl
test cl , 1000b
jz src_left_ok
xor eax , eax
mov [ src_x0 ] , eax
sub eax , [ src_x ]
imul [ dst_width ]
idiv [ src_width ]
add eax , [ dst_x ]
mov [ dst_x0 ] , eax
src_left_ok:
test cl , 0010b
jz src_bottom_ok
xor eax , eax
mov [ src_y0 ] , eax
sub eax , [ src_y ]
imul [ dst_height ]
idiv [ src_height ]
add eax , [ dst_y ]
mov [ dst_y0 ] , eax
src_bottom_ok:
test bl , 0100b
jz src_right_ok
mov eax , [esi]GraphicViewPortClass.Width ; get width into register
mov [ src_x1 ] , eax
sub eax , [ src_x ]
imul [ dst_width ]
idiv [ src_width ]
add eax , [ dst_x ]
mov [ dst_x1 ] , eax
src_right_ok:
test bl , 0001b
jz clip_against_dest
mov eax , [esi]GraphicViewPortClass.Height ; get width into register
mov [ src_y1 ] , eax
sub eax , [ src_y ]
imul [ dst_height ]
idiv [ src_height ]
add eax , [ dst_y ]
mov [ dst_y1 ] , eax
; Clip destination Rectangle against source Window boundaries.
clip_against_dest:
mov esi , [ dest ] ; get ptr to src
xor ecx , ecx
xor edx , edx
mov edi , [esi]GraphicViewPortClass.Width ; get width into register
mov eax , [ dst_x0 ]
mov ebx , [ dst_x1 ]
shld ecx , eax , 1
inc edi
shld edx , ebx , 1
sub eax , edi
sub ebx , edi
shld ecx , eax , 1
shld edx , ebx , 1
mov edi,[esi]GraphicViewPortClass.Height ; get height into register
mov eax , [ dst_y0 ]
mov ebx , [ dst_y1 ]
shld ecx , eax , 1
inc edi
shld edx , ebx , 1
sub eax , edi
sub ebx , edi
shld ecx , eax , 1
shld edx , ebx , 1
xor cl , 5
xor dl , 5
mov al , cl
test dl , cl
jnz all_done
or al , dl
jz do_scaling
mov bl , dl
test cl , 1000b
jz dst_left_ok
xor eax , eax
mov [ dst_x0 ] , eax
sub eax , [ dst_x ]
imul [ src_width ]
idiv [ dst_width ]
add eax , [ src_x ]
mov [ src_x0 ] , eax
dst_left_ok:
test cl , 0010b
jz dst_bottom_ok
xor eax , eax
mov [ dst_y0 ] , eax
sub eax , [ dst_y ]
imul [ src_height ]
idiv [ dst_height ]
add eax , [ src_y ]
mov [ src_y0 ] , eax
dst_bottom_ok:
test bl , 0100b
jz dst_right_ok
mov eax , [esi]GraphicViewPortClass.Width ; get width into register
mov [ dst_x1 ] , eax
sub eax , [ dst_x ]
imul [ src_width ]
idiv [ dst_width ]
add eax , [ src_x ]
mov [ src_x1 ] , eax
dst_right_ok:
test bl , 0001b
jz do_scaling
mov eax , [esi]GraphicViewPortClass.Height ; get width into register
mov [ dst_y1 ] , eax
sub eax , [ dst_y ]
imul [ src_height ]
idiv [ dst_height ]
add eax , [ src_y ]
mov [ src_y1 ] , eax
do_scaling:
cld
mov ebx , [ this_object ]
mov esi , [ebx]GraphicViewPortClass. Offset
mov eax , [ebx]GraphicViewPortClass. XAdd
add eax , [ebx]GraphicViewPortClass. Width
add eax , [ebx]GraphicViewPortClass. Pitch
mov [ src_win_width ] , eax
mul [ src_y0 ]
add esi , [ src_x0 ]
add esi , eax
mov ebx , [ dest ]
mov edi , [ebx]GraphicViewPortClass. Offset
mov eax , [ebx]GraphicViewPortClass. XAdd
add eax , [ebx]GraphicViewPortClass. Width
add eax , [ebx]GraphicViewPortClass. Pitch
mov [ dst_win_width ] , eax
mul [ dst_y0 ]
add edi , [ dst_x0 ]
add edi , eax
mov eax , [ src_height ]
xor edx , edx
mov ebx , [ dst_height ]
idiv [ dst_height ]
imul eax , [ src_win_width ]
neg ebx
mov [ dy_intr ] , eax
mov [ dy_frac ] , edx
mov [ dy_acc ] , ebx
mov eax , [ src_width ]
xor edx , edx
shl eax , 16
idiv [ dst_width ]
xor edx , edx
shld edx , eax , 16
shl eax , 16
mov ecx , [ dst_y1 ]
mov ebx , [ dst_x1 ]
sub ecx , [ dst_y0 ]
jle all_done
sub ebx , [ dst_x0 ]
jle all_done
mov [ counter_y ] , ecx
cmp [ trans ] , 0
jnz transparency
cmp [ remap ] , 0
jnz normal_remap
; *************************************************************************
; normal scale
mov ecx , ebx
and ecx , 01fh
lea ecx , [ ecx + ecx * 2 ]
shr ebx , 5
neg ecx
mov [ counter_x ] , ebx
lea ecx , [ ref_point + ecx + ecx * 2 ]
mov [ entry ] , ecx
outter_loop:
push esi
push edi
xor ecx , ecx
mov ebx , [ counter_x ]
jmp [ entry ]
inner_loop:
// REPT not supported for inline asm. ST - 12/19/2018 6:11PM
//REPT 32
push ebx //ST - 12/19/2018 6:11PM
mov ebx,32 //ST - 12/19/2018 6:11PM
rept_loop:
mov cl , [ esi ]
add ecx , eax
adc esi , edx
mov [ edi ] , cl
inc edi
dec ebx //ST - 12/19/2018 6:11PM
jnz rept_loop //ST - 12/19/2018 6:11PM
pop ebx //ST - 12/19/2018 6:11PM
//ENDM
ref_point:
dec ebx
jge inner_loop
pop edi
pop esi
add edi , [ dst_win_width ]
add esi , [ dy_intr ]
mov ebx , [ dy_acc ]
add ebx , [ dy_frac ]
jle skip_line
add esi , [ src_win_width ]
sub ebx , [ dst_height ]
skip_line:
dec [ counter_y ]
mov [ dy_acc ] , ebx
jnz outter_loop
jmp all_done //ret
; *************************************************************************
; normal scale with remap
normal_remap:
mov ecx , ebx
mov [ dx_frac ], eax
and ecx , 01fh
mov eax , [ remap ]
shr ebx , 5
imul ecx , - 13
mov [ counter_x ] , ebx
lea ecx , [ remapref_point ]
mov [ entry ] , ecx
remapoutter_loop:
mov ebx , [ counter_x ]
push esi
mov [ remap_counter ] , ebx
push edi
xor ecx , ecx
xor ebx , ebx
jmp [ entry ]
remapinner_loop:
// REPT not supported for inline asm. ST - 12/19/2018 6:11PM
//REPT 32
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
mov bl , [ esi ]
add ecx , [ dx_frac ]
adc esi , edx
mov cl , [ eax + ebx ]
mov [ edi ] , cl
inc edi
//ENDM
remapref_point:
dec [ remap_counter ]
jge remapinner_loop
pop edi
pop esi
add edi , [ dst_win_width ]
add esi , [ dy_intr ]
mov ebx , [ dy_acc ]
add ebx , [ dy_frac ]
jle remapskip_line
add esi , [ src_win_width ]
sub ebx , [ dst_height ]
remapskip_line:
dec [ counter_y ]
mov [ dy_acc ] , ebx
jnz remapoutter_loop
jmp all_done //ret
;****************************************************************************
; scale with trnsparency
transparency:
cmp [ remap ] , 0
jnz trans_remap
; *************************************************************************
; normal scale with transparency
mov ecx , ebx
and ecx , 01fh
imul ecx , -13
shr ebx , 5
mov [ counter_x ] , ebx
lea ecx , [ trans_ref_point ]
mov [ entry ] , ecx
trans_outter_loop:
xor ecx , ecx
push esi
push edi
mov ebx , [ counter_x ]
jmp [ entry ]
trans_inner_loop:
// REPT not supported for inline asm. ST - 12/19/2018 6:11PM
//REPT 32
push ebx //ST - 12/19/2018 6:11PM
mov ebx,32 //ST - 12/19/2018 6:11PM
rept_loop2:
mov cl , [ esi ]
test cl , cl
jz trans_pixel
mov [ edi ] , cl
trans_pixel:
add ecx , eax
adc esi , edx
inc edi
dec ebx //ST - 12/19/2018 6:11PM
jnz rept_loop2 //ST - 12/19/2018 6:11PM
pop ebx //ST - 12/19/2018 6:11PM
//ENDM
trans_ref_point:
dec ebx
jge trans_inner_loop
pop edi
pop esi
add edi , [ dst_win_width ]
add esi , [ dy_intr ]
mov ebx , [ dy_acc ]
add ebx , [ dy_frac ]
jle trans_skip_line
add esi , [ src_win_width ]
sub ebx , [ dst_height ]
trans_skip_line:
dec [ counter_y ]
mov [ dy_acc ] , ebx
jnz trans_outter_loop
jmp all_done //ret
; *************************************************************************
; normal scale with remap
trans_remap:
mov ecx , ebx
mov [ dx_frac ], eax
and ecx , 01fh
mov eax , [ remap ]
shr ebx , 5
imul ecx , - 17
mov [ counter_x ] , ebx
lea ecx , [ trans_remapref_point ]
mov [ entry ] , ecx
trans_remapoutter_loop:
mov ebx , [ counter_x ]
push esi
mov [ remap_counter ] , ebx
push edi
xor ecx , ecx
xor ebx , ebx
jmp [ entry ]
trans_remapinner_loop:
// REPT not supported for inline asm. ST - 12/19/2018 6:11PM
//REPT 32
// Run out of registers so use ebp
push ebp //ST - 12/19/2018 6:11PM
mov ebp,32 //ST - 12/19/2018 6:11PM
rept_loop3:
mov bl , [ esi ]
test bl , bl
jz trans_pixel2
mov cl , [ eax + ebx ]
mov [ edi ] , cl
trans_pixel2:
add ecx , [ dx_frac ]
adc esi , edx
inc edi
dec ebp //ST - 12/19/2018 6:11PM
jnz rept_loop3 //ST - 12/19/2018 6:11PM
pop ebp //ST - 12/19/2018 6:11PM
//ENDM
trans_remapref_point:
dec [ remap_counter ]
jge trans_remapinner_loop
pop edi
pop esi
add edi , [ dst_win_width ]
add esi , [ dy_intr ]
mov ebx , [ dy_acc ]
add ebx , [ dy_frac ]
jle trans_remapskip_line
add esi , [ src_win_width ]
sub ebx , [ dst_height ]
trans_remapskip_line:
dec [ counter_y ]
mov [ dy_acc ] , ebx
jnz trans_remapoutter_loop
//ret
all_done:
dest[destPos] = source[sourcePos];
}
}
}
#pragma warning (pop)
byte* Draw_Dropsample(const byte* in, int inwidth, int inheight, int outwidth, int outheight) {
int i, j, k;
const byte* inrow;
const byte* pix1;
byte* out, * out_p;
static byte ViewportPixelBuffer[4096 * 4096];
out = &ViewportPixelBuffer[0];
out_p = out;
for (i = 0; i < outheight; i++, out_p += outwidth * 1) {
inrow = in + 1 * inwidth * (int)((i + 0.25) * inheight / outheight);
for (j = 0; j < outwidth; j++) {
k = j * inwidth / outwidth;
pix1 = inrow + k * 1;
out_p[j * 1 + 0] = pix1[0];
//out_p[j * 3 + 1] = pix1[1];
//out_p[j * 3 + 2] = pix1[2];
}
}
return out;
}
BOOL __cdecl Linear_Scale_To_Linear(void *this_object, void *dest, int src_x, int src_y, int dst_x, int dst_y, int src_width, int src_height, int dst_width, int dst_height, BOOL trans, char *remap)
{
if (src_x != 0 || src_y != 0)
return false;
GraphicViewPortClass* viewportClass = (GraphicViewPortClass*)this_object;
GraphicViewPortClass* destViewportClass = (GraphicViewPortClass*)dest;
byte* viewportBuffer = ((byte*)viewportClass->Get_Graphic_Buffer()->Get_Buffer());
// Scale the GraphicViewPortClass to dest_x, dest_y
byte* scaled_buffer = Draw_Dropsample((byte *)viewportBuffer, viewportClass->Get_Width(), viewportClass->Get_Height(), dst_width, dst_height);
// Blit the scaled_buffer to dest.
Nearest_CopyImage(scaled_buffer, 0, 0, dst_width, (byte *)destViewportClass->Get_Graphic_Buffer()->Get_Buffer(), dst_x, dst_y, destViewportClass->Get_Width(), dst_width, dst_height);
return true;
}
// jmarshall end