mirror of
https://github.com/jmarshall23/CnC_Remastered_Collection.git
synced 2026-08-12 08:00:55 +02:00
Tileset stamps are now loaded before the level is rendered.
This commit is contained in:
@@ -3136,6 +3136,12 @@ void TemplateTypeClass::Init(TheaterType theater)
|
||||
|
||||
((unsigned char &)tplate.Width) = Get_IconSet_MapWidth(ptr);
|
||||
((unsigned char &)tplate.Height) = Get_IconSet_MapHeight(ptr);
|
||||
|
||||
{
|
||||
char tmp[512];
|
||||
sprintf(tmp, "icon_%s", fullname);
|
||||
((void const*&)tplate.HDImageData) = Load_Stamp(fullname, tplate.ImageData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1091,7 +1091,9 @@ void CellClass::Draw_It(int x, int y, bool objects) const
|
||||
** This is the underlying terrain icon.
|
||||
*/
|
||||
if (ttype->Get_Image_Data()) {
|
||||
LogicPage->Draw_Stamp(ttype, icon, x, y, NULL, WINDOW_TACTICAL);
|
||||
// jmarshall - hd image should always be valid even if loading legacy assets
|
||||
LogicPage->Draw_Stamp(ttype->Get_HDImage_Data(), icon, x, y, NULL, WINDOW_TACTICAL);
|
||||
// jmarshall end
|
||||
if (remap) {
|
||||
LogicPage->Remap(x+Map.TacPixelX, y+Map.TacPixelY, ICON_PIXEL_W, ICON_PIXEL_H, remap);
|
||||
}
|
||||
@@ -1190,9 +1192,9 @@ void CellClass::Draw_It(int x, int y, bool objects) const
|
||||
** Draw the hash-mark cursor:
|
||||
*/
|
||||
if (Map.ProximityCheck && Is_Clear_To_Build(loco)) {
|
||||
LogicPage->Draw_Stamp(DisplayClass::TransIconset, 0, x, y, NULL, WINDOW_TACTICAL);
|
||||
LogicPage->Draw_Stamp(DisplayClass::TransIconsetHD, 0, x, y, NULL, WINDOW_TACTICAL);
|
||||
} else {
|
||||
LogicPage->Draw_Stamp(DisplayClass::TransIconset, 2, x, y, NULL, WINDOW_TACTICAL);
|
||||
LogicPage->Draw_Stamp(DisplayClass::TransIconsetHD, 2, x, y, NULL, WINDOW_TACTICAL);
|
||||
}
|
||||
|
||||
#ifdef SCENARIO_EDITOR
|
||||
@@ -1213,8 +1215,8 @@ void CellClass::Draw_It(int x, int y, bool objects) const
|
||||
icon = (Cell_X(cell) - Cell_X(Map.ZoneCell + Map.ZoneOffset)) +
|
||||
(Cell_Y(cell) - Cell_Y(Map.ZoneCell + Map.ZoneOffset)) *
|
||||
tptr->Width;
|
||||
// jmarshall - pass in raw tptr
|
||||
LogicPage->Draw_Stamp(tptr, icon, x, y, NULL, WINDOW_TACTICAL);
|
||||
// jmarshall - hd image should always be valid even if loading legacy assets
|
||||
LogicPage->Draw_Stamp(tptr->Get_HDImage_Data(), icon, x, y, NULL, WINDOW_TACTICAL);
|
||||
// jmarshall end
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -108,6 +108,9 @@ unsigned char DisplayClass::TranslucentTable[(MAGIC_COL_COUNT+1)*256];
|
||||
unsigned char DisplayClass::WhiteTranslucentTable[(1+1)*256];
|
||||
unsigned char DisplayClass::MouseTranslucentTable[(4+1)*256];
|
||||
void const * DisplayClass::TransIconset;
|
||||
// jmarshall
|
||||
Image_t* DisplayClass::TransIconsetHD;
|
||||
// jmarshall end
|
||||
unsigned char DisplayClass::UnitShadow[(USHADOW_COL_COUNT+1)*256];
|
||||
unsigned char DisplayClass::UnitShadowAir[(USHADOW_COL_COUNT+1)*256];
|
||||
unsigned char DisplayClass::SpecialGhost[2*256];
|
||||
@@ -187,6 +190,7 @@ DisplayClass::DisplayClass(void) :
|
||||
{
|
||||
ShadowShapes = 0;
|
||||
TransIconset = 0;
|
||||
TransIconsetHD = 0;
|
||||
|
||||
Set_View_Dimensions(0, 8 * RESFACTOR, ScreenWidth, ScreenHeight);
|
||||
}
|
||||
@@ -228,6 +232,9 @@ void DisplayClass::One_Time(void)
|
||||
** Load the generic transparent icon set.
|
||||
*/
|
||||
TransIconset = MFCD::Retrieve("TRANS.ICN");
|
||||
// jmarshall
|
||||
TransIconsetHD = Load_Stamp("TRANS_ICON", TransIconset);
|
||||
// jmarshall end
|
||||
|
||||
#ifndef NDEBUG
|
||||
RawFileClass file("SHADOW.SHP");
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "map.h"
|
||||
#include "layer.h"
|
||||
|
||||
struct Image_t;
|
||||
|
||||
#define ICON_PIXEL_W 24
|
||||
#define ICON_PIXEL_H 24
|
||||
@@ -114,6 +115,9 @@ class DisplayClass: public MapClass
|
||||
static unsigned char WhiteTranslucentTable[(1+1)*256];
|
||||
static unsigned char MouseTranslucentTable[(4+1)*256];
|
||||
static void const *TransIconset;
|
||||
// jmarshall
|
||||
static Image_t* TransIconsetHD;
|
||||
// jmarshall end
|
||||
static unsigned char UnitShadow[(USHADOW_COL_COUNT+1)*256];
|
||||
static unsigned char UnitShadowAir[(USHADOW_COL_COUNT+1)*256];
|
||||
static unsigned char SpecialGhost[2*256];
|
||||
|
||||
@@ -15,20 +15,18 @@ struct Image_t {
|
||||
int height;
|
||||
int renderwidth;
|
||||
int renderheight;
|
||||
//unsigned char* buffer[MAX_HOUSE_COLORS][MAX_IMAGE_FRAMES];
|
||||
void* IconMapPtr;
|
||||
};
|
||||
|
||||
__forceinline Image_t::Image_t() {
|
||||
// buffer = NULL;
|
||||
IconMapPtr = NULL;
|
||||
numAnimFrames = 0;
|
||||
}
|
||||
|
||||
__forceinline Image_t::~Image_t() {
|
||||
//if (buffer) {
|
||||
// delete buffer;
|
||||
// buffer = NULL;
|
||||
//}
|
||||
}
|
||||
|
||||
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);
|
||||
Image_t* Image_CreateImageFrom8Bit(const char* name, int Width, int Height, unsigned char* data, unsigned char *remap = NULL);
|
||||
Image_t* Find_Image(const char* name);
|
||||
void Image_Add8BitImage(Image_t* image, int HouseId, int ShapeID, int Width, int Height, unsigned char* data, unsigned char* remap);
|
||||
@@ -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, int colorRemap) {
|
||||
void GL_RenderImage(Image_t* image, int x, int y, int width, int height, int colorRemap, int shapeId) {
|
||||
ImVec2 mi(x, y);
|
||||
ImVec2 ma(x + width, y + height);
|
||||
ImGui::GetForegroundDrawList()->AddImage((ImTextureID)image->image[colorRemap][0], mi, ma);
|
||||
ImGui::GetForegroundDrawList()->AddImage((ImTextureID)image->image[colorRemap][shapeId], mi, ma);
|
||||
}
|
||||
|
||||
void GL_FillRect(int color, int x, int y, int width, int height) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
|
||||
struct Image_t;
|
||||
void GL_RenderImage(Image_t* image, int x, int y, int width, int height, int colorRemap = 0);
|
||||
void GL_RenderImage(Image_t* image, int x, int y, int width, int height, int colorRemap = 0, int shapeId = 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);
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "function.h"
|
||||
#include "terrain.h"
|
||||
#include "type.h"
|
||||
#include "Image.h"
|
||||
|
||||
|
||||
static short const _List000011101000[] = {MAP_CELL_W, MAP_CELL_W+1, MAP_CELL_W+2, MAP_CELL_W*2, REFRESH_EOL};
|
||||
@@ -689,6 +690,12 @@ void TerrainTypeClass::Init(TheaterType theater)
|
||||
_makepath(fullname, NULL, NULL, terrain.IniName, Theaters[theater].Suffix);
|
||||
((void const *&)terrain.ImageData) = MFCD::Retrieve(fullname);
|
||||
|
||||
{
|
||||
char tmp[512];
|
||||
sprintf(tmp, "icon_%s", fullname);
|
||||
((void const*&)terrain.HDImageData) = Load_Stamp(fullname, terrain.ImageData);
|
||||
}
|
||||
|
||||
IsTheaterShape = true; //Let Build_Frame know that this is a theater specific shape
|
||||
if (terrain.RadarIcon != NULL) delete[] (char *)terrain.RadarIcon;
|
||||
((void const *&)terrain.RadarIcon) = Get_Radar_Icon(terrain.Get_Image_Data(), 0, 1, 3);
|
||||
|
||||
+53
-40
@@ -32,8 +32,6 @@ class GraphicViewPortClass;
|
||||
|
||||
#define TD_TILESET_CHECK 0x20
|
||||
|
||||
Image_t* tileset_icon_cache[4096];
|
||||
|
||||
/**
|
||||
* @brief union is to handle the parts of the header which vary between TD and RA format tiles.
|
||||
*/
|
||||
@@ -103,8 +101,7 @@ static int IconSize;
|
||||
static int IconCount;
|
||||
|
||||
void __cdecl Init_Stamps(IconControlType* iconset)
|
||||
{
|
||||
memset(&tileset_icon_cache, 0, sizeof(tileset_icon_cache));
|
||||
{
|
||||
if (iconset && LastIconset != iconset) {
|
||||
IconCount = (iconset->count);
|
||||
IconWidth = (iconset->width);
|
||||
@@ -193,51 +190,67 @@ void __cdecl Buffer_Draw_Stamp2(GraphicViewPortClass& viewport, IconControlType*
|
||||
}
|
||||
}
|
||||
|
||||
struct Image_t *__cdecl Load_Stamp(const char *name, const void* icondata)
|
||||
{
|
||||
IconControlType* tileset = (IconControlType*)icondata;
|
||||
|
||||
if (!tileset) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (LastIconset != tileset) {
|
||||
Init_Stamps(tileset);
|
||||
}
|
||||
|
||||
|
||||
int icon_index = 0;
|
||||
|
||||
if (icon_index >= IconCount) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t* src = &StampPtr[IconSize * icon_index];
|
||||
|
||||
// Check to see if the image is already loaded.
|
||||
{
|
||||
Image_t* image = Find_Image(name);
|
||||
if (image) {
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
Image_t *image = Image_CreateImageFrom8Bit(name, IconWidth, IconHeight, (unsigned char*)src);
|
||||
image->IconMapPtr = MapPtr;
|
||||
if (IconCount == 1)
|
||||
return image;
|
||||
|
||||
for (int i = 1; i < IconCount; i++) {
|
||||
icon_index = i;
|
||||
src = &StampPtr[IconSize * icon_index];
|
||||
Image_Add8BitImage(image, 0, i, IconWidth, IconHeight, src, NULL);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void __cdecl Buffer_Draw_Stamp_Clip2(GraphicViewPortClass& viewport, const void *icondata, int icon, int x, int y, const void* remapper, int left, int top, int right, int bottom)
|
||||
{
|
||||
const TemplateTypeClass* ttype = (TemplateTypeClass const*)icondata;
|
||||
IconControlType* tileset = (IconControlType * )ttype->Get_Image_Data();
|
||||
|
||||
// This is a awful hack, but need type info to generate unique id's for tileset generation.
|
||||
if (icondata == DisplayClass::TransIconset) {
|
||||
tileset = (IconControlType*)DisplayClass::TransIconset;
|
||||
ttype = NULL;
|
||||
}
|
||||
|
||||
if (!tileset) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (LastIconset != tileset) {
|
||||
Init_Stamps(tileset);
|
||||
}
|
||||
|
||||
int icon_index = MapPtr != nullptr ? MapPtr[icon] : icon;
|
||||
|
||||
if (icon_index < IconCount) {
|
||||
Image_t* iconImage = (Image_t*)icondata;
|
||||
uint8_t* MapPtr = (uint8_t * )iconImage->IconMapPtr;
|
||||
int icon_index = MapPtr != nullptr ? MapPtr[icon] : icon;
|
||||
{
|
||||
int blit_height = IconHeight;
|
||||
int blit_width = IconWidth;
|
||||
uint8_t* src = &StampPtr[IconSize * icon_index];
|
||||
|
||||
int width = left + right;
|
||||
int xstart = left + x;
|
||||
int height = top + bottom;
|
||||
int ystart = top + y;
|
||||
|
||||
//
|
||||
if (!tileset_icon_cache[icon_index]) {
|
||||
char tmp[512];
|
||||
if (ttype != NULL) {
|
||||
sprintf(tmp, "icon_%d_%d", ttype->Type, icon_index);
|
||||
}
|
||||
else {
|
||||
sprintf(tmp, "icon_%d_%d", icondata, icon_index);
|
||||
}
|
||||
tileset_icon_cache[icon_index] = Image_CreateImageFrom8Bit(tmp, IconWidth, IconHeight, (unsigned char *)src);
|
||||
}
|
||||
|
||||
|
||||
if (xstart < width && ystart < height && IconHeight + ystart > top && IconWidth + xstart > left) {
|
||||
if (xstart < left) {
|
||||
src += left - xstart;
|
||||
// src += left - xstart;
|
||||
blit_width -= left - xstart;
|
||||
xstart = left;
|
||||
}
|
||||
@@ -251,7 +264,7 @@ void __cdecl Buffer_Draw_Stamp_Clip2(GraphicViewPortClass& viewport, const void
|
||||
|
||||
if (top > ystart) {
|
||||
blit_height = IconHeight - (top - ystart);
|
||||
src += IconWidth * (top - ystart);
|
||||
// src += IconWidth * (top - ystart);
|
||||
ystart = top;
|
||||
}
|
||||
|
||||
@@ -308,7 +321,7 @@ void __cdecl Buffer_Draw_Stamp_Clip2(GraphicViewPortClass& viewport, const void
|
||||
//}
|
||||
|
||||
GL_SetClipRect(xstart, ystart, blit_width, blit_height);
|
||||
GL_RenderImage(tileset_icon_cache[icon_index], xstart, ystart, blit_width, blit_height);
|
||||
GL_RenderImage(iconImage, xstart, ystart, blit_width, blit_height, 0, icon_index);
|
||||
GL_ResetClipRect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,8 @@ extern "C" {
|
||||
void * __cdecl Get_Font_Palette_Ptr ( void );
|
||||
}
|
||||
|
||||
struct Image_t* __cdecl Load_Stamp(const char* name, const void* icondata);
|
||||
|
||||
extern GraphicViewPortClass *LogicPage;
|
||||
extern BOOL AllowHardwareBlitFills;
|
||||
#endif
|
||||
|
||||
@@ -290,6 +290,25 @@ Image_t* Image_LoadImage(const char* name, bool loadAnims, bool loadHouseColor)
|
||||
return image;
|
||||
}
|
||||
|
||||
Image_t *Find_Image(const char* name) {
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Image_t* Image_CreateImageFrom8Bit(const char* name, int Width, int Height, unsigned char *data, unsigned char* remap) {
|
||||
int64_t hash = generateHashValue(name, strlen(name));
|
||||
|
||||
@@ -360,6 +379,61 @@ Image_t* Image_CreateImageFrom8Bit(const char* name, int Width, int Height, unsi
|
||||
return image;
|
||||
}
|
||||
|
||||
void Image_Add8BitImage(Image_t *image, int HouseId, int ShapeID, int Width, int Height, unsigned char* data, unsigned char* remap) {
|
||||
unsigned char* buffer = new unsigned char[Width * Height * 4];
|
||||
unsigned char* ccpalete = (unsigned char*)CCPalette.Get_Data();
|
||||
|
||||
if (image->width != Width || image->height != Height) {
|
||||
assert(!"Image_Add8BitImage: Invalid new dimensions!");
|
||||
}
|
||||
|
||||
for (int i = 0; i < Width * Height; i++) {
|
||||
unsigned char c = data[i];
|
||||
if (remap) {
|
||||
c = remap[c];
|
||||
}
|
||||
|
||||
unsigned char r = ccpalete[(c * 3) + 0] << 2;
|
||||
unsigned char g = ccpalete[(c * 3) + 1] << 2;
|
||||
unsigned char b = ccpalete[(c * 3) + 2] << 2;
|
||||
unsigned char a = 0;
|
||||
|
||||
if ((r == 84 && g == 252 && b == 84) || (r == 0 && g == 168 && b == 0)) {
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
a = 128;
|
||||
}
|
||||
else if (c != 0) {
|
||||
a = 255;
|
||||
}
|
||||
|
||||
|
||||
buffer[(i * 4) + 0] = r;
|
||||
buffer[(i * 4) + 1] = g;
|
||||
buffer[(i * 4) + 2] = b;
|
||||
buffer[(i * 4) + 3] = a;
|
||||
}
|
||||
|
||||
|
||||
GLuint texture;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
|
||||
image->image[HouseId][ShapeID] = texture;
|
||||
image->numAnimFrames = -1;
|
||||
image->renderwidth = image->width = Width;
|
||||
image->renderheight = image->height = Height;
|
||||
|
||||
delete buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL Set_Video_Mode(HWND hwnd, int w, int h, int bits_per_pixel) {
|
||||
// Todo implement resoluton scaling.
|
||||
|
||||
Reference in New Issue
Block a user