diff --git a/code/REDALERT/CONQUER.CPP b/code/REDALERT/CONQUER.CPP index 5c81f6d..6f33e9a 100644 --- a/code/REDALERT/CONQUER.CPP +++ b/code/REDALERT/CONQUER.CPP @@ -3626,9 +3626,9 @@ void CC_Draw_Shape(void const * shapefile, int shapenum, int x, int y, WindowNum predoffset = Frame; - if (x > ( WindowList[window][WINDOWWIDTH] << 2)) { - predoffset = -predoffset; - } + //if (x > ( WindowList[window][WINDOWWIDTH] << 2)) { + // predoffset = -predoffset; + //} if (draw_window.Lock()) { if ((flags & (SHAPE_GHOST|SHAPE_FADING)) == (SHAPE_GHOST|SHAPE_FADING)) { diff --git a/code/REDALERT/GSCREEN.CPP b/code/REDALERT/GSCREEN.CPP index ee8cd9b..4ddf2a1 100644 --- a/code/REDALERT/GSCREEN.CPP +++ b/code/REDALERT/GSCREEN.CPP @@ -468,14 +468,20 @@ extern "C" { } void GScreenClass::Blit_Display(void) -{ - BStart(BENCH_BLIT_DISPLAY); - - WWMouse->Draw_Mouse(&HidPage); - HidPage.Blit(SeenBuff , 0 , 0 , 0 , 0 , HidPage.Get_Width() , HidPage.Get_Height() , (BOOL) FALSE ); - WWMouse->Erase_Mouse(&HidPage, FALSE); - - BEnd(BENCH_BLIT_DISPLAY); +{ + BEnd(BENCH_BLIT_DISPLAY); +#ifdef WIN32 + if (SeenBuff.Get_Width()!=320) { + WWMouse->Draw_Mouse(&HidPage); + //HidPage.Blit(SeenBuff , 0 , 0 , 0 , 0 , HidPage.Get_Width() , HidPage.Get_Height() , (BOOL) FALSE ); + memcpy(SeenBuff.Get_Graphic_Buffer()->GetMemoryBuffer(), HidPage.Get_Graphic_Buffer()->GetMemoryBuffer(), HidPage.Get_Width() * HidPage.Get_Height() * 4); + WWMouse->Erase_Mouse(&HidPage, FALSE); + } else { + //PG ModeX_Blit(&HiddenPage); + } + #else + Shadow_Blit(0, 0, 320, 200, HidPage, SeenPage, ShadowPage->Get_Buffer()); + #endif } diff --git a/code/REDALERT/INIT.CPP b/code/REDALERT/INIT.CPP index 90d0697..9ec0c7f 100644 --- a/code/REDALERT/INIT.CPP +++ b/code/REDALERT/INIT.CPP @@ -2532,7 +2532,9 @@ static void Init_Color_Remaps(void) GraphicBufferClass temp_page(320, 200, (void*)NULL); temp_page.Clear(); Load_Picture("PALETTE.CPS", temp_page, temp_page, NULL, BM_DEFAULT); - temp_page.Blit(HidPage); +// jmarshall + temp_page.BlitLegacy(HidPage, (BOOL)false); +// jmarshall end #else Load_Picture("PALETTE.CPS", HidPage, HidPage, NULL, BM_DEFAULT); #endif diff --git a/code/REDALERT/MPLAYER.CPP b/code/REDALERT/MPLAYER.CPP index a8d7e35..e750394 100644 --- a/code/REDALERT/MPLAYER.CPP +++ b/code/REDALERT/MPLAYER.CPP @@ -160,7 +160,7 @@ GameType Select_MPlayer_Game (void) // Initialize //------------------------------------------------------------------------ Set_Logic_Page(SeenBuff); - VisiblePage.Blit(seen_buff_save); + //VisiblePage.Blit(seen_buff_save); //------------------------------------------------------------------------ // Fill array of button ptrs diff --git a/code/REDALERT/MSGBOX.CPP b/code/REDALERT/MSGBOX.CPP index e686bec..7418406 100644 --- a/code/REDALERT/MSGBOX.CPP +++ b/code/REDALERT/MSGBOX.CPP @@ -166,7 +166,9 @@ int WWMessageBox::Process(const char * msg, const char * b1txt, const char * b2t */ Set_Logic_Page(SeenBuff); #ifdef WIN32 - VisiblePage.Blit(seen_buff_save); +// jmarshall - not needed + //VisiblePage.Blit(seen_buff_save); +// jmarshall end #endif /* diff --git a/code/REDALERT/Shape.cpp b/code/REDALERT/Shape.cpp index c97d4a6..b1a97da 100644 --- a/code/REDALERT/Shape.cpp +++ b/code/REDALERT/Shape.cpp @@ -114,20 +114,23 @@ void BF_Copy(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, i void BF_Trans(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) { - while (height--) { - for (int i = width; i > 0; --i) { - uint8_t sbyte = *src++; + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; - if (sbyte) { - *dst = sbyte; - } + if (sbyte) { + dst[0] = backbuffer_palette[(sbyte * 3) + 0]; + dst[1] = backbuffer_palette[(sbyte * 3) + 1]; + dst[2] = backbuffer_palette[(sbyte * 3) + 2]; + dst[3] = 255; + } - ++dst; - } + dst+=4; + } - src += src_pitch; - dst += dst_pitch; - } + src += src_pitch; + dst += dst_pitch * 4; + } } // Fading table based shadow and transparency @@ -166,14 +169,17 @@ void BF_Ghost_Trans(int width, int height, uint8_t* dst, uint8_t* src, int dst_p sbyte = ghost_tab[*dst + fbyte * 256]; } - *dst = sbyte; + dst[0] = backbuffer_palette[(sbyte * 3) + 0]; + dst[1] = backbuffer_palette[(sbyte * 3) + 1]; + dst[2] = backbuffer_palette[(sbyte * 3) + 2]; + dst[3] = 255; } - ++dst; + dst += 4; } src += src_pitch; - dst += dst_pitch; + dst += dst_pitch * 4; } } @@ -258,14 +264,17 @@ void BF_Ghost_Fading_Trans(int width, int height, uint8_t* dst, uint8_t* src, in sbyte = fade_tab[sbyte]; } - *dst = sbyte; + dst[0] = backbuffer_palette[(sbyte * 3) + 0]; + dst[1] = backbuffer_palette[(sbyte * 3) + 1]; + dst[2] = backbuffer_palette[(sbyte * 3) + 2]; + dst[3] = 255; } - ++dst; + dst += 4; } src += src_pitch; - dst += dst_pitch; + dst += dst_pitch * 4; } } @@ -1508,7 +1517,7 @@ long Buffer_Frame_To_Page(int x, int y, int width, int height, void* shape, Grap int blit_height = yend - ystart + 1; int pitch = viewport.Get_Full_Pitch(); - uint8_t* dst = ystart * pitch + xstart + (uint8_t*)(viewport.Get_Offset()); + uint8_t* dst = (ystart * pitch * 4) + (xstart * 4) + (uint8_t*)(viewport.Get_Offset()); uint8_t* src = frame_data + ms_img_offset; int dst_pitch = pitch - blit_width; int src_pitch = width - blit_width; @@ -1525,7 +1534,7 @@ long Buffer_Frame_To_Page(int x, int y, int width, int height, void* shape, Grap for (int i = 0; i < blit_height; ++i) { NewShapeJumpTable[line_flags[i] & 0x1F](blit_width, dst, src, ghost_lookup, ghost_table, fade_table, fade_count); src += width; - dst += pitch; + dst += pitch * 4; } return 0; diff --git a/code/REDALERT/TILESET.CPP b/code/REDALERT/TILESET.CPP index 8d2fdff..1b34281 100644 --- a/code/REDALERT/TILESET.CPP +++ b/code/REDALERT/TILESET.CPP @@ -129,7 +129,7 @@ void __cdecl Buffer_Draw_Stamp2(GraphicViewPortClass& viewport, IconControlType* 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()); + uint8_t* dst = (x * 4) + (y * 4) * fullpitch + (uint8_t*)(viewport.Get_Offset()); int32_t blitpitch = fullpitch - IconWidth; uint8_t* src = &StampPtr[IconSize * icon_index]; @@ -140,10 +140,13 @@ void __cdecl Buffer_Draw_Stamp2(GraphicViewPortClass& viewport, IconControlType* uint8_t cur_byte = remap[*src++]; if (cur_byte) { - *dst = cur_byte; + dst[0] = backbuffer_data_raw[(cur_byte * 3) + 0]; + dst[1] = backbuffer_data_raw[(cur_byte * 3) + 1]; + dst[2] = backbuffer_data_raw[(cur_byte * 3) + 2]; + dst[3] = 255; } - ++dst; + dst+=4; } dst += blitpitch; @@ -155,11 +158,14 @@ void __cdecl Buffer_Draw_Stamp2(GraphicViewPortClass& viewport, IconControlType* for (int j = 0; j < IconWidth; ++j) { uint8_t cur_byte = *src++; - if (cur_byte) { - *dst = cur_byte; - } + if (cur_byte) { + dst[0] = backbuffer_data_raw[(cur_byte * 3) + 0]; + dst[1] = backbuffer_data_raw[(cur_byte * 3) + 1]; + dst[2] = backbuffer_data_raw[(cur_byte * 3) + 2]; + dst[3] = 255; + } - ++dst; + dst += 4; } dst += blitpitch; @@ -167,9 +173,9 @@ void __cdecl Buffer_Draw_Stamp2(GraphicViewPortClass& viewport, IconControlType* } else { for (int32_t i = 0; i < IconHeight; ++i) { - memcpy(dst, src, IconWidth); + FastScanlinePaletteBlit(dst, src, IconWidth); dst += fullpitch; - src += IconWidth; + src += IconWidth * 4; } } } @@ -221,7 +227,7 @@ void __cdecl Buffer_Draw_Stamp_Clip2(GraphicViewPortClass& viewport, IconControl } 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()); + uint8_t* dst = (xstart * 4) + (ystart * 4) * full_pitch + (uint8_t*)(viewport.Get_Offset()); int dst_pitch = full_pitch - blit_width; if (remapper) { @@ -229,13 +235,16 @@ void __cdecl Buffer_Draw_Stamp_Clip2(GraphicViewPortClass& viewport, IconControl 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; - } + if (cur_byte) { + dst[0] = backbuffer_data_raw[(cur_byte * 3) + 0]; + dst[1] = backbuffer_data_raw[(cur_byte * 3) + 1]; + dst[2] = backbuffer_data_raw[(cur_byte * 3) + 2]; + dst[3] = 255; + } - ++dst; + dst += 4; } - dst += dst_pitch; + dst += dst_pitch * 4; } } @@ -243,21 +252,24 @@ void __cdecl Buffer_Draw_Stamp_Clip2(GraphicViewPortClass& viewport, IconControl 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; - } + if (cur_byte) { + dst[0] = backbuffer_data_raw[(cur_byte * 3) + 0]; + dst[1] = backbuffer_data_raw[(cur_byte * 3) + 1]; + dst[2] = backbuffer_data_raw[(cur_byte * 3) + 2]; + dst[3] = 255; + } - ++dst; + dst += 4; } src += src_pitch; - dst += dst_pitch; + dst += dst_pitch * 4; } } else { for (int i = 0; i < blit_height; ++i) { - memcpy(dst, src, blit_width); - dst += full_pitch; + FastScanlinePaletteBlit(dst, src, blit_width); + dst += full_pitch * 4; src += IconWidth; } } diff --git a/code/REDALERT/WIN32LIB/DRAWBUFF.H b/code/REDALERT/WIN32LIB/DRAWBUFF.H index f30e477..38b46d4 100644 --- a/code/REDALERT/WIN32LIB/DRAWBUFF.H +++ b/code/REDALERT/WIN32LIB/DRAWBUFF.H @@ -43,6 +43,7 @@ extern "C" { long __cdecl Buffer_To_Page(int x, int y, int w, int h, void *Buffer, void *view); BOOL __cdecl Linear_Blit_To_Linear( void *thisptr, void * dest, int x_pixel, int y_pixel, int dx_pixel, int dy_pixel, int pixel_width, int pixel_height, BOOL trans); + BOOL __cdecl Linear_Blit_To_Linear_Pal(void* this_object, void* dest, int src_x, int src_y, int dst_x, int dst_y, int w, int h, BOOL use_key); BOOL __cdecl Linear_Scale_To_Linear( void *, void *, int, int, int, int, int, int, int, int, BOOL, char *); LONG __cdecl Buffer_Print(void *thisptr, const char *str, int x, int y, int fcolor, int bcolor); diff --git a/code/REDALERT/WIN32LIB/DrawMisc.cpp b/code/REDALERT/WIN32LIB/DrawMisc.cpp index 49f00bd..15382d1 100644 --- a/code/REDALERT/WIN32LIB/DrawMisc.cpp +++ b/code/REDALERT/WIN32LIB/DrawMisc.cpp @@ -1054,231 +1054,34 @@ CODESEG #define OPTIMAL_BYTE_COPY 14 -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 x, int y, int w, int h, unsigned char color) { -/* - ;*=================================================================== - ;* define the arguements that our function takes. - ;*=================================================================== - ARG this_object:DWORD ; this is a member function - ARG x1_pixel:WORD - ARG y1_pixel:WORD - ARG x2_pixel:WORD - ARG y2_pixel:WORD - ARG color:BYTE ; what color should we clear to -*/ - - void *this_object = thisptr; - int x1_pixel = sx; - int y1_pixel = sy; - int x2_pixel = dx; - int y2_pixel = dy; - -/* - ;*=================================================================== - ; Define some locals so that we can handle things quickly - ;*=================================================================== - LOCAL VPwidth:DWORD ; the width of the viewport - LOCAL VPheight:DWORD ; the height of the viewport - LOCAL VPxadd:DWORD ; the additional x offset of viewport - LOCAL VPbpr:DWORD ; the number of bytes per row of viewport -*/ + GraphicViewPortClass& vp = (*(GraphicViewPortClass *)thisptr); - int VPwidth; - int VPheight; - int VPxadd; - int VPbpr; + // If we aren't drawing within the viewport, return + if (x >= vp.Get_Width() || y >= vp.Get_Height() || w < 0 || h < 0) { + return; + } - int local_ebp; // Can't use ebp + // Clipping + if (x < 0) { + x = 0; + } - __asm { + if (y < 0) { + y = 0; + } - ;*=================================================================== - ;* save off the viewport characteristics on the stack - ;*=================================================================== - mov ebx,[this_object] ; get a pointer to viewport - mov eax,[ebx]GraphicViewPortClass.Width ; get width from viewport - mov ecx,[ebx]GraphicViewPortClass.Height ; get height from viewport - mov edx,[ebx]GraphicViewPortClass.XAdd ; get xadd from viewport - add edx,[ebx]GraphicViewPortClass.Pitch ; extra pitch of direct draw surface - mov [VPwidth],eax ; store the width of locally - mov [VPheight],ecx - mov [VPxadd],edx - add eax,edx - mov [VPbpr],eax + w = min(w, vp.Get_Width() - 1); + h = min(h, vp.Get_Height() - 1); - ;*=================================================================== - ;* move the important parameters into local registers - ;*=================================================================== - mov eax,[x1_pixel] - mov ebx,[y1_pixel] - mov ecx,[x2_pixel] - mov edx,[y2_pixel] + uint8_t* offset = (y * 4) * vp.Get_Full_Pitch() + (x * 4) + (uint8_t*)(vp.Get_Offset()); + int height = h - y + 1; + int width = w - x + 1; - ;*=================================================================== - ;* Convert the x2 and y2 pixel to a width and height - ;*=================================================================== - cmp eax,ecx - jl no_swap_x - xchg eax,ecx - - no_swap_x: - sub ecx,eax - cmp ebx,edx - jl no_swap_y - xchg ebx,edx - no_swap_y: - sub edx,ebx - inc ecx - inc edx - - ;*=================================================================== - ;* Bounds check source X. - ;*=================================================================== - cmp eax, [VPwidth] ; compare with the max - jge done ; starts off screen, then later - jb short sx_done ; if it's not negative, it's ok - - ;------ Clip source X to left edge of screen. - add ecx, eax ; Reduce width (add in negative src X). - xor eax, eax ; Clip to left of screen. - sx_done: - - ;*=================================================================== - ;* Bounds check source Y. - ;*=================================================================== - cmp ebx, [VPheight] ; compare with the max - jge done ; starts off screen, then later - jb short sy_done ; if it's not negative, it's ok - - ;------ Clip source Y to top edge of screen. - add edx, ebx ; Reduce height (add in negative src Y). - xor ebx, ebx ; Clip to top of screen. - - sy_done: - ;*=================================================================== - ;* Bounds check width versus width of source and dest view ports - ;*=================================================================== - push ebx ; save off ebx for later use - mov ebx,[VPwidth] ; get the source width - sub ebx, eax ; Maximum allowed pixel width (given coordinates). - sub ebx, ecx ; Pixel width undershoot. - jns short width_ok ; if not signed no adjustment necessary - add ecx, ebx ; Reduce width to screen limits. - - width_ok: - pop ebx ; restore ebx to old value - - ;*=================================================================== - ;* Bounds check height versus height of source view port - ;*=================================================================== - push eax ; save of eax for later use - mov eax, [VPheight] ; get the source height - sub eax, ebx ; Maximum allowed pixel height (given coordinates). - sub eax, edx ; Pixel height undershoot. - jns short height_ok ; if not signed no adjustment necessary - add edx, eax ; Reduce height to screen limits. - height_ok: - pop eax ; restore eax to old value - - ;*=================================================================== - ;* Perform the last minute checks on the width and height - ;*=================================================================== - or ecx,ecx - jz done - - or edx,edx - jz done - - cmp ecx,[VPwidth] - ja done - cmp edx,[VPheight] - ja done - - ;*=================================================================== - ;* Get the offset into the virtual viewport. - ;*=================================================================== - xchg edi,eax ; save off the contents of eax - xchg esi,edx ; and edx for size test - mov eax,ebx ; move the y pixel into eax - mul [VPbpr] ; multiply by bytes per row - add edi,eax ; add the result into the x position - mov ebx,[this_object] - add edi,[ebx]GraphicViewPortClass.Offset - - mov edx,esi ; restore edx back to real value - mov eax,ecx ; store total width in ecx - sub eax,[VPwidth] ; modify xadd value to include clipped - sub [VPxadd],eax ; width bytes (subtract a negative number) - - ;*=================================================================== - ; Convert the color byte to a DWORD for fast storing - ;*=================================================================== - mov al,[color] ; get color to clear to - mov ah,al ; extend across WORD - mov ebx,eax ; extend across DWORD in - shl eax,16 ; several steps - mov ax,bx - - ;*=================================================================== - ; If there is no row offset then adjust the width to be the size of - ; the entire viewport and adjust the height to be 1 - ;*=================================================================== - mov esi,[VPxadd] - or esi,esi ; set the flags for esi - jnz row_by_row_aligned ; and act on them - - xchg eax,ecx ; switch bit pattern and width - mul edx ; multiply by edx to get size - xchg eax,ecx ; switch size and bit pattern - mov edx,1 ; only 1 line off view port size to do - - ;*=================================================================== - ; Find out if we should bother to align the row. - ;*=================================================================== - row_by_row_aligned: - mov [local_ebp],ecx ; width saved in ebp - cmp ecx,OPTIMAL_BYTE_COPY ; is it worth aligning them? - jl row_by_row ; if not then skip - - ;*=================================================================== - ; Figure out the alignment offset if there is any - ;*=================================================================== - mov ebx,edi ; get output position - and ebx,3 ; is there a remainder? - jz aligned_loop ; if not we are aligned - xor ebx,3 ; find number of align bytes - inc ebx ; this number is off by one - sub [local_ebp],ebx ; subtract from width - - ;*=================================================================== - ; Now that we have the alignment offset copy each row - ;*=================================================================== - aligned_loop: - mov ecx,ebx ; get number of bytes to align - rep stosb ; and move them over - mov ecx,[local_ebp] ; get number of aligned bytes - shr ecx,2 ; convert to DWORDS - rep stosd ; and move them over - mov ecx,[local_ebp] ; get number of aligned bytes - and ecx,3 ; find the remainder - rep stosb ; and move it over - add edi,esi ; fix the line offset - dec edx ; decrement the height - jnz aligned_loop ; if more to do than do it - jmp done ; we are all done - - ;*=================================================================== - ; If not enough bytes to bother aligning copy each line across a byte - ; at a time. - ;*=================================================================== - row_by_row: - mov ecx,[local_ebp] ; get total width in bytes - rep stosb ; store the width - add edi,esi ; handle the xadd - dec edx ; decrement the height - jnz row_by_row ; if any left then next line - done: + for (int i = 0; i < height; ++i) { + FastScanlinePaletteBlit(offset, color, width); + offset += vp.Get_Full_Pitch() * 4; } } @@ -1493,6 +1296,86 @@ BOOL __cdecl Linear_Blit_To_Linear(void* this_object, void* dest, int src_x, int GraphicViewPortClass& src_vp = *(GraphicViewPortClass *)this_object; GraphicViewPortClass& dst_vp = *(GraphicViewPortClass*)dest; + uint8_t* src = (uint8_t*)(src_vp.Get_Offset()); + uint8_t* dst = (uint8_t*)(dst_vp.Get_Offset()); + int src_pitch = src_vp.Get_Full_Pitch(); + int dst_pitch = dst_vp.Get_Full_Pitch() * 4; + + if (src_x >= src_vp.Get_Width() || src_y >= src_vp.Get_Height() || dst_x >= dst_vp.Get_Width() + || dst_y >= dst_vp.Get_Height() || h < 0 || w < 1) { + return 0; + } + + src_x = max(0, src_x); + src_y = max(0, src_y); + dst_x = max(0, dst_x); + dst_y = max(0, dst_y); + + h = (dst_y + h) > dst_vp.Get_Height() ? dst_vp.Get_Height() - 1 - dst_y : h; + w = (dst_x + w) > dst_vp.Get_Width() ? dst_vp.Get_Width() - 1 - dst_x : w; + + // move our pointers to the start locations + src += src_x + src_y * src_pitch; + dst += dst_x + dst_y * dst_pitch; + + // If src is before dst, we run the risk of overlapping memory regions so we + // need to move src and dst to the last line and work backwards + if (src < dst) { + uint8_t* esrc = src + (h - 1) * src_pitch; + uint8_t* edst = dst + (h - 1) * dst_pitch; + if (use_key) { + char key_colour = 0; + while (h-- != 0) { + // Can't optimize as we need to check every pixel against key colour :( + for (int i = w - 1; i >= 0; --i) { + if (esrc[i] != key_colour) { + edst[i] = esrc[i]; + } + } + + edst -= dst_pitch; + esrc -= src_pitch; + } + } + else { + while (h-- != 0) { + FastScanlinePaletteBlit(edst, esrc, w); + edst -= dst_pitch; + esrc -= src_pitch; + } + } + } + else { + if (use_key) { + uint8_t key_colour = 0; + while (h-- != 0) { + // Can't optimize as we need to check every pixel against key colour :( + for (int i = 0; i < w; ++i) { + if (src[i] != key_colour) { + dst[i] = src[i]; + } + } + + dst += dst_pitch; + src += src_pitch; + } + } + else { + while (h-- != 0) { + FastScanlinePaletteBlit(dst, src, w); + dst += dst_pitch; + src += src_pitch; + } + } + } + return true; +} + +BOOL __cdecl Linear_Blit_To_Linear_Pal(void* this_object, void* dest, int src_x, int src_y, int dst_x, int dst_y, int w, int h, BOOL use_key) +{ + GraphicViewPortClass& src_vp = *(GraphicViewPortClass*)this_object; + GraphicViewPortClass& dst_vp = *(GraphicViewPortClass*)dest; + uint8_t* src = (uint8_t*)(src_vp.Get_Offset()); uint8_t* dst = (uint8_t*)(dst_vp.Get_Offset()); int src_pitch = src_vp.Get_Full_Pitch(); @@ -3651,7 +3534,7 @@ extern "C" long __cdecl Buffer_To_Page(int x, int y, int w, int h, void *buffer, int pitch = vp.Get_Pitch() + vp.Get_Width() + vp.Get_XAdd(); uint8_t* dst = y * pitch + x + (uint8_t*)(vp.Get_Offset()); - uint8_t* src = xoffset + w * yoffset + static_cast(buffer); + uint8_t* src = (xoffset * 4) + w * (yoffset * 4) + static_cast(buffer); // int dst_pitch = x_pos + pitch - xend; // int src_pitch = x_pos + width - xend; int lines = yend - ystart + 1; @@ -3659,9 +3542,9 @@ extern "C" long __cdecl Buffer_To_Page(int x, int y, int w, int h, void *buffer, // blit while (lines--) { - memcpy(dst, src, blit_width); + FastScanlinePaletteBlit(dst, src, blit_width); src += w; - dst += pitch; + dst += pitch * 4; } return 0; diff --git a/code/REDALERT/WIN32LIB/GBUFFER.CPP b/code/REDALERT/WIN32LIB/GBUFFER.CPP index 946545d..19d7cf8 100644 --- a/code/REDALERT/WIN32LIB/GBUFFER.CPP +++ b/code/REDALERT/WIN32LIB/GBUFFER.CPP @@ -172,7 +172,7 @@ void GraphicViewPortClass::Attach(GraphicBufferClass *gbuffer, int x, int y, int /*======================================================================*/ /* Get a pointer to the top left edge of the buffer. */ /*======================================================================*/ - Offset = gbuffer->Get_Offset() + ((gbuffer->Get_Width()+gbuffer->Get_Pitch()) * y) + x; + Offset = gbuffer->Get_Offset() + ((gbuffer->Get_Width()+gbuffer->Get_Pitch()) * y * 4) + (x * 4); /*======================================================================*/ /* Copy over all of the variables that we need to store. */ @@ -237,7 +237,7 @@ BOOL GraphicViewPortClass::Change(int x, int y, int w, int h) *=========================================================================*/ void GraphicBufferClass::DD_Init(GBC_Enum flags) { - rawCpuBuffer = new unsigned char[Width * Height]; + rawCpuBuffer = new unsigned char[Width * Height * 4]; Allocated = FALSE; // even if system alloced, dont flag it cuz // we dont want it freed. @@ -280,7 +280,7 @@ void GraphicBufferClass::Init(int w, int h, void *buffer, long size, GBC_Enum fl Buffer= (BYTE *)buffer; // point to it and mark Allocated = FALSE; // it as user allocated } else { - if (!Size) Size = w*h; + if (!Size) Size = w*h*4; Buffer = new BYTE[Size]; // otherwise allocate it and Allocated = TRUE; // mark it system alloced } diff --git a/code/REDALERT/WIN32LIB/GBUFFER.H b/code/REDALERT/WIN32LIB/GBUFFER.H index 3f8b3c1..3bdf860 100644 --- a/code/REDALERT/WIN32LIB/GBUFFER.H +++ b/code/REDALERT/WIN32LIB/GBUFFER.H @@ -138,7 +138,31 @@ #include "iconcach.h" #include "../NEWBLIT.H" +#include + extern unsigned char* backbuffer_data_raw; +extern unsigned char backbuffer_palette[768]; +__forceinline void FastScanlinePaletteBlit(uint8_t* dst, uint8_t* src, int length) { + for (int i = 0; i < length; i++) { + uint8_t color = src[i]; + if (color == 0) + continue; + + dst[(i * 4) + 0] = backbuffer_palette[(color * 3) + 0]; + dst[(i * 4) + 1] = backbuffer_palette[(color * 3) + 1]; + dst[(i * 4) + 2] = backbuffer_palette[(color * 3) + 2]; + dst[(i * 4) + 3] = 255; + } +} + +__forceinline void FastScanlinePaletteBlit(uint8_t* dst, uint8_t color, int length) { + for (int i = 0; i < length; i++) { + dst[(i * 4) + 0] = backbuffer_palette[(color * 3) + 0]; + dst[(i * 4) + 1] = backbuffer_palette[(color * 3) + 1]; + dst[(i * 4) + 2] = backbuffer_palette[(color * 3) + 2]; + dst[(i * 4) + 3] = 255; + } +} #ifndef FUNCTION_H //#pragma off (unreferenced) @@ -268,6 +292,7 @@ class GraphicViewPortClass { int dy_pixel, int pixel_width, int pixel_height, BOOL trans = FALSE); HRESULT Blit( GraphicViewPortClass& dest, int dx, int dy, BOOL trans = FALSE); HRESULT Blit( GraphicViewPortClass& dest, BOOL trans = FALSE); + HRESULT BlitLegacy(GraphicViewPortClass& dest, BOOL trans = FALSE); HRESULT Blit( VideoViewPortClass& dest, int x_pixel, int y_pixel, int dx_pixel, int dy_pixel, int pixel_width, int pixel_height, BOOL trans = FALSE); HRESULT Blit( VideoViewPortClass& dest, int dx, int dy, BOOL trans = FALSE); @@ -796,6 +821,40 @@ inline HRESULT GraphicViewPortClass::Blit( GraphicViewPortClass& dest, int dx, i } +/*************************************************************************** + * GVPC::BLIT -- stub 3 to call curr graphic mode Blit to GVPC * + * * + * INPUT: * + * * + * OUTPUT: * + * * + * WARNINGS: * + * * + * HISTORY: * + * 01/06/1995 PWG : Created. * + *=========================================================================*/ +inline HRESULT GraphicViewPortClass::BlitLegacy(GraphicViewPortClass& dest, BOOL trans) +{ + HRESULT return_code = 0; + + + if (Lock()) { + if (dest.Lock()) { + + return_code = (Linear_Blit_To_Linear_Pal(this, &dest, 0, 0 + , 0, 0 + , Width, Height, trans)); + + } + dest.Unlock(); + } + Unlock(); + + return (return_code); + +} + + /*************************************************************************** * GVPC::BLIT -- stub 3 to call curr graphic mode Blit to GVPC * * * @@ -810,7 +869,7 @@ inline HRESULT GraphicViewPortClass::Blit( GraphicViewPortClass& dest, int dx, i *=========================================================================*/ inline HRESULT GraphicViewPortClass::Blit( GraphicViewPortClass& dest, BOOL trans) { - HRESULT return_code=0; + HRESULT return_code = 0; if (Lock()) { diff --git a/code/REDALERT/WINSTUB.CPP b/code/REDALERT/WINSTUB.CPP index 5ff2587..0051c54 100644 --- a/code/REDALERT/WINSTUB.CPP +++ b/code/REDALERT/WINSTUB.CPP @@ -64,7 +64,7 @@ #include GLuint backbuffer_texture = -1; -byte* backbuffer_data; +//byte* backbuffer_data; unsigned char* backbuffer_data_raw; byte backbuffer_palette[768]; HWND MainWindow; @@ -83,7 +83,7 @@ void (*Imgui_Dialog_Function)(void) = nullptr; bool show_oldframebuffer = true; void Show_OldFrameBuffer(bool show) { show_oldframebuffer = show; - memset(backbuffer_data, 0, ScreenWidth * ScreenHeight * 4); + memset(backbuffer_data_raw, 0, ScreenWidth * ScreenHeight * 4); } std::vector loaded_images; @@ -185,14 +185,14 @@ void ImGui_NewFrame(void) { void Device_Present(void) { // Rasterize the palette. - for (int i = 0; i < ScreenWidth * ScreenHeight; i++) { - backbuffer_data[(i * 4) + 0] = backbuffer_palette[(backbuffer_data_raw[i] * 3) + 0]; - backbuffer_data[(i * 4) + 1] = backbuffer_palette[(backbuffer_data_raw[i] * 3) + 1]; - backbuffer_data[(i * 4) + 2] = backbuffer_palette[(backbuffer_data_raw[i] * 3) + 2]; - backbuffer_data[(i * 4) + 3] = 255; - } + //for (int i = 0; i < ScreenWidth * ScreenHeight; i++) { + // backbuffer_data[(i * 4) + 0] = backbuffer_palette[(backbuffer_data_raw[i] * 3) + 0]; + // backbuffer_data[(i * 4) + 1] = backbuffer_palette[(backbuffer_data_raw[i] * 3) + 1]; + // backbuffer_data[(i * 4) + 2] = backbuffer_palette[(backbuffer_data_raw[i] * 3) + 2]; + // backbuffer_data[(i * 4) + 3] = 255; + //} glBindTexture(GL_TEXTURE_2D, backbuffer_texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ScreenWidth, ScreenHeight, GL_RGBA, GL_UNSIGNED_BYTE, backbuffer_data); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ScreenWidth, ScreenHeight, GL_RGBA, GL_UNSIGNED_BYTE, backbuffer_data_raw); bool ScreenActive; ImGuiStyle& style = ImGui::GetStyle(); @@ -422,15 +422,13 @@ void Create_Main_Window ( HANDLE instance , int command_show , int width , int h glGenTextures(1, &backbuffer_texture); glBindTexture(GL_TEXTURE_2D, backbuffer_texture); + // Give the image to OpenGL + backbuffer_data_raw = new byte[width * height * 4]; + memset(backbuffer_data_raw, 0, width * height * 4); - // Give the image to OpenGL - backbuffer_data = new byte[width * height * 4]; - memset(backbuffer_data, 0, width * height * 4); - backbuffer_data_raw = new byte[width * height]; - memset(backbuffer_data_raw, 0, width * height); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, backbuffer_data); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, backbuffer_data_raw); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glewInit();