From 9183814eb85b034d618e5fbabeb3e29fcadaa8ed Mon Sep 17 00:00:00 2001 From: Justin Marshall Date: Tue, 16 Jun 2020 15:39:32 -0700 Subject: [PATCH] Fixed a bug were TemplateTypeClass::Display was displaying incorrect pixels. Enabling the editor no longer shows the system cursor. Placement_Editor now renders correctly again. Linear_Blit_Linear and Linear_Scale_To_Linear now work with 32bit images. --- code/REDALERT/CDATA.CPP | 3 +- code/REDALERT/CONQUER.CPP | 4 +- code/REDALERT/KEY.CPP | 6 +- code/REDALERT/KEY.H | 4 +- code/REDALERT/MAPEDPLC.CPP | 9 +- code/REDALERT/Shape.cpp | 2 +- code/REDALERT/WIN32LIB/DrawMisc.cpp | 313 +++++++++------------------- code/REDALERT/WINSTUB.CPP | 8 +- 8 files changed, 118 insertions(+), 231 deletions(-) diff --git a/code/REDALERT/CDATA.CPP b/code/REDALERT/CDATA.CPP index 572246a..02e12b5 100644 --- a/code/REDALERT/CDATA.CPP +++ b/code/REDALERT/CDATA.CPP @@ -3184,8 +3184,8 @@ void TemplateTypeClass::Display(int x, int y, WindowNumberType window, HousesTyp for (index = 0; index < w*h; index++) { if (map[index] != 0xFF) { HidPage.Draw_Stamp(iconset, index, 0, 0, NULL, WINDOW_MAIN); + Buffer_Enable_HD_Texture(true); // At this point, Draw_Stamp creates a 32bit image. if (scale) { - HidPage.Scale((*LogicPage), 0, 0, x + ((index % w)*(ICON_PIXEL_W/2)), y + ((index / w)*(ICON_PIXEL_H/2)), @@ -3196,6 +3196,7 @@ void TemplateTypeClass::Display(int x, int y, WindowNumberType window, HousesTyp HidPage.Blit((*LogicPage), 0, 0, x + ((index % w)*(ICON_PIXEL_W)), y + ((index / w)*(ICON_PIXEL_H)), ICON_PIXEL_W, ICON_PIXEL_H); } + Buffer_Enable_HD_Texture(false); } } } diff --git a/code/REDALERT/CONQUER.CPP b/code/REDALERT/CONQUER.CPP index fccd6cf..f8aaa77 100644 --- a/code/REDALERT/CONQUER.CPP +++ b/code/REDALERT/CONQUER.CPP @@ -2547,7 +2547,7 @@ void Go_Editor(bool flag) if (flag) { AudMix_SetMusicState(false); // jmarshall: disable music if we are in editor mode Hide_Mouse(); - ShowCursor(TRUE); + //ShowCursor(TRUE); Debug_Map = true; Debug_Unshroud = true; @@ -2580,7 +2580,7 @@ void Go_Editor(bool flag) } else { AudMix_SetMusicState(true); // jmarshall: enable music if we are going back into editor mode. Show_Mouse(); - ShowCursor(FALSE); + //ShowCursor(FALSE); /* ** Go into normal game mode diff --git a/code/REDALERT/KEY.CPP b/code/REDALERT/KEY.CPP index 3603b12..1d96f9d 100644 --- a/code/REDALERT/KEY.CPP +++ b/code/REDALERT/KEY.CPP @@ -62,6 +62,8 @@ #define ARRAY_SIZE(x) int(sizeof(x)/sizeof(x[0])) +int WWKeyboardClass::Head = 0; +int WWKeyboardClass::Tail = 0; /*********************************************************************************************** * WWKeyboardClass::WWKeyBoardClass -- Construction for Westwood Keyboard Class * @@ -75,9 +77,7 @@ *=============================================================================================*/ WWKeyboardClass::WWKeyboardClass(void) : MouseQX(0), - MouseQY(0), - Head(0), - Tail(0) + MouseQY(0) { // _Kbd = this; diff --git a/code/REDALERT/KEY.H b/code/REDALERT/KEY.H index fbaec2c..67f4cef 100644 --- a/code/REDALERT/KEY.H +++ b/code/REDALERT/KEY.H @@ -117,8 +117,8 @@ class WWKeyboardClass ** These are the tracking pointers to maintain the ** circular keyboard list. */ - int Head; - int Tail; + static int Head; + static int Tail; }; #define RA_SCANCODE_MASK (1<<30) diff --git a/code/REDALERT/MAPEDPLC.CPP b/code/REDALERT/MAPEDPLC.CPP index ab9d0f1..4f072a2 100644 --- a/code/REDALERT/MAPEDPLC.CPP +++ b/code/REDALERT/MAPEDPLC.CPP @@ -428,14 +428,17 @@ int MapEditClass::Placement_Dialog(void) /* ** Refresh display if needed */ - if (display) { + //if (display) { /* ** Display the dialog box */ Hide_Mouse(); - Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); + // Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); // Draw_Caption(TXT_PLACE_OBJECT, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); +// jmarshall - temp render a black background here so the tool works. + LogicPage->Fill_Rect(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_X + D_DIALOG_W, D_DIALOG_Y + D_DIALOG_H, 0); +// jamrshall end /* ** Display the current object: @@ -560,7 +563,7 @@ int MapEditClass::Placement_Dialog(void) Show_Mouse(); display = false; - } + // } display = true; diff --git a/code/REDALERT/Shape.cpp b/code/REDALERT/Shape.cpp index cd2f736..0cfd6c2 100644 --- a/code/REDALERT/Shape.cpp +++ b/code/REDALERT/Shape.cpp @@ -101,7 +101,7 @@ static uint8_t* g_PredatorLimit = nullptr; typedef void (*BF_Function)(int, int, uint8_t*, uint8_t*, int, int, uint8_t*, uint8_t*, uint8_t*, int); typedef void (*Single_Line_Function)(int, uint8_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*, int); -static bool renderHDTexture = false; +bool renderHDTexture = false; void Buffer_Enable_HD_Texture(bool hdTextureEnabled) { renderHDTexture = hdTextureEnabled; } diff --git a/code/REDALERT/WIN32LIB/DrawMisc.cpp b/code/REDALERT/WIN32LIB/DrawMisc.cpp index 1cd467c..6a6c0fd 100644 --- a/code/REDALERT/WIN32LIB/DrawMisc.cpp +++ b/code/REDALERT/WIN32LIB/DrawMisc.cpp @@ -79,7 +79,7 @@ extern "C" int __cdecl Get_Free_Cache_Slot(void) {return -1;} void IconCacheClass::Draw_It (void *dest_surface , int x_pixel, int y_pixel, int window_left , int window_top , int window_width , int window_height) {} - +extern bool renderHDTexture; extern int CachedIconsDrawn; extern int UnCachedIconsDrawn; @@ -1131,22 +1131,37 @@ void __cdecl Buffer_Clear(void *this_object, unsigned char color) */ // jmarshall - ported to c + + unsigned char* Draw_Dropsample(const unsigned char* in, int inwidth, int inheight, int outwidth, int outheight) { int i, j, k; const unsigned char* inrow; const unsigned char* pix1; unsigned char* out, * out_p; - static unsigned char ViewportPixelBuffer[4096 * 4096]; + static unsigned char ViewportPixelBuffer[4096 * 4096 * 4]; 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); + int bpp = 1; + if (renderHDTexture) { + bpp = 4; + } + + for (i = 0; i < outheight; i++, out_p += outwidth * bpp) { + inrow = in + bpp * 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]; + pix1 = inrow + k * bpp; + if (renderHDTexture) { + out_p[j * 4 + 0] = pix1[0]; + out_p[j * 4 + 1] = pix1[1]; + out_p[j * 4 + 2] = pix1[2]; + out_p[j * 4 + 3] = pix1[3]; + } + else { + out_p[j * 1 + 0] = pix1[0]; + } //out_p[j * 3 + 1] = pix1[1]; //out_p[j * 3 + 2] = pix1[2]; } @@ -1155,237 +1170,105 @@ unsigned char* Draw_Dropsample(const unsigned char* in, int inwidth, int inheigh 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_w, int src_h, int dst_w, int dst_h, BOOL use_keysrc, char* fade) + +/* +============== +R_CopyImage +============== +*/ +void Nearest_CopyImage(unsigned char* source, int sourceX, int sourceY, int sourceWidth, unsigned char* dest, int destX, int destY, int destWidth, int width, int height, BOOL trans) { - GraphicViewPortClass& src_vp = *(GraphicViewPortClass*)this_object; - GraphicViewPortClass& dst_vp = *(GraphicViewPortClass*)dest; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { - // If there is nothing to scale, just return. - if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0) { - return false; - } + int destPos = ((destWidth * (y + destY)) * 4) + ((x + destX) * 4); + int sourcePos = (sourceWidth * (y + (sourceY))) + (x + (sourceX)); + if (renderHDTexture) { + sourcePos = ((sourceWidth * (y + sourceY)) * 4) + ((x + sourceX) * 4); - int sx = src_x; - int sy = src_y; - int dx = dst_x; - int dy = dst_y; - int dw = dst_w + dst_x; - int dh = dst_h + dst_y; + // This needs some work! + if (source[0] == 0 && source[1] == 0 && source[2] == 0 && trans) + continue; - // These ifs are all for clipping purposes incase coords are outside - // the expected area. - if (src_x < 0) { - sx = 0; - dx = dst_x + ((dst_w * -src_x) / src_w); - } - - if (src_y < 0) { - sy = 0; - dy = dst_y + ((dst_h * -src_y) / src_h); - } - - if (src_x + src_w > src_vp.Get_Width() + 1) { - dw = dst_x + (dst_w * (src_vp.Get_Width() - src_x) / src_w); - } - - if (src_y + src_h > src_vp.Get_Height() + 1) { - dh = dst_y + (dst_h * (src_vp.Get_Height() - src_y) / src_h); - } - - if (dx < 0) { - dx = 0; - sx = src_x + ((src_w * -dst_x) / dst_w); - } - - if (dy < 0) { - dy = 0; - sy = src_y + ((src_h * -dst_y) / dst_h); - } - - if (dw > dst_vp.Get_Width() + 1) { - dw = dst_vp.Get_Width(); - } - - if (dh > dst_vp.Get_Height() + 1) { - dh = dst_vp.Get_Height(); - } - - if (dy > dh || dx > dw) { - return false; - } - - uint8_t* src = (sy) * src_vp.Get_Full_Pitch() + (sx) + (uint8_t*)(src_vp.Get_Offset()); - uint8_t* dst = (dy * 4) * dst_vp.Get_Full_Pitch() + (dx * 4) + (uint8_t*)(dst_vp.Get_Offset()); - dw -= dx; - dh -= dy; - int x_ratio = ((src_w << 16) / dw) + 1; - int y_ratio = ((src_h << 16) / dh) + 1; - - // keysrc basically means do we skip index 0 entries, thus treating them as - // transparent? - if (use_keysrc) { - if (fade != nullptr) { - for (int i = 0; i < dh; ++i) { - uint8_t* d = dst + (i * 4) * dst_vp.Get_Full_Pitch(); - uint8_t* s = src + ((i * y_ratio) >> 16) * src_vp.Get_Full_Pitch(); - int xrat = 0; - - for (int j = 0; j < dw; ++j) { - uint8_t tmp = s[xrat >> 16]; - - if (tmp != 0) { - uint8_t color = ((uint8_t*)(fade))[tmp]; - d[0] = backbuffer_palette[(color * 3) + 0]; - d[1] = backbuffer_palette[(color * 3) + 1]; - d[2] = backbuffer_palette[(color * 3) + 2]; - d[3] = 255; - } - - d+=4; - xrat += x_ratio; - } + dest[destPos + 0] = source[sourcePos + 0]; + dest[destPos + 1] = source[sourcePos + 1]; + dest[destPos + 2] = source[sourcePos + 2]; + dest[destPos + 3] = 255; } - } - else { - for (int i = 0; i < dh; ++i) { - uint8_t* d = dst + (i * 4) * dst_vp.Get_Full_Pitch(); - uint8_t* s = src + ((i * y_ratio) >> 16) * src_vp.Get_Full_Pitch(); - int xrat = 0; + else + { + unsigned char c = source[sourcePos]; - for (int j = 0; j < dw; ++j) { - uint8_t tmp = s[xrat >> 16]; - - if (tmp != 0) { - uint8_t color = tmp; - d[0] = backbuffer_palette[(color * 3) + 0]; - d[1] = backbuffer_palette[(color * 3) + 1]; - d[2] = backbuffer_palette[(color * 3) + 2]; - d[3] = 255; - } - - d += 4; - xrat += x_ratio; + if (c == 0 && trans) { + continue; } + + dest[destPos + 0] = backbuffer_palette[(c * 3) + 0]; + dest[destPos + 1] = backbuffer_palette[(c * 3) + 1]; + dest[destPos + 2] = backbuffer_palette[(c * 3) + 2]; + dest[destPos + 3] = 255; } } } - else { - if (fade != nullptr) { - for (int i = 0; i < dh; ++i) { - uint8_t* d = dst + (i * 4) * dst_vp.Get_Full_Pitch(); - uint8_t* s = src + ((i * y_ratio) >> 16) * src_vp.Get_Full_Pitch(); - int xrat = 0; +} - for (int j = 0; j < dw; ++j) { - uint8_t color = ((uint8_t*)(fade))[s[xrat >> 16]]; - d[0] = backbuffer_palette[(color * 3) + 0]; - d[1] = backbuffer_palette[(color * 3) + 1]; - d[2] = backbuffer_palette[(color * 3) + 2]; - d[3] = 255; - d += 4; - xrat += x_ratio; - } - } - } - else { - for (int i = 0; i < dh; ++i) { - uint8_t* d = dst + (i * 4) * dst_vp.Get_Full_Pitch(); - uint8_t* s = src + ((i * y_ratio) >> 16) * src_vp.Get_Full_Pitch(); - int xrat = 0; - for (int j = 0; j < dw; ++j) { - uint8_t color = s[xrat >> 16]; - d[0] = backbuffer_palette[(color * 3) + 0]; - d[1] = backbuffer_palette[(color * 3) + 1]; - d[2] = backbuffer_palette[(color * 3) + 2]; - d[3] = 255; - d += 4; - xrat += x_ratio; - } - } - } - } +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) +{ + GraphicViewPortClass* viewportClass = (GraphicViewPortClass*)this_object; + GraphicViewPortClass* destViewportClass = (GraphicViewPortClass*)dest; + + unsigned char* viewportBuffer = ((unsigned char*)viewportClass->Get_Offset()); + + // Scale the GraphicViewPortClass to dest_x, dest_y + unsigned char* scaled_buffer = Draw_Dropsample((unsigned char*)viewportBuffer, viewportClass->Get_Width(), viewportClass->Get_Height(), dst_width, dst_height); + + // Blit the scaled_buffer to dest. + Nearest_CopyImage(scaled_buffer, src_x, src_y, dst_width, (unsigned char*)destViewportClass->Get_Offset(), dst_x, dst_y, destViewportClass->Get_Width(), dst_width, dst_height, trans); return true; } -BOOL __cdecl Linear_Blit_To_Linear(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_Blit_To_Linear(void* this_object, void* dest, int x_pixel, int y_pixel, int dest_x0, int dest_y0, int pixel_width, int pixel_height, BOOL trans) { - GraphicViewPortClass& src_vp = *(GraphicViewPortClass *)this_object; - GraphicViewPortClass& dst_vp = *(GraphicViewPortClass*)dest; + GraphicViewPortClass* viewportClass = (GraphicViewPortClass*)this_object; + GraphicViewPortClass* destViewportClass = (GraphicViewPortClass*)dest; + bool needsUnlock = false; + bool sourceNeedsUnlock = false; - 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; + unsigned char* viewportBuffer = NULL; + viewportBuffer = ((unsigned char*)viewportClass->Get_Offset()); - 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; - } + unsigned char* destBuffer = NULL; + destBuffer = ((unsigned char*)destViewportClass->Get_Offset()); - src_x = max(0, src_x); - src_y = max(0, src_y); - dst_x = max(0, dst_x); - dst_y = max(0, dst_y); + //if (destViewportClass->Get_Graphic_Buffer()->Get_Buffer() != NULL) { + // destBuffer = (byte*)destViewportClass->Get_Graphic_Buffer()->Get_Buffer(); + //} + //else { + // destViewportClass->Get_Graphic_Buffer()->Lock(); + // destBuffer = ((byte*)destViewportClass->Get_Graphic_Buffer()->GetMemoryBuffer()); + // needsUnlock = true; + //} + // + //if (viewportBuffer == NULL) { + // viewportClass->Get_Graphic_Buffer()->Lock(); + // viewportBuffer = ((byte*)viewportClass->Get_Graphic_Buffer()->GetMemoryBuffer()); + // sourceNeedsUnlock = true; + //} - 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; + // Blit the buffer to dest. + Nearest_CopyImage(viewportBuffer, x_pixel, y_pixel, viewportClass->Get_Width(), (unsigned char*)destBuffer, dest_x0, dest_y0, destViewportClass->Get_Width(), pixel_width, pixel_height, trans); - // 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; - } - } - } + //if (needsUnlock) { + // destViewportClass->Get_Graphic_Buffer()->Unlock(); + //} + // + //if (sourceNeedsUnlock) { + // viewportClass->Get_Graphic_Buffer()->Unlock(); + //} return true; } diff --git a/code/REDALERT/WINSTUB.CPP b/code/REDALERT/WINSTUB.CPP index 2a7c6aa..714ab96 100644 --- a/code/REDALERT/WINSTUB.CPP +++ b/code/REDALERT/WINSTUB.CPP @@ -749,12 +749,12 @@ void WWSDL_ProcessEvents(KeyNumType& key, int& flags, bool presentBuffer) { renderConsole = !renderConsole; if (renderConsole) { - ShowCursor(TRUE); - Hide_Mouse(); + // ShowCursor(TRUE); + // Hide_Mouse(); } else { - ShowCursor(FALSE); - Show_Mouse(); + // ShowCursor(FALSE); + // Show_Mouse(); } break; }