Merge branch 'master' into BL/SDL-UserInput-plus-hotfixes

This commit is contained in:
Ben Lankamp
2020-06-22 00:09:24 +02:00
38 changed files with 10557 additions and 1242 deletions
+5
View File
@@ -2,6 +2,11 @@
How to use:
You can use the vanilla assets, but this codebase supports the remaster assets as well. Please support EA and purchase the remaster!
Extract TEXTURES_SRGB.MEG CONFIG.MEG to the same folder as RedAlert.exe(so the data folder is at the same level as the executable).
If you are using the remaster assets, initial launch might take a minute to generate the cache. This only needs to be done once, as more things move over to the asset cache, first launches are syncing might cause the same slow load, but following loading will be extremely fast.
For playing back audio you'll need to download the converted wav files:
https://drive.google.com/file/d/1feetm3tuqTcPc7LAohnu50kseSEX0R7f/view?usp=sharing
+1 -1
View File
@@ -3,4 +3,4 @@
################################################################################
/.vs
/out
/out
+6 -2
View File
@@ -134,6 +134,7 @@ set(src_redalert
./RedAlert/BASE64.CPP
./RedAlert/BASE64.H
./RedAlert/BBDATA.CPP
./RedAlert/BDATAXML.CPP
./RedAlert/BDATA.CPP
./RedAlert/BENCH.CPP
./RedAlert/BENCH.H
@@ -426,6 +427,7 @@ set(src_redalert
./RedAlert/OPTIONS.H
./RedAlert/OVERLAY.CPP
./RedAlert/OVERLAY.H
./RedAlert/UNITXML.CPP
./RedAlert/PACKET.CPP
./RedAlert/PACKET.H
./RedAlert/PALETTEC.CPP
@@ -624,6 +626,7 @@ set(src_redalert
./RedAlert/_WSPROTO.H
./REDALERT/MapScript.cpp
./REDALERT/TXTPRNT.cpp
./REDALERT/TILESETXML.cpp
)
set(src_external
@@ -710,7 +713,8 @@ set(src_external
./external/lua/lvm.h
./external/lua/lzio.c
./external/lua/lzio.h
./external/xml/tinyxml2.cpp
./external/xml/tinyxml2.h
)
@@ -719,5 +723,5 @@ add_compile_options(/permissive+ /Zc:forScope- /Zp1)
add_executable(RedAlert ${src_io} ${src_win32lib} ${src_redalert} ${src_external})
set_target_properties(RedAlert PROPERTIES OUTPUT_NAME "RedAlert" LINK_FLAGS "/PDB:\"RedAlert.pdb\" /SUBSYSTEM:WINDOWS" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../" )
target_include_directories(RedAlert PRIVATE ./external/devil/;./external/;./redalert/win32lib;./external/lua/;./external/imgui;./external/dxsdk/Include;./external/ffmpeg-win32/include;./external/sdl2/include;./win32lib;./external/openal/include)
target_include_directories(RedAlert PRIVATE ./external/xml/;./external/devil/;./external/;./redalert/win32lib;./external/lua/;./external/imgui;./external/dxsdk/Include;./external/ffmpeg-win32/include;./external/sdl2/include;./win32lib;./external/openal/include)
target_link_libraries(RedAlert "opengl32.lib" "winmm.lib" "Ws2_32.lib" "${CMAKE_SOURCE_DIR}/external/devil/ilu.lib" "${CMAKE_SOURCE_DIR}/external/devil/DevIL.lib" "${CMAKE_SOURCE_DIR}/external/sdl2/lib/x86/SDL2.lib" "${CMAKE_SOURCE_DIR}/external/openal/out/build/x86-Release/OpenAL32.lib")
+77 -19
View File
@@ -3141,17 +3141,50 @@ void BuildingTypeClass::One_Time(void)
_makepath(fullname, NULL, NULL, building.Graphic_Name(), ".SHP");
((void const *&)building.ImageData) = MFCD::Retrieve(fullname);
{
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, true, true);
const char* imageFileName = Buildings_FindHDTexture(fullname, 0, 0);
if (building.ImageData != NULL && building.HDImageData != NULL) {
int width = Get_Build_Frame_Width(building.ImageData);
int height = Get_Build_Frame_Height(building.ImageData);
if (imageFileName) {
Image_t *image = Image_LoadImage(imageFileName, true, true);
int numBuildingAnims = Buildings_GetNumFramesForTile(fullname, 0);
int shapeId = 1;
building.HDImageData->renderwidth = width;
building.HDImageData->renderheight = height;
}
// Load the old school animation pipeline.
{
while (true) {
imageFileName = Buildings_FindHDTexture(fullname, shapeId, 0);
if (imageFileName == NULL)
break;
for (int d = 0; d < MAX_MPLAYER_COLORS; d++) {
Image_Add32BitImage(imageFileName, image, d, shapeId, 0);
}
shapeId++;
}
}
if (numBuildingAnims > 0)
{
for (int i = 1; i < numBuildingAnims; i++) {
imageFileName = Buildings_FindHDTexture(fullname, 0, i);
for (int d = 0; d < MAX_MPLAYER_COLORS; d++) {
Image_Add32BitImage(imageFileName, image, d, 0, i);
}
}
}
image->numFrames = numBuildingAnims;
((void const*&)building.HDImageData) = image;
if (building.ImageData != NULL && building.HDImageData != NULL) {
int width = Get_Build_Frame_Width(building.ImageData);
int height = Get_Build_Frame_Height(building.ImageData);
for (int d = 0; d < shapeId; d++)
{
building.HDImageData->renderwidth[d] = width;
building.HDImageData->renderheight[d] = height;
}
}
}
}
}
@@ -3231,7 +3264,7 @@ void BuildingTypeClass::Display(int x, int y, WindowNumberType window, HousesTyp
//CC_Draw_Shape((Image_t *)Get_HDImage_Data(), 0, x, y, window, SHAPE_CENTER | SHAPE_WIN_REL, NULL, NULL, DIR_N);
x += WindowList[window][WINDOWX];
y += WindowList[window][WINDOWY];
GL_RenderImage(hdimage, x, y, hdimage->renderwidth, hdimage->renderheight);
GL_RenderImage(hdimage, x, y, hdimage->renderwidth[0], hdimage->renderheight[0]);
}
else {
void const* ptr = Get_Cameo_Data();
@@ -3388,23 +3421,48 @@ void BuildingTypeClass::Init(TheaterType theater)
((void const *&)classptr->ImageData) = MFCD::Retrieve(fullname);
// jmarshall
{
char imageFileName[512];
const char* imageFileName = Buildings_FindHDTexture(fullname, 0, 0);
// Try load the theatre specific asset first
sprintf(imageFileName, "DATA/ART/TEXTURES/SRGB/RED_ALERT/TERRAIN/%s/%s.%s/%s.%s-0000.DDS", Theaters[theater].Name, classptr->Graphic_Name(), Theaters[theater].Suffix, classptr->Graphic_Name(), Theaters[theater].Suffix);
((BuildingTypeClass*)classptr)->HDImageData = Image_LoadImage(imageFileName);
// Try load the theatre specific asset first
if (imageFileName) {
Image_t *image = ((BuildingTypeClass*)classptr)->HDImageData = Image_LoadImage(imageFileName, true, true);
if (!((BuildingTypeClass*)classptr)->HDImageData) {
sprintf(imageFileName, "DATA/ART/TEXTURES/SRGB/RED_ALERT/STRUCTURES/%s/%s-0000.TGA", classptr->Graphic_Name(), classptr->Graphic_Name());
((BuildingTypeClass*)classptr)->HDImageData = Image_LoadImage(imageFileName);
// Load the old school animation pipeline.
int shapeId = 1;
{
while (true) {
imageFileName = Buildings_FindHDTexture(fullname, shapeId, 0);
if (imageFileName == NULL)
break;
for (int d = 0; d < MAX_MPLAYER_COLORS; d++) {
Image_Add32BitImage(imageFileName, image, d, shapeId, 0);
}
shapeId++;
}
}
int numBuildingAnims = Buildings_GetNumFramesForTile(fullname, 0);
if (numBuildingAnims > 0)
{
for (int i = 1; i < numBuildingAnims; i++) {
imageFileName = Buildings_FindHDTexture(fullname, 0, i);
for (int d = 0; d < MAX_MPLAYER_COLORS; d++) {
Image_Add32BitImage(imageFileName, ((BuildingTypeClass*)classptr)->HDImageData, d, 0, i);
}
}
}
((BuildingTypeClass*)classptr)->HDImageData->numFrames = numBuildingAnims;
}
if (classptr->ImageData != NULL && classptr->HDImageData != NULL) {
int width = Get_Build_Frame_Width(classptr->ImageData);
int height = Get_Build_Frame_Height(classptr->ImageData);
classptr->HDImageData->renderwidth = width;
classptr->HDImageData->renderheight = height;
classptr->HDImageData->renderwidth[0] = width;
classptr->HDImageData->renderheight[0] = height;
}
}
// jmarshall end
+98
View File
@@ -0,0 +1,98 @@
// BDATAXML.CPP
//
#include "FUNCTION.H"
#include "tinyxml2.h"
#include <string>
#include <vector>
int64_t generateHashValue(const char* fname, const int size);
struct BuildingsTileRule_t {
std::string name;
int64_t hash;
int shape;
std::vector<std::string> frames;
};
struct BuildingsXMLInfo_t {
std::vector<BuildingsTileRule_t> tiles;
};
BuildingsXMLInfo_t buildingsXmlRules;
const char* Buildings_FindHDTexture(const char* shapeFileName, int shapeNum, int frameNum) {
char tmpFileName[2048];
strcpy(tmpFileName, shapeFileName);
COM_SetExtension(tmpFileName, strlen(tmpFileName), "");
int64_t hash = generateHashValue(tmpFileName, strlen(tmpFileName));
for (int i = 0; i < buildingsXmlRules.tiles.size(); i++) {
if (buildingsXmlRules.tiles[i].hash == hash && buildingsXmlRules.tiles[i].shape == shapeNum) {
static char hdTexturePath[2048];
if (buildingsXmlRules.tiles[i].frames.size() == 0)
return NULL;
sprintf(hdTexturePath, "DATA/ART/TEXTURES/SRGB/RED_ALERT/STRUCTURES/%s", buildingsXmlRules.tiles[i].frames[frameNum].c_str());
return &hdTexturePath[0];
}
}
return NULL;
}
int Buildings_GetNumFramesForTile(const char* shapeFileName, int shapeNum) {
char tmpFileName[2048];
strcpy(tmpFileName, shapeFileName);
COM_SetExtension(tmpFileName, strlen(tmpFileName), "");
int64_t hash = generateHashValue(tmpFileName, strlen(tmpFileName));
for (int i = 0; i < buildingsXmlRules.tiles.size(); i++) {
if (buildingsXmlRules.tiles[i].hash == hash && buildingsXmlRules.tiles[i].shape == shapeNum) {
return buildingsXmlRules.tiles[i].frames.size();
}
}
return 0;
}
void Buildings_ParseTile(tinyxml2::XMLNode* tile, BuildingsTileRule_t& tileRule) {
tinyxml2::XMLNode* KeyNode = tile->FirstChildElement("Key");
tinyxml2::XMLNode* NameNode = KeyNode->FirstChildElement("Name");
tinyxml2::XMLNode* ShapeNode = KeyNode->FirstChildElement("Shape");
tinyxml2::XMLNode* ValueNode = tile->FirstChildElement("Value");
tinyxml2::XMLNode* FramesNode = ValueNode->FirstChildElement("Frames");
tinyxml2::XMLNode* FrameNode = FramesNode->FirstChildElement("Frame");
tileRule.name = NameNode->FirstChild()->ToText()->Value();
tileRule.hash = generateHashValue(tileRule.name.c_str(), tileRule.name.size());
tileRule.shape = atoi(ShapeNode->FirstChild()->ToText()->Value());
while (FrameNode != NULL) {
if (FrameNode->FirstChild() != NULL) {
tileRule.frames.push_back(FrameNode->FirstChild()->ToText()->Value());
}
FrameNode = FrameNode->NextSiblingElement("Frame");
}
}
void Buildings_LoadRuleXML(const char* path, BuildingsXMLInfo_t& info) {
tinyxml2::XMLDocument doc;
doc.LoadFile(path);
tinyxml2::XMLElement* root = doc.FirstChildElement();
if (root == NULL)
return;
tinyxml2::XMLNode* tilesetTypeClassNode = root->FirstChild();
tinyxml2::XMLNode* tilesParent = tilesetTypeClassNode->FirstChildElement("Tiles");
tinyxml2::XMLNode* tile = tilesParent->FirstChildElement("Tile");
while (tile != NULL) {
BuildingsTileRule_t tileRule;
Buildings_ParseTile(tile, tileRule);
info.tiles.push_back(tileRule);
tile = tile->NextSiblingElement("Tile");
}
}
void Buildings_LoadRules(void) {
Buildings_LoadRuleXML("data/xml/tilesets/RA_STRUCTURES.XML", buildingsXmlRules);
}
+33 -15
View File
@@ -46,7 +46,7 @@
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include "image.h"
static TemplateTypeClass const Empty(
TEMPLATE_CLEAR1,
@@ -3136,6 +3136,21 @@ void TemplateTypeClass::Init(TheaterType theater)
((unsigned char &)tplate.Width) = Get_IconSet_MapWidth(ptr);
((unsigned char &)tplate.Height) = Get_IconSet_MapHeight(ptr);
// Try and load HD assets first.
Image_t *hdImage = Load_StampHD(theater, fullname, tplate.ImageData);
if (hdImage)
{
Get_Stamp_Size(tplate.ImageData, hdImage->renderwidth, hdImage->renderheight);
((void const*&)tplate.HDImageData) = hdImage;
}
else
{
// If no HD assets, load the legacy assets into a texture.
char tmp[512];
sprintf(tmp, "icon_%s", fullname);
((void const*&)tplate.HDImageData) = Load_Stamp(fullname, tplate.ImageData);
}
}
}
}
@@ -3183,20 +3198,23 @@ 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)),
ICON_PIXEL_W, ICON_PIXEL_H,
ICON_PIXEL_W/2, ICON_PIXEL_H/2, (char *)NULL);
} else {
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);
// jmarshall - even if using legacy data, always use hdimage.
HidPage.Draw_Stamp(Get_HDImage_Data(), index, 0, 0, NULL, WINDOW_MAIN);
// Disabled legacy blit code.
//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)),
// ICON_PIXEL_W, ICON_PIXEL_H,
// ICON_PIXEL_W/2, ICON_PIXEL_H/2, (char *)NULL);
//
//} else {
// 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);
// jmarshall end
}
}
}
+7 -5
View File
@@ -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;
+11 -10
View File
@@ -2138,6 +2138,7 @@ static void Sync_Delay(void)
Map.Render();
}
}
animFrameNum+=0.5f; // This is garbage and needs to be fixed with proper delta time bits!!!
if (!FrameTimer) {
Color_Cycle();
Call_Back();
@@ -3498,8 +3499,8 @@ void CC_Draw_Shape(Image_t* image, int shapenum, int x, int y, WindowNumberType
if (image != NULL && shapenum != -1) {
int width = image->renderwidth;
int height = image->renderheight;
int width = image->renderwidth[shapenum];
int height = image->renderheight[shapenum];
#ifdef NEVER
/*
@@ -3584,18 +3585,18 @@ void CC_Draw_Shape(Image_t* image, int shapenum, int x, int y, WindowNumberType
Buffer_Enable_HD_Texture(true);
//if (draw_window.Lock()) {
if ((flags & (SHAPE_GHOST | SHAPE_FADING)) == (SHAPE_GHOST | SHAPE_FADING)) {
Buffer_Frame_To_Page(x, y, width, height, image, window, flags | SHAPE_TRANS, ghostdata, fadingdata, 1, predoffset);
Buffer_Frame_To_Page(shapenum, x, y, width, height, image, window, flags | SHAPE_TRANS, ghostdata, fadingdata, 1, predoffset);
}
else {
if (flags & SHAPE_FADING) {
Buffer_Frame_To_Page(x, y, width, height, image, window, flags | SHAPE_TRANS, fadingdata, 1, predoffset);
Buffer_Frame_To_Page(shapenum, x, y, width, height, image, window, flags | SHAPE_TRANS, fadingdata, 1, predoffset);
}
else {
if (flags & SHAPE_PREDATOR) {
Buffer_Frame_To_Page(x, y, width, height, image, window, flags | SHAPE_TRANS, predoffset);
Buffer_Frame_To_Page(shapenum, x, y, width, height, image, window, flags | SHAPE_TRANS, predoffset);
}
else {
Buffer_Frame_To_Page(x, y, width, height, image, window, flags | SHAPE_TRANS, ghostdata, predoffset);
Buffer_Frame_To_Page(shapenum, x, y, width, height, image, window, flags | SHAPE_TRANS, ghostdata, predoffset);
}
}
}
@@ -3785,15 +3786,15 @@ void CC_Draw_Shape(void const * shapefile, int shapenum, int x, int y, WindowNum
{
if ((flags & (SHAPE_GHOST|SHAPE_FADING)) == (SHAPE_GHOST|SHAPE_FADING)) {
Buffer_Frame_To_Page(x, y, width, height, shape_image, window, flags | SHAPE_TRANS, ghostdata, fadingdata, 1, predoffset);
Buffer_Frame_To_Page(-1, x, y, width, height, shape_image, window, flags | SHAPE_TRANS, ghostdata, fadingdata, 1, predoffset);
} else {
if (flags & SHAPE_FADING) {
Buffer_Frame_To_Page(x, y, width, height, shape_image, window, flags | SHAPE_TRANS, fadingdata, 1, predoffset);
Buffer_Frame_To_Page(-1, x, y, width, height, shape_image, window, flags | SHAPE_TRANS, fadingdata, 1, predoffset);
} else {
if (flags & SHAPE_PREDATOR) {
Buffer_Frame_To_Page(x, y, width, height, shape_image, window, flags | SHAPE_TRANS, predoffset);
Buffer_Frame_To_Page(-1, x, y, width, height, shape_image, window, flags | SHAPE_TRANS, predoffset);
} else {
Buffer_Frame_To_Page(x, y, width, height, shape_image, window, flags | SHAPE_TRANS, ghostdata, predoffset);
Buffer_Frame_To_Page(-1, x, y, width, height, shape_image, window, flags | SHAPE_TRANS, ghostdata, predoffset);
}
}
}
+3 -3
View File
@@ -229,11 +229,11 @@ void Console_Printf(const char* fmt, ...) {
vsprintf(msg, fmt, argptr);
va_end(argptr);
int len = strlen(msg);
strcpy(&console_text[console_text_len], msg);
//int len = strlen(msg);
//strcpy(&console_text[console_text_len], msg);
OutputDebugStringA(msg);
console_text_len += len;
//console_text_len += len;
}
/*
+7
View File
@@ -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");
+4
View File
@@ -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];
+13 -1
View File
@@ -710,7 +710,7 @@ void Buffer_Enable_HD_Texture(bool hdTextureEnabled);
/*
** KEYFBUFF.ASM
*/
long __cdecl Buffer_Frame_To_Page(int x, int y, int w, int h, Image_t* image, unsigned int Window, int flags, ...);
long __cdecl Buffer_Frame_To_Page(int shapeNum, int x, int y, int w, int h, Image_t* image, unsigned int Window, int flags, ...);
/*
** KEYFRAME.CPP
@@ -1180,7 +1180,19 @@ __forceinline void COM_SetExtension(char* path, int maxSize, const char* extensi
sprintf(path, "%s%s", oldPath, extension);
}
void Tileset_LoadRules(void);
void Buildings_LoadRules(void);
void Units_LoadRules(void);
const char* Tileset_FindHDTexture(int theaterType, const char* shapeFileName, int shapeNum, int frameNum);
int Tileset_GetNumFramesForTile(int theaterType, const char* shapeFileName, int shapeNum);
int Buildings_GetNumFramesForTile(const char* shapeFileName, int shapeNum);
const char* Buildings_FindHDTexture(const char* shapeFileName, int shapeNum, int frameNum);
int Units_GetNumFramesForTile(const char* shapeFileName, int shapeNum);
const char* Units_FindHDTexture(const char* shapeFileName, int shapeNum, int frameNum);
extern bool g_inMainMenu;
extern KeyNumType g_globalKeyNumType;
extern int g_globalKeyFlags;
extern float animFrameNum;
#endif
+20 -11
View File
@@ -1,34 +1,43 @@
// Image.h
//
#define MAX_IMAGE_FRAMES 256
#define MAX_IMAGE_SHAPES 256
#define MAX_IMAGE_FRAMES 12
#define MAX_HOUSE_COLORS 8
struct HouseImage_t {
unsigned int image[MAX_IMAGE_SHAPES][MAX_IMAGE_FRAMES];
};
struct Image_t {
Image_t();
~Image_t();
char name[512];
int64_t namehash;
unsigned int image[MAX_HOUSE_COLORS][MAX_IMAGE_FRAMES];
HouseImage_t HouseImages[MAX_HOUSE_COLORS];
unsigned int numAnimFrames;
int width;
int height;
int renderwidth;
int renderheight;
//unsigned char* buffer[MAX_HOUSE_COLORS][MAX_IMAGE_FRAMES];
int renderwidth[MAX_IMAGE_SHAPES];
int renderheight[MAX_IMAGE_SHAPES];
bool perFrameRenderDimen;
int numFrames;
void* IconMapPtr;
};
__forceinline Image_t::Image_t() {
// buffer = NULL;
IconMapPtr = NULL;
numAnimFrames = 0;
perFrameRenderDimen = false;
memset(HouseImages, 0, sizeof(HouseImages));
}
__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);
bool Image_Add32BitImage(const char* name, Image_t* image, int HouseId, int ShapeID, int frameId);
+6
View File
@@ -425,6 +425,12 @@ int MapEditClass::Placement_Dialog(void)
*/
Call_Back();
g_globalKeyNumType = KN_NONE;
g_globalKeyFlags = 0;
UserInput.Process_Input();
Device_Present();
/*
** Refresh display if needed
*/
+4165 -1098
View File
File diff suppressed because it is too large Load Diff
+32 -1
View File
@@ -11,15 +11,46 @@ extern "C" {
# include "lualib.h"
}
// Object Cache Item
// Stores an id lookup table
struct MapScriptObject {
int ID=-1; // The object's "Global ID"
int classIndex=-1; // The object's "Global ID"
RTTIType RTTI; // The type of object
};
//
// MapScript
// MapScript Class
//
class MapScript {
public:
~MapScript() { Deinit(); };
bool Init(const char* mapName);
void Deinit();
void CallFunction(const char* functionName);
void SetLuaPath(const char* input_path);
std::vector<MapScriptObject*> ObjectCache;
private:
lua_State* L;
};
// Non-Class-Functions
bool Script_SetObjectTrigger(int input_object_id, TriggerClass* input_trigger);
ObjectClass* Script_GetCacheObject(int input_object_id);
int Script_BuildingIndexFromID(int input_object_id);
int Script_UnitIndexFromID(int input_object_id);
int Script_AircraftIndexFromID(int input_object_id);
int Script_InfantryIndexFromID(int input_object_id);
int Script_VesselIndexFromID(int input_object_id);
#endif
+12 -2
View File
@@ -18,10 +18,20 @@ 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);
if (image->numFrames > 0) {
if(image->HouseImages[colorRemap].image[shapeId][((int)animFrameNum) % image->numFrames] == 0)
ImGui::GetForegroundDrawList()->AddImage((ImTextureID)image->HouseImages[colorRemap].image[shapeId][0], mi, ma);
else
ImGui::GetForegroundDrawList()->AddImage((ImTextureID)image->HouseImages[colorRemap].image[shapeId][((int)animFrameNum) % image->numFrames], mi, ma);
}
else {
ImGui::GetForegroundDrawList()->AddImage((ImTextureID)image->HouseImages[colorRemap].image[shapeId][0], mi, ma);
}
}
void GL_FillRect(int color, int x, int y, int width, int height) {
+1 -1
View File
@@ -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);
+5
View File
@@ -387,6 +387,11 @@ int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int
#endif
// Load all of the XML files.
Tileset_LoadRules();
Buildings_LoadRules();
Units_LoadRules();
if (Parse_Command_Line(argc, argv)) {
#if(TEN)
+2 -2
View File
@@ -1396,7 +1396,7 @@ static void Single_Line_Flagger(
}
}
long Buffer_Frame_To_Page(int x, int y, int width, int height, struct Image_t * shape_image, unsigned int Window, int flags, ...)
long Buffer_Frame_To_Page(int shapeNum, int x, int y, int width, int height, struct Image_t * shape_image, unsigned int Window, int flags, ...)
{
BOOL use_old_drawer = false;
int fade_count = 0;
@@ -1547,7 +1547,7 @@ long Buffer_Frame_To_Page(int x, int y, int width, int height, struct Image_t *
ystart = ystart + WindowList[Window][WINDOWY];// + LogicPage->Get_YPos();
//GL_SetClipRect(WindowList[Window][WINDOWX], WindowList[Window][WINDOWY], WindowList[Window][WINDOWWIDTH], WindowList[Window][WINDOWWIDTH]);
if(renderHDTexture)
GL_RenderImage(shape_image, xstart, ystart, width, height, (int)fade_table);
GL_RenderImage(shape_image, xstart, ystart, width, height, (int)fade_table, shapeNum);
else
GL_RenderImage(shape_image, xstart, ystart, width, height, 0);
+15
View File
@@ -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,20 @@ void TerrainTypeClass::Init(TheaterType theater)
_makepath(fullname, NULL, NULL, terrain.IniName, Theaters[theater].Suffix);
((void const *&)terrain.ImageData) = MFCD::Retrieve(fullname);
// Try and load HD assets first.
Image_t* hdImage = Load_StampHD(theater, fullname, terrain.ImageData);
if (hdImage)
{
Get_Stamp_Size(terrain.ImageData, hdImage->renderwidth, hdImage->renderheight);
((void const*&)terrain.HDImageData) = hdImage;
}
else
{
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);
+137 -42
View File
@@ -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,146 @@ void __cdecl Buffer_Draw_Stamp2(GraphicViewPortClass& viewport, IconControlType*
}
}
Image_t* Load_StampHD(int theater, const char* iconName, const void* icondata) {
char filename[2048];
Image_t* image = NULL;
IconControlType* tileset = (IconControlType*)icondata;
if (!tileset) {
return NULL;
}
if (LastIconset != tileset) {
Init_Stamps(tileset);
}
// This is because were trying to avoid parsing the XML's and the filenames aren't consistant.
const char* theaterName = Theaters[theater].Name;
for (int i = 0; i < IconCount; i++)
{
char filename[512];
char fixedIconName[512];
strcpy(fixedIconName, iconName);
COM_SetExtension(fixedIconName, strlen(fixedIconName), "");
int numFrames = Tileset_GetNumFramesForTile(theater, fixedIconName, i);
for (int d = 0; d < numFrames; d++)
{
const char* tileEntryName = Tileset_FindHDTexture(theater, fixedIconName, i, d);
sprintf(filename, "DATA/ART/TEXTURES/SRGB/RED_ALERT/TERRAIN/%s/%s", Theaters[theater].Name, tileEntryName);
COM_SetExtension(filename, sizeof(filename), ".dds");
if (image == NULL) {
image = Image_LoadImage(filename);
if (image != NULL && i != 0) {
image->HouseImages[0].image[i][d] = image->HouseImages[0].image[0][d];
image->HouseImages[0].image[0][d] = 0;
}
if (image != NULL) {
image->numFrames = numFrames;
}
}
else {
if (!Image_Add32BitImage(filename, image, -1, i, d)) {
continue;
}
}
}
}
//if (image) {
// image->IconMapPtr = MapPtr;
//}
return image;
}
void Get_Stamp_Size(const void* icondata, int* width, int* height) {
IconControlType* tileset = (IconControlType*)icondata;
if (!tileset) {
for (int i = 0; i < MAX_IMAGE_SHAPES; i++) {
*width = -1;
*height = -1;
}
return;
}
if (LastIconset != tileset) {
Init_Stamps(tileset);
}
for (int i = 0; i < MAX_IMAGE_SHAPES; i++) {
width[i] = IconWidth;
height[i] = IconHeight;
}
}
Image_t * 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) {
int blit_height = IconHeight;
int blit_width = IconWidth;
uint8_t* src = &StampPtr[IconSize * icon_index];
Image_t* iconImage = (Image_t*)icondata;
uint8_t* MapPtr = (uint8_t * )iconImage->IconMapPtr;
int icon_index = MapPtr != nullptr ? MapPtr[icon] : icon;
{
int blit_height = iconImage->renderheight[0];
int blit_width = iconImage->renderwidth[0];
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 +343,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;
}
@@ -307,8 +399,11 @@ void __cdecl Buffer_Draw_Stamp_Clip2(GraphicViewPortClass& viewport, const void
// src += IconWidth;
//}
if (iconImage->HouseImages[0].image[icon_index] == 0)
return;
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();
}
}
+89
View File
@@ -0,0 +1,89 @@
// TILESETXML.CPP
//
#include "FUNCTION.H"
#include "tinyxml2.h"
#include <string>
#include <vector>
int64_t generateHashValue(const char* fname, const int size);
struct TilesetTileRule_t {
std::string name;
int64_t hash;
int shape;
std::vector<std::string> frames;
};
struct TilesetXMLInfo_t {
std::vector< TilesetTileRule_t> tiles;
};
TilesetXMLInfo_t theaterXMLRules[3];
const char* Tileset_FindHDTexture(int theaterType, const char* shapeFileName, int shapeNum, int frameNum) {
int64_t hash = generateHashValue(shapeFileName, strlen(shapeFileName));
for (int i = 0; i < theaterXMLRules[theaterType].tiles.size(); i++) {
if (theaterXMLRules[theaterType].tiles[i].hash == hash && theaterXMLRules[theaterType].tiles[i].shape == shapeNum) {
return theaterXMLRules[theaterType].tiles[i].frames[frameNum].c_str();
}
}
return NULL;
}
int Tileset_GetNumFramesForTile(int theaterType, const char* shapeFileName, int shapeNum) {
int64_t hash = generateHashValue(shapeFileName, strlen(shapeFileName));
for (int i = 0; i < theaterXMLRules[theaterType].tiles.size(); i++) {
if (theaterXMLRules[theaterType].tiles[i].hash == hash && theaterXMLRules[theaterType].tiles[i].shape == shapeNum) {
return theaterXMLRules[theaterType].tiles[i].frames.size();
}
}
return 0;
}
void Tileset_ParseTile(tinyxml2::XMLNode* tile, TilesetTileRule_t& tileRule) {
tinyxml2::XMLNode* KeyNode = tile->FirstChildElement("Key");
tinyxml2::XMLNode* NameNode = KeyNode->FirstChildElement("Name");
tinyxml2::XMLNode* ShapeNode = KeyNode->FirstChildElement("Shape");
tinyxml2::XMLNode* ValueNode = tile->FirstChildElement("Value");
tinyxml2::XMLNode* FramesNode = ValueNode->FirstChildElement("Frames");
tinyxml2::XMLNode* FrameNode = FramesNode->FirstChildElement("Frame");
tileRule.name = NameNode->FirstChild()->ToText()->Value();
tileRule.hash = generateHashValue(tileRule.name.c_str(), tileRule.name.size());
tileRule.shape = atoi(ShapeNode->FirstChild()->ToText()->Value());
while (FrameNode != NULL) {
tileRule.frames.push_back(FrameNode->FirstChild()->ToText()->Value());
FrameNode = FrameNode->NextSiblingElement("Frame");
}
}
void Tileset_LoadRuleXML(const char* path, TilesetXMLInfo_t& info) {
tinyxml2::XMLDocument doc;
doc.LoadFile(path);
tinyxml2::XMLElement* root = doc.FirstChildElement();
if (root == NULL)
return;
tinyxml2::XMLNode* tilesetTypeClassNode = root->FirstChild();
tinyxml2::XMLNode* tilesParent = tilesetTypeClassNode->FirstChildElement("Tiles");
tinyxml2::XMLNode* tile = tilesParent->FirstChildElement("Tile");
while (tile != NULL) {
TilesetTileRule_t tileRule;
Tileset_ParseTile(tile, tileRule);
info.tiles.push_back(tileRule);
tile = tile->NextSiblingElement("Tile");
}
}
void Tileset_LoadRules(void) {
for (int i = 0; i < 3; i++) {
char tmp[512];
sprintf(tmp, "data/xml/tilesets/ra_terrain_%s.xml", Theaters[i].Name);
Tileset_LoadRuleXML(tmp, theaterXMLRules[i]);
}
}
-1
View File
@@ -42,7 +42,6 @@ class MapEditClass;
class HouseClass;
class WeaponTypeClass;
/***************************************************************************
** This is the abstract type class. It holds information common to all
** objects that might exist. This contains the name of the object type.
+43 -1
View File
@@ -48,6 +48,7 @@
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include "image.h"
/*
** This is the list of animation stages to use when the harvester
@@ -1113,10 +1114,51 @@ void UnitTypeClass::One_Time(void)
((void const *&)uclass.ImageData) = ptr;
if (ptr != NULL) {
largest = max(largest, (int)Get_Build_Frame_Width(ptr));
largest = max(largest, (int)Get_Build_Frame_Height(ptr));
}
{
const char* imageFileName = Units_FindHDTexture(fullname, 0, 0);
if (imageFileName) {
Image_t* image = Image_LoadImage(imageFileName, true, true);
int numUnitsAnims = Units_GetNumFramesForTile(fullname, 0);
int shapeId = 1;
// Load the old school animation pipeline.
{
while (true) {
imageFileName = Units_FindHDTexture(fullname, shapeId, 0);
if (imageFileName == NULL)
break;
for (int d = 0; d < MAX_MPLAYER_COLORS; d++) {
Image_Add32BitImage(imageFileName, image, d, shapeId, 0);
}
shapeId++;
}
}
for (int d = 0; d < shapeId; d++) {
image->renderwidth[d] = image->renderwidth[d] / 5;
image->renderheight[d] = image->renderheight[d] / 5;
}
if (numUnitsAnims > 0)
{
for (int i = 1; i < numUnitsAnims; i++) {
imageFileName = Units_FindHDTexture(fullname, 0, i);
for (int d = 0; d < MAX_MPLAYER_COLORS; d++) {
Image_Add32BitImage(imageFileName, image, d, 0, i);
}
}
}
image->numFrames = numUnitsAnims;
((void const*&)uclass.HDImageData) = image;
}
}
((int &)uclass.MaxSize) = max(largest, 8);
}
+32 -5
View File
@@ -2051,11 +2051,13 @@ void UnitClass::Draw_It(int x, int y, WindowNumberType window) const
int tfacing = Dir_To_32(SecondaryFacing);
DirType rotation = DIR_N;
int scale = 0x0100;
Image_t* hdShapeFile;
/*
** Verify the legality of the unit class.
*/
shapefile = Get_Image_Data();
hdShapeFile = Get_HDImage_Data();
if (shapefile == NULL) return;
/*
@@ -2076,7 +2078,12 @@ void UnitClass::Draw_It(int x, int y, WindowNumberType window) const
/*
** Actually perform the draw. Overlay an optional shimmer effect as necessary.
*/
Techno_Draw_Object(shapefile, shapenum, x, y, window, rotation, scale);
if (hdShapeFile) {
Techno_Draw_Object_HD(hdShapeFile, shapenum, x, y, window, rotation, scale);
}
else {
Techno_Draw_Object(shapefile, shapenum, x, y, window, rotation, scale);
}
/*
** If there is a rotating radar dish, draw it now.
@@ -2086,7 +2093,12 @@ void UnitClass::Draw_It(int x, int y, WindowNumberType window) const
int x2 = x, y2 = y;
shapenum = 32 + (Frame & 7);
Class->Turret_Adjust(PrimaryFacing, x2, y2);
Techno_Draw_Object(shapefile, shapenum, x2, y2, window);
if (hdShapeFile) {
Techno_Draw_Object_HD(hdShapeFile, shapenum, x, y, window);
}
else {
Techno_Draw_Object(shapefile, shapenum, x2, y2, window);
}
} else {
//#ifdef FIXIT_PHASETRANSPORT // checked - ajw 9/28/98
// if (*this == UNIT_PHASE) {
@@ -2099,9 +2111,19 @@ void UnitClass::Draw_It(int x, int y, WindowNumberType window) const
//#endif
#ifdef FIXIT_CSII // checked - ajw 9/28/98
if (*this == UNIT_TESLATANK) {
Techno_Draw_Object(shapefile, shapenum, x, y, window);
if (hdShapeFile) {
Techno_Draw_Object_HD(hdShapeFile, shapenum, x, y, window);
}
else {
Techno_Draw_Object(shapefile, shapenum, x, y, window);
}
} else {
Techno_Draw_Object(shapefile, shapenum, x, y-5, window);
if (hdShapeFile) {
Techno_Draw_Object_HD(hdShapeFile, shapenum, x, y - 5, window);
}
else {
Techno_Draw_Object(shapefile, shapenum, x, y - 5, window);
}
}
#else
Techno_Draw_Object(shapefile, shapenum, x, y-5, window);
@@ -2139,7 +2161,12 @@ void UnitClass::Draw_It(int x, int y, WindowNumberType window) const
/*
** Actually perform the draw. Overlay an optional shimmer effect as necessary.
*/
Techno_Draw_Object(shapefile, shapenum, xx, yy, window);
if (hdShapeFile) {
Techno_Draw_Object_HD(hdShapeFile, shapenum, xx, yy - 4, window); // jmarshall - 4 pixel offset for turrets feels wrong, but visually looks alright.
}
else {
Techno_Draw_Object(shapefile, shapenum, xx, yy, window);
}
}
}
+99
View File
@@ -0,0 +1,99 @@
// UNITXML.CPP
//
#include "FUNCTION.H"
#include "tinyxml2.h"
#include <string>
#include <vector>
int64_t generateHashValue(const char* fname, const int size);
struct UnitsTileRule_t {
std::string name;
int64_t hash;
int shape;
std::vector<std::string> frames;
};
struct UnitsXMLInfo_t {
std::vector<UnitsTileRule_t> tiles;
};
UnitsXMLInfo_t unitsXmlRules;
const char* Units_FindHDTexture(const char* shapeFileName, int shapeNum, int frameNum) {
char tmpFileName[2048];
strcpy(tmpFileName, shapeFileName);
COM_SetExtension(tmpFileName, strlen(tmpFileName), "");
int64_t hash = generateHashValue(tmpFileName, strlen(tmpFileName));
for (int i = 0; i < unitsXmlRules.tiles.size(); i++) {
if (unitsXmlRules.tiles[i].hash == hash && unitsXmlRules.tiles[i].shape == shapeNum) {
static char hdTexturePath[2048];
if (unitsXmlRules.tiles[i].frames.size() == 0)
return NULL;
sprintf(hdTexturePath, "DATA/ART/TEXTURES/SRGB/RED_ALERT/UNITS/%s", unitsXmlRules.tiles[i].frames[frameNum].c_str());
return &hdTexturePath[0];
}
}
return NULL;
}
int Units_GetNumFramesForTile(const char* shapeFileName, int shapeNum) {
char tmpFileName[2048];
strcpy(tmpFileName, shapeFileName);
COM_SetExtension(tmpFileName, strlen(tmpFileName), "");
int64_t hash = generateHashValue(tmpFileName, strlen(tmpFileName));
for (int i = 0; i < unitsXmlRules.tiles.size(); i++) {
if (unitsXmlRules.tiles[i].hash == hash && unitsXmlRules.tiles[i].shape == shapeNum) {
return unitsXmlRules.tiles[i].frames.size();
}
}
return 0;
}
void Units_ParseTile(tinyxml2::XMLNode* tile, UnitsTileRule_t& tileRule) {
tinyxml2::XMLNode* KeyNode = tile->FirstChildElement("Key");
tinyxml2::XMLNode* NameNode = KeyNode->FirstChildElement("Name");
tinyxml2::XMLNode* ShapeNode = KeyNode->FirstChildElement("Shape");
tinyxml2::XMLNode* ValueNode = tile->FirstChildElement("Value");
tinyxml2::XMLNode* FramesNode = ValueNode->FirstChildElement("Frames");
tinyxml2::XMLNode* FrameNode = FramesNode->FirstChildElement("Frame");
tileRule.name = NameNode->FirstChild()->ToText()->Value();
tileRule.hash = generateHashValue(tileRule.name.c_str(), tileRule.name.size());
tileRule.shape = atoi(ShapeNode->FirstChild()->ToText()->Value());
while (FrameNode != NULL) {
if (FrameNode->FirstChild() != NULL) {
tileRule.frames.push_back(FrameNode->FirstChild()->ToText()->Value());
}
FrameNode = FrameNode->NextSiblingElement("Frame");
}
}
void Units_LoadRuleXML(const char* path, UnitsXMLInfo_t& info) {
tinyxml2::XMLDocument doc;
doc.LoadFile(path);
tinyxml2::XMLElement* root = doc.FirstChildElement();
if (root == NULL)
return;
tinyxml2::XMLNode* tilesetTypeClassNode = root->FirstChild();
tinyxml2::XMLNode* tilesParent = tilesetTypeClassNode->FirstChildElement("Tiles");
tinyxml2::XMLNode* tile = tilesParent->FirstChildElement("Tile");
while (tile != NULL) {
UnitsTileRule_t tileRule;
Units_ParseTile(tile, tileRule);
info.tiles.push_back(tileRule);
tile = tile->NextSiblingElement("Tile");
}
}
void Units_LoadRules(void) {
Units_LoadRuleXML("data/xml/tilesets/RA_UNITS.XML", unitsXmlRules);
}
+6
View File
@@ -61,6 +61,12 @@ extern "C" {
void * __cdecl Get_Font_Palette_Ptr ( void );
}
struct Image_t;
Image_t* Load_Stamp(const char* name, const void* icondata);
void Get_Stamp_Size(const void* icondata, int *width, int *height);
Image_t* Load_StampHD(int theater, const char* iconName, const void *icondata);
extern GraphicViewPortClass *LogicPage;
extern BOOL AllowHardwareBlitFills;
#endif
+1 -1
View File
@@ -252,7 +252,7 @@ void WWMouseClass::RenderMouse(void) {
ImGui::SetMouseCursor(ImGuiMouseCursor_None);
ImGui::GetForegroundDrawList()->AddImage((ImTextureID)current_cursor->image[0][0], mi, ma);
ImGui::GetForegroundDrawList()->AddImage((ImTextureID)current_cursor->HouseImages[0].image[0][0], mi, ma);
}
void WWMouseClass::Low_Show_Mouse(int x, int y)
+103 -20
View File
@@ -77,6 +77,7 @@ SurfaceMonitorClass AllSurfaces;
SDL_Window* game_window;
SDL_GLContext game_context;
int OverlappedVideoBlits = 0;
float animFrameNum = 0;
extern std::vector<const ObjectClass*> renderedFrameObjects;
@@ -102,7 +103,7 @@ unsigned char* Draw_Dropsample(const unsigned char* in, int inwidth, int inheigh
return a hash value for the filename
================
*/
static int64_t generateHashValue(const char* fname, const int size) {
int64_t generateHashValue(const char* fname, const int size) {
uint32_t hash = 0x811c9dc5;
uint32_t prime = 0x1000193;
@@ -157,18 +158,18 @@ void Image_WriteTGA(const char* filename, const byte* data, int width, int heigh
}
static char* Image_GetGeneratedName(Image_t* image, const char* name, int houseid, int animid, int64_t hash) {
static char* Image_GetGeneratedName(Image_t* image, const char* name, int houseid, int animid, int frameId, int64_t hash) {
static char generatedFileName[1024];
sprintf(generatedFileName, "cache/%d.%d.%d.tga", hash, houseid, animid);
sprintf(generatedFileName, "cache/v4.%d.%d.%d.%d.tga", frameId, houseid, animid, hash);
return &generatedFileName[0];
}
static bool Image_loadHDImage(Image_t *image, const char* name, int houseid, int animid, int64_t hash, bool writeGenerated) {
static bool Image_loadHDImage(Image_t *image, const char* name, int houseid, int animid, int frameId, int64_t hash, bool writeGenerated) {
// Check to see if we can load a generated image first.
// We only generate images that need a houseid
if (!writeGenerated && houseid >= 0) {
char* generatedImageName = Image_GetGeneratedName(image, name, houseid, animid, hash);
if (Image_loadHDImage(image, generatedImageName, houseid, animid, hash, true)) {
char* generatedImageName = Image_GetGeneratedName(image, name, houseid, animid, frameId, hash);
if (Image_loadHDImage(image, generatedImageName, houseid, animid, frameId, hash, true)) {
return true;
}
}
@@ -182,9 +183,12 @@ static bool Image_loadHDImage(Image_t *image, const char* name, int houseid, int
}
bool swapBGR = false;
if (strstr(name, ".TGA")) {
iluFlipImage();
swapBGR = true;
if (strstr(name, ".TGA") || strstr(name, ".tga")) {
if (!writeGenerated)
{
iluFlipImage();
swapBGR = true;
}
}
ILuint Width, Height, Bpp;
@@ -233,18 +237,21 @@ static bool Image_loadHDImage(Image_t *image, const char* name, int houseid, int
strcpy(image->name, name);
if(houseid == -1)
image->image[0][animid] = texture;
image->HouseImages[0].image[animid][frameId] = texture;
else
image->image[houseid][animid] = texture;
image->HouseImages[houseid].image[animid][frameId] = texture;
image->namehash = hash;
image->renderwidth = image->width = Width;
image->renderheight = image->height = Height;
image->renderwidth[animid] = image->width = Width;
image->renderheight[animid] = image->height = Height;
//image->buffer[houseid][animid] = new unsigned char[Width * Height * Bpp];
//memcpy(image->buffer[houseid][animid], Data, Width * Height * Bpp);
if (!writeGenerated && Bpp == 4 && houseid >= 0) {
char* generatedImageName = Image_GetGeneratedName(image, name, houseid, animid, hash);
char* generatedImageName = Image_GetGeneratedName(image, name, houseid, animid, frameId, hash);
Image_WriteTGA(generatedImageName, Data, Width, Height, false);
Console_Printf("Writing %s to cache %s\n", image->name, name);
Sleep(0);
}
ilDeleteImages(1, &ImageName);
@@ -271,7 +278,7 @@ Image_t* Image_LoadImage(const char* name, bool loadAnims, bool loadHouseColor)
if (!loadAnims) {
unsigned char remap[3] = { 0, 0, 0 };
if (!Image_loadHDImage(image, name, -1, 0, hash, false)) {
if (!Image_loadHDImage(image, name, -1, 0, 0, hash, false)) {
delete image;
return NULL;
}
@@ -279,7 +286,7 @@ Image_t* Image_LoadImage(const char* name, bool loadAnims, bool loadHouseColor)
else {
byte* palette = (byte *)CCPalette.Get_Data();
for (int i = 0; i < MAX_MPLAYER_COLORS; i++) {
if (!Image_loadHDImage(image, name, i, 0, hash, false)) {
if (!Image_loadHDImage(image, name, i, 0, 0, hash, false)) {
delete image;
return NULL;
}
@@ -290,6 +297,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));
@@ -350,16 +376,73 @@ Image_t* Image_CreateImageFrom8Bit(const char* name, int Width, int Height, unsi
strcpy(image->name, name);
image->image[0][0] = texture;
image->HouseImages[0].image[0][0] = texture;
image->numAnimFrames = -1;
image->namehash = hash;
image->renderwidth = image->width = Width;
image->renderheight = image->height = Height;
image->renderwidth[0] = image->width = Width;
image->renderheight[0] = image->height = Height;
loaded_images.push_back(image);
delete buffer;
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->HouseImages[HouseId].image[ShapeID][0] = texture;
image->numAnimFrames = -1;
image->renderwidth[ShapeID] = image->width = Width;
image->renderheight[ShapeID] = image->height = Height;
delete buffer;
}
bool Image_Add32BitImage(const char *name, Image_t* image, int HouseId, int ShapeID, int frameId) {
return Image_loadHDImage(image, name, HouseId, ShapeID, frameId, image->namehash, false);
}
BOOL Set_Video_Mode(HWND hwnd, int w, int h, int bits_per_pixel) {
// Todo implement resoluton scaling.
@@ -450,7 +533,7 @@ void Device_Present(void) {
// Last thing we do is execute any console commands
Console_Tick();
ImGui_NewFrame();
ImGui_NewFrame();
}
+1 -1
View File
@@ -1684,7 +1684,7 @@ void UnitTypeClass::One_Time(void)
}
#endif //PETROGLYPH_EXAMPLE_MOD
((void const *&)uclass.ImageData) = ptr;
((void const *&)uclass.ImageData) = ptr;
if (ptr) {
if (index == UNIT_MLRS || index == UNIT_MSAM) {
+2951
View File
File diff suppressed because it is too large Load Diff
+2376
View File
File diff suppressed because it is too large Load Diff
+196
View File
@@ -0,0 +1,196 @@
-- *=======================================================*
-- * *
-- * Mapscript Global Helper Header *
-- * *
-- *=======================================================*
-- *********************************************************
-- * *
-- * Buildings *
-- * *
-- *********************************************************
BUILDING_ATEK=0 -- Allied Technology Centre
BUILDING_IRON=1 -- Iron Curtain
BUILDING_WEAP=2 -- Weapons Factory
BUILDING_PDOX=3 -- Chronosphere
BUILDING_PBOX=4 -- Pillbox
BUILDING_HBOX=5 -- Camouflaged Pillbox
BUILDING_DOME=6 -- Radar Dome
BUILDING_GAP =7 -- Gap Generator
BUILDING_GUN =8 -- Gun Turret
BUILDING_AGUN=9 -- Anti-Aircraft Gun
BUILDING_FTUR=10 -- Flame Turret
BUILDING_FACT=11 -- Construction Yard
BUILDING_PROC=12 -- Ore Refinery
BUILDING_SILO=13 -- Ore Silo
BUILDING_HPAD=14 -- Helicopter Pad
BUILDING_SAM =15 -- SAM Site
BUILDING_AFLD=16 -- Airfield
BUILDING_POWR=17 -- Power Plant
BUILDING_APWR=18 -- Advanced Power Plant
BUILDING_STEK=19 -- Soviet Technology Centre
BUILDING_HOSP=20 -- Hospital
BUILDING_BARR=21 -- Barracks (Allied)
BUILDING_TENT=22 -- Barracks (Soviet)
BUILDING_KENN=23 -- Dog Kennel
BUILDING_FIX =24 -- Service Depot
BUILDING_BIO =25 -- Bio-Research Laboratory
BUILDING_MISS=26 -- Technology Centre/Prison
BUILDING_SYRD=27 -- Ship Yard
BUILDING_SPEN=28 -- Sub Pen
BUILDING_MSLO=29 -- Missile Silo
BUILDING_FCOM=30 -- Forward Command Post
BUILDING_TSLA=31 -- Tesla Coil
BUILDING_WEAF=32 -- Fake Weapons Factory
BUILDING_FACF=33 -- Fake Construction Yard
BUILDING_SYRF=34 -- Fake Ship Yard
BUILDING_SPEF=35 -- Fake Sub Pen
BUILDING_DOMF=36 -- Fake Radar Dome
BUILDING_MINV=43 -- Anti-vehicle mine
BUILDING_MINP=44 -- Anti-personnel mine
-- Counterstrike
BUILDING_QUEE=84 -- Queen ant structure
BUILDING_LAR1=85 -- Ant - single ant larva
BUILDING_LAR2=86 -- Ant - two ant larvae
-- *********************************************************
-- * *
-- * Infantry *
-- * *
-- *********************************************************
INFANTRY_E1=0 -- Rifle Infantry
INFANTRY_E2=1 -- Grenadier
INFANTRY_E3=2 -- Rocket Soldier
INFANTRY_E4=3 -- Flamethrower
INFANTRY_E6=4 -- Engineer
INFANTRY_E7=5 -- Tanya
INFANTRY_SPY=6 -- Spy
INFANTRY_THF=7 -- Thief
INFANTRY_MEDI=8 -- Field Medic
INFANTRY_GNRL=9 -- General
INFANTRY_DOG=10 -- Attack Dog
INFANTRY_C1=11 -- Joe
INFANTRY_C2=12 -- Barry
INFANTRY_C3=13 -- Shelly
INFANTRY_C4=14 -- Maria
INFANTRY_C5=15 -- Karen
INFANTRY_C6=16 -- Steve
INFANTRY_C7=17 -- Phil
INFANTRY_C8=18 -- Dwight
INFANTRY_C9=19 -- Erik
INFANTRY_C10=20 -- Scientist
INFANTRY_EINSTEIN=21 -- Prof. Einstein
INFANTRY_DELPHI=22 -- Special 1
INFANTRY_CHAN=23 -- Special 2
-- *********************************************************
-- * *
-- * Vehicle *
-- * *
-- *********************************************************
VEHICLE_4TNK=0 -- Mammoth Tank
VEHICLE_3TNK=1 -- Heavy Tank
VEHICLE_2TNK=2 -- Medium Tank
VEHICLE_1TNK=3 -- Light Tank
VEHICLE_APC=4 -- Armoured Personnel Carrier
VEHICLE_MNLY=5 -- Mine Layer
VEHICLE_JEEP=6 -- Ranger
VEHICLE_HARV=7 -- Ore Truck
VEHICLE_ARTY=8 -- Artillery
VEHICLE_MRJ=9 -- Mobile Radar Jammer
VEHICLE_MGG=10 -- Mobile Gap Generator
VEHICLE_MCV=11 -- Mobile Construction Vehicle
VEHICLE_2VRL=12 -- V2 Rocket Launcher
VEHICLE_TRUK=13 -- Convoy Truck
-- Counterstrike only:
VEHICLE_ANT1=14 -- First ant type
VEHICLE_ANT2=15 -- Second ant type
VEHICLE_ANT3=16 -- Third ant type
-- *********************************************************
-- * *
-- * Aircraft *
-- * *
-- *********************************************************
AIRCRAFT_TRAN=0 -- Chinook Helicopter
AIRCRAFT_BADR=1 -- Badger Bomber
AIRCRAFT_U2=2 -- Spy Plane
AIRCRAFT_MIG=3 -- MIG Attack Plane
AIRCRAFT_YAK=4 -- Yak Attack Plane
AIRCRAFT_HELI=5 -- Longbow Helicopter
AIRCRAFT_HIND=6 -- Hind Helicopter
-- *********************************************************
-- * *
-- * Houses (players) *
-- * *
-- *********************************************************
HOUSE_SPAIN= 0 -- YELLOW/GOLD
HOUSE_GREECE=1 -- BLUE-GREY
HOUSE_USSR=2 -- RED
HOUSE_ENGLAND=3 -- GREEN
HOUSE_UKRAINE=4 -- ORANGE
HOUSE_GERMANY=5 -- KHAKI/LIGHT BROWN
HOUSE_FRANCE=6 -- AQUA
HOUSE_TURKEY=7 -- RED-OCHRE
HOUSE_GOODGUY=8 -- BLUE-GREY
HOUSE_BADGUY=9 -- RED
HOUSE_NEUTRAL=10 -- YELLOW/GOLD
HOUSE_SPECIAL=11 -- YELLOW/GOLD
HOUSE_MULTI1=12 -- YELLOW/GOLD
HOUSE_MULTI2=13 -- BLUE-GREY
HOUSE_MULTI3=14 -- RED
HOUSE_MULTI4=15 -- GREEN
HOUSE_MULTI5=16 -- ORANGE
HOUSE_MULTI6=17 -- KHAKI/LIGHT BROWN
HOUSE_MULTI7=18 -- AQUA
HOUSE_MULTI8=19 -- RED-OCHRE
-- *********************************************************
-- * *
-- * Special weapons *
-- * *
-- *********************************************************
SPECIAL_WEAPON_SONAR=0
SPECIAL_WEAPON_NUKE=1
SPECIAL_WEAPON_CHRONO=2
SPECIAL_WEAPON_PARABOMB=3
SPECIAL_WEAPON_PARATROOPS=4
SPECIAL_WEAPON_SPY_PLANE=5
SPECIAL_WEAPON_IRON_CURTAIN=6
SPECIAL_WEAPON_GPS=7
-- *********************************************************
-- * *
-- * Target types (for use with DesignatePreferredTarget) *
-- * *
-- *********************************************************
TARGET_TYPE_ANYTHING=1
TARGET_TYPE_BUILDINGS=2
TARGET_TYPE_HARVESTERS=3
TARGET_TYPE_INFANTRY=4
TARGET_TYPE_VEHICLES=5
TARGET_TYPE_SHIPS=6
TARGET_TYPE_FACTORIES=7
TARGET_TYPE_BASE_DEFENCES=8
TARGET_TYPE_BASE_THREATS=9
TARGET_TYPE_POWER=10
TARGET_TYPE_FAKE_BUILDINGS=11
-- *********************************************************
-- * *
-- * Trigger persistance *
-- * *
-- *********************************************************
TRIGGER_VOLATILE=0
TRIGGER_SEMI_PERSISTENT=1
TRIGGER_PERSISTENT=2
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB