From d5698bc9f221b4f52f291a2186830f70df2c1bd8 Mon Sep 17 00:00:00 2001 From: Justin Marshall Date: Sat, 6 Jun 2020 17:19:43 -0700 Subject: [PATCH] Linear_Scale_To_Linear ported to C --- REDALERT/WIN32LIB/DrawMisc.cpp | 801 +++------------------------------ 1 file changed, 56 insertions(+), 745 deletions(-) diff --git a/REDALERT/WIN32LIB/DrawMisc.cpp b/REDALERT/WIN32LIB/DrawMisc.cpp index a51ffd6..8ef56fa 100644 --- a/REDALERT/WIN32LIB/DrawMisc.cpp +++ b/REDALERT/WIN32LIB/DrawMisc.cpp @@ -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 +