diff --git a/code/REDALERT/BDATA.CPP b/code/REDALERT/BDATA.CPP index e452ce0..56553f7 100644 --- a/code/REDALERT/BDATA.CPP +++ b/code/REDALERT/BDATA.CPP @@ -3143,7 +3143,7 @@ void BuildingTypeClass::One_Time(void) { char imageFileName[512]; sprintf(imageFileName, "DATA/ART/TEXTURES/SRGB/RED_ALERT/STRUCTURES/%s/%s-0000.TGA", building.Graphic_Name(), building.Graphic_Name()); - ((void const*&)building.HDImageData) = Image_LoadImage(imageFileName); + ((void const*&)building.HDImageData) = Image_LoadImage(imageFileName, true, true); if (building.ImageData != NULL && building.HDImageData != NULL) { int width = Get_Build_Frame_Width(building.ImageData); diff --git a/code/REDALERT/CONQUER.CPP b/code/REDALERT/CONQUER.CPP index 1762cac..2455d61 100644 --- a/code/REDALERT/CONQUER.CPP +++ b/code/REDALERT/CONQUER.CPP @@ -3486,9 +3486,9 @@ void CC_Draw_Shape(Image_t* image, int shapenum, int x, int y, WindowNumberType if ((flags & SHAPE_GHOST) && (!ghostdata)) { ghostdata = DisplayClass::SpecialGhost; } - if ((flags & SHAPE_FADING) && (!fadingdata)) { - fadingdata = DisplayClass::FadingShade; - } + //if ((flags & SHAPE_FADING) && (!fadingdata)) { + // fadingdata = DisplayClass::FadingShade; + //} static unsigned char* _xbuffer = 0; diff --git a/code/REDALERT/Image.h b/code/REDALERT/Image.h index 0e08fa7..3631a73 100644 --- a/code/REDALERT/Image.h +++ b/code/REDALERT/Image.h @@ -1,13 +1,16 @@ // Image.h // +#define MAX_IMAGE_FRAMES 256 +#define MAX_HOUSE_COLORS 8 struct Image_t { Image_t(); ~Image_t(); char name[512]; int64_t namehash; - unsigned int image; + unsigned int image[MAX_HOUSE_COLORS][MAX_IMAGE_FRAMES]; + unsigned int numAnimFrames; int width; int height; int renderwidth; @@ -17,6 +20,7 @@ struct Image_t { __forceinline Image_t::Image_t() { buffer = NULL; + numAnimFrames = 0; } __forceinline Image_t::~Image_t() { @@ -26,5 +30,5 @@ __forceinline Image_t::~Image_t() { } } -Image_t* Image_LoadImage(const char* name); +Image_t* Image_LoadImage(const char* name, bool loadAnims = false, bool loadHouseColor = false); Image_t* Image_CreateImageFrom8Bit(const char* name, int Width, int Height, unsigned char* data, unsigned char *remap = NULL); \ No newline at end of file diff --git a/code/REDALERT/NEWBLIT.CPP b/code/REDALERT/NEWBLIT.CPP index 0e92de6..693953c 100644 --- a/code/REDALERT/NEWBLIT.CPP +++ b/code/REDALERT/NEWBLIT.CPP @@ -18,10 +18,10 @@ void GL_ResetClipRect(void) { ImGui::GetForegroundDrawList()->PopClipRect(); } -void GL_RenderImage(Image_t* image, int x, int y, int width, int height) { +void GL_RenderImage(Image_t* image, int x, int y, int width, int height, int colorRemap) { ImVec2 mi(x, y); ImVec2 ma(x + width, y + height); - ImGui::GetForegroundDrawList()->AddImage((ImTextureID)image->image, mi, ma); + ImGui::GetForegroundDrawList()->AddImage((ImTextureID)image->image[colorRemap][0], mi, ma); } void GL_FillRect(int color, int x, int y, int width, int height) { diff --git a/code/REDALERT/NEWBLIT.H b/code/REDALERT/NEWBLIT.H index 84eba03..b3e9508 100644 --- a/code/REDALERT/NEWBLIT.H +++ b/code/REDALERT/NEWBLIT.H @@ -2,7 +2,7 @@ // struct Image_t; -void GL_RenderImage(Image_t* image, int x, int y, int width, int height); +void GL_RenderImage(Image_t* image, int x, int y, int width, int height, int colorRemap = 0); void GL_DrawText(int color, int x, int y, char* text); void GL_FillRect(int color, int x, int y, int width, int height); void GL_DrawLine(int color, int x, int y, int dx, int dy); diff --git a/code/REDALERT/OBJECT.CPP b/code/REDALERT/OBJECT.CPP index ad1b2e4..6b39275 100644 --- a/code/REDALERT/OBJECT.CPP +++ b/code/REDALERT/OBJECT.CPP @@ -2182,7 +2182,8 @@ ObjectTypeClass::ObjectTypeClass( Armor(ARMOR_NONE), MaxStrength(0), ImageData(0), - RadarIcon(0) + RadarIcon(0), + HDImageData(0) { /* ** Init the DimensionData rect. Not sure how this was ever working before without being allocated. It was just trashing diff --git a/code/REDALERT/Shape.cpp b/code/REDALERT/Shape.cpp index 9c2480e..7fa8e26 100644 --- a/code/REDALERT/Shape.cpp +++ b/code/REDALERT/Shape.cpp @@ -1546,8 +1546,10 @@ long Buffer_Frame_To_Page(int x, int y, int width, int height, struct Image_t * xstart = xstart + WindowList[Window][WINDOWX];// + LogicPage->Get_XPos(); ystart = ystart + WindowList[Window][WINDOWY];// + LogicPage->Get_YPos(); //GL_SetClipRect(WindowList[Window][WINDOWX], WindowList[Window][WINDOWY], WindowList[Window][WINDOWWIDTH], WindowList[Window][WINDOWWIDTH]); - GL_RenderImage(shape_image, xstart, ystart, width, height); - + if(renderHDTexture) + GL_RenderImage(shape_image, xstart, ystart, width, height, (int)fade_table); + else + GL_RenderImage(shape_image, xstart, ystart, width, height, 0); // Here we just use the function that will blit the entire frame // using the appropriate effects. diff --git a/code/REDALERT/TECHNO.CPP b/code/REDALERT/TECHNO.CPP index 71ff47a..7f9ea58 100644 --- a/code/REDALERT/TECHNO.CPP +++ b/code/REDALERT/TECHNO.CPP @@ -4451,11 +4451,17 @@ VisualType TechnoClass::Visual_Character(bool raw) const } void TechnoClass::Techno_Draw_Object_HD(struct Image_t* image, int shapenum, int x, int y, WindowNumberType window, DirType rotation, int scale) const { - void const* remap = Remap_Table(); + //void const* remap = Remap_Table(); void const* shadow = Map.UnitShadow; - y -= Lepton_To_Pixel(Height); - CC_Draw_Shape(image, shapenum, x, y, window, SHAPE_CENTER | SHAPE_WIN_REL | SHAPE_FADING | SHAPE_GHOST, remap, shadow, rotation); + PlayerColorType remapColor = PCOLOR_GOLD; + if (Techno_Type_Class()->IsRemappable) { + remapColor = House->RemapColor; + } + + y -= Lepton_To_Pixel(Height); + + CC_Draw_Shape(image, shapenum, x, y, window, SHAPE_CENTER | SHAPE_WIN_REL | SHAPE_FADING | SHAPE_GHOST, (const void *)remapColor, shadow, rotation); } /*********************************************************************************************** diff --git a/code/REDALERT/VDATA.CPP b/code/REDALERT/VDATA.CPP index e5d04fa..1e111e5 100644 --- a/code/REDALERT/VDATA.CPP +++ b/code/REDALERT/VDATA.CPP @@ -49,7 +49,7 @@ #include "function.h" - +#include "Image.h" // Submarine static VesselTypeClass const VesselSubmarine( @@ -578,7 +578,6 @@ void VesselTypeClass::One_Time(void) */ _makepath(fullname, NULL, NULL, uclass.Graphic_Name(), ".SHP"); ((void const *&)uclass.ImageData) = MFCD::Retrieve(fullname); - ((int &)uclass.MaxSize) = 26; } } diff --git a/code/REDALERT/WIN32LIB/MOUSEWW.CPP b/code/REDALERT/WIN32LIB/MOUSEWW.CPP index e41649d..da56f02 100644 --- a/code/REDALERT/WIN32LIB/MOUSEWW.CPP +++ b/code/REDALERT/WIN32LIB/MOUSEWW.CPP @@ -252,7 +252,7 @@ void WWMouseClass::RenderMouse(void) { ImGui::SetMouseCursor(ImGuiMouseCursor_None); - ImGui::GetForegroundDrawList()->AddImage((ImTextureID)current_cursor->image, mi, ma); + ImGui::GetForegroundDrawList()->AddImage((ImTextureID)current_cursor->image[0][0], mi, ma); } void WWMouseClass::Low_Show_Mouse(int x, int y) diff --git a/code/REDALERT/WINSTUB.CPP b/code/REDALERT/WINSTUB.CPP index 1839060..6948342 100644 --- a/code/REDALERT/WINSTUB.CPP +++ b/code/REDALERT/WINSTUB.CPP @@ -109,26 +109,19 @@ static int64_t generateHashValue(const char* fname, const int size) { return hash; } -Image_t* Image_LoadImage(const char* name) { - int64_t hash = generateHashValue(name, strlen(name)); - - // Check to see if the image is already loaded. - for (int i = 0; i < loaded_images.size(); i++) { - if (loaded_images[i]->namehash == hash) { - return loaded_images[i]; - } - } - +static bool Image_loadHDImage(Image_t *image, const char* name, int houseid, int animid, int64_t hash, unsigned char remap[3]) { ILuint ImageName; ilGenImages(1, &ImageName); ilBindImage(ImageName); if (!ilLoadImage(name)) { ilDeleteImages(1, &ImageName); - return NULL; + return false; } + bool swapBGR = false; if (strstr(name, ".TGA")) { iluFlipImage(); + swapBGR = true; } ILuint Width, Height, Bpp; @@ -137,12 +130,31 @@ Image_t* Image_LoadImage(const char* name) { Bpp = ilGetInteger(IL_IMAGE_BPP); ILubyte* Data = ilGetData(); + if (Bpp == 4 && (remap[0] + remap[1] + remap[2]) > 0) { + for (int i = 0; i < Width * Height; i++) { + //float g = (Data[(i * 4) + 1] / 255.0f); + if (Data[(i * 4) + 1] > Data[(i * 4) + 0] && Data[(i * 4) + 1] > Data[(i * 4) + 2]) { + + for (int c = 0; c < 3; c++) { + //float f = (remap[2 - c]) / 255.0f; + //f = f * min((g * 2.0f), 1.0f); + Data[(i * 4) + c] = remap[2 - c] << 2; //((unsigned char)(f * 255.0f)) << 2; //((unsigned char)f) << 2; + } + } + } + } + GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); if (Bpp == 4) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, Data); + if (swapBGR) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_BGRA, GL_UNSIGNED_BYTE, Data); + } + else { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, Data); + } } else if (Bpp == 3) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGB, GL_UNSIGNED_BYTE, Data); @@ -157,28 +169,79 @@ Image_t* Image_LoadImage(const char* name) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - Image_t* image = new Image_t(); + strcpy(image->name, name); - image->image = texture; + image->image[houseid][animid] = texture; image->namehash = hash; image->renderwidth = image->width = Width; image->renderheight = image->height = Height; image->buffer = new unsigned char[Width * Height * Bpp]; - memcpy(image->buffer, Data, Width * Height * Bpp); - loaded_images.push_back(image); + if (houseid == 0 && animid == 0) { + memcpy(image->buffer, Data, Width * Height * Bpp); + } ilDeleteImages(1, &ImageName); + return true; +} + +Image_t* Image_LoadImage(const char* name, bool loadAnims, bool loadHouseColor) { + int64_t hash = generateHashValue(name, strlen(name)); + + int image_table_size = loaded_images.size(); + if (image_table_size > 0) + { + Image_t** image_table = &loaded_images[0]; + + // Check to see if the image is already loaded. + for (int i = 0; i < image_table_size; i++) { + if (image_table[i]->namehash == hash) { + return image_table[i]; + } + } + } + Image_t* image = new Image_t(); + + if (!loadAnims) { + unsigned char remap[3] = { 0, 0, 0 }; + if (!Image_loadHDImage(image, name, 0, 0, hash, remap)) { + delete image; + return NULL; + } + } + else { + byte* palette = (byte *)CCPalette.Get_Data(); + for (int i = 0; i < MAX_MPLAYER_COLORS; i++) { + unsigned char p = ColorRemaps[i].Color; + unsigned char remap[3]; + + remap[0] = palette[(p * 3) + 0]; + remap[1] = palette[(p * 3) + 1]; + remap[2] = palette[(p * 3) + 2]; + if (!Image_loadHDImage(image, name, i, 0, hash, remap)) { + delete image; + return NULL; + } + } + } + + loaded_images.push_back(image); return image; } Image_t* Image_CreateImageFrom8Bit(const char* name, int Width, int Height, unsigned char *data, unsigned char* remap) { int64_t hash = generateHashValue(name, strlen(name)); - // Check to see if the image is already loaded. - for (int i = 0; i < loaded_images.size(); i++) { - if (loaded_images[i]->namehash == hash) { - return loaded_images[i]; + int image_table_size = loaded_images.size(); + if (image_table_size > 0) + { + Image_t** image_table = &loaded_images[0]; + + // Check to see if the image is already loaded. + for (int i = 0; i < image_table_size; i++) { + if (image_table[i]->namehash == hash) { + return image_table[i]; + } } } @@ -226,7 +289,8 @@ Image_t* Image_CreateImageFrom8Bit(const char* name, int Width, int Height, unsi strcpy(image->name, name); - image->image = texture; + image->image[0][0] = texture; + image->numAnimFrames = -1; image->namehash = hash; image->renderwidth = image->width = Width; image->renderheight = image->height = Height; diff --git a/code/TIBERIANDAWN/GSCREEN.CPP b/code/TIBERIANDAWN/GSCREEN.CPP index 95c47eb..e241d0c 100644 --- a/code/TIBERIANDAWN/GSCREEN.CPP +++ b/code/TIBERIANDAWN/GSCREEN.CPP @@ -492,6 +492,7 @@ extern bool CanVblankSync; *=============================================================================================*/ void GScreenClass::Blit_Display(void) { +#if 0 // jmarshall - no longer used and saves on performance to disable it(3.6%). if (SeenBuff.Get_Width()!=320){ #if (0) if (HidPage.Get_IsDirectDraw() && (Options.GameSpeed >1 || Options.ScrollRate==6 && CanVblankSync) ){ @@ -520,7 +521,7 @@ void GScreenClass::Blit_Display(void) // ST - 1/2/2019 5:26PM //ModeX_Blit (&HiddenPage); } - +#endif }