RA2/TS idle animation support. TS uncompressed tile support. Smaller shapes then the main image now blit to a correctly sized buffer.

This commit is contained in:
Justin Marshall
2020-08-01 12:22:29 -07:00
parent 8e4a9a019c
commit 857f0b7f60
9 changed files with 78 additions and 11 deletions
+20 -1
View File
@@ -554,6 +554,17 @@ unsigned short Get_Build_Frame_Y(void const *dataptr, int frame)
return(0); return(0);
} }
bool Get_Build_Is_Compressed(void const *dataptr, int frame) {
if(dataptr) {
if (Get_Build_TS_Shape(dataptr)) {
return Get_Build_TS_FrameInfo(dataptr, frame)->Flags & 2;
}
return false;
}
return false;
}
/*********************************************************************************************** /***********************************************************************************************
* Get_Build_Frame_Width -- Fetches the width of the shape image. * * Get_Build_Frame_Width -- Fetches the width of the shape image. *
@@ -574,6 +585,11 @@ unsigned short Get_Build_Frame_Width(void const *dataptr, int frame)
{ {
if (dataptr) { if (dataptr) {
if(Get_Build_TS_Shape(dataptr)) { if(Get_Build_TS_Shape(dataptr)) {
if(frame == -1) {
const TiberianSunShapeHeader* ts = (const TiberianSunShapeHeader*)dataptr;
return ts->width;
}
return Get_Build_TS_FrameInfo(dataptr, frame)->FrameWidth; return Get_Build_TS_FrameInfo(dataptr, frame)->FrameWidth;
} }
@@ -582,7 +598,6 @@ unsigned short Get_Build_Frame_Width(void const *dataptr, int frame)
return(0); return(0);
} }
/*********************************************************************************************** /***********************************************************************************************
* Get_Build_Frame_Height -- Fetches the height of the shape image. * * Get_Build_Frame_Height -- Fetches the height of the shape image. *
* * * *
@@ -602,6 +617,10 @@ unsigned short Get_Build_Frame_Height(void const *dataptr, int frame)
{ {
if (dataptr) { if (dataptr) {
if (Get_Build_TS_Shape(dataptr)) { if (Get_Build_TS_Shape(dataptr)) {
if (frame == -1) {
const TiberianSunShapeHeader* ts = (const TiberianSunShapeHeader*)dataptr;
return ts->height;
}
return Get_Build_TS_FrameInfo(dataptr, frame)->FrameHeight; return Get_Build_TS_FrameInfo(dataptr, frame)->FrameHeight;
} }
return(((RedAlertShapeHeader const *)dataptr)->height); return(((RedAlertShapeHeader const *)dataptr)->height);
+7 -2
View File
@@ -2946,6 +2946,7 @@ BuildingTypeClass::BuildingTypeClass(
{ {
memset(CustomTheatrePalette, 0, sizeof(CustomTheatrePalette)); memset(CustomTheatrePalette, 0, sizeof(CustomTheatrePalette));
IdleAnimShape = NULL;
Anims[BSTATE_CONSTRUCTION].Start = 0; Anims[BSTATE_CONSTRUCTION].Start = 0;
Anims[BSTATE_CONSTRUCTION].Count = 1; Anims[BSTATE_CONSTRUCTION].Count = 1;
@@ -4002,6 +4003,9 @@ bool BuildingTypeClass::Flush_For_Placement(CELL cell, HouseClass * house) cons
*=============================================================================================*/ *=============================================================================================*/
bool BuildingTypeClass::Read_INI(CCINIClass & ini) bool BuildingTypeClass::Read_INI(CCINIClass & ini)
{ {
char customPalName[512];
char idleAnimName[512];
if (TechnoTypeClass::Read_INI(ini)) { if (TechnoTypeClass::Read_INI(ini)) {
Speed = ini.Get_Bool(Name(), "WaterBound", (Speed == SPEED_FLOAT)) ? SPEED_FLOAT : SPEED_NONE; Speed = ini.Get_Bool(Name(), "WaterBound", (Speed == SPEED_FLOAT)) ? SPEED_FLOAT : SPEED_NONE;
Capacity = ini.Get_Int(Name(), "Storage", Capacity); Capacity = ini.Get_Int(Name(), "Storage", Capacity);
@@ -4013,8 +4017,6 @@ bool BuildingTypeClass::Read_INI(CCINIClass & ini)
IsBase = ini.Get_Bool(Name(), "BaseNormal", IsBase); IsBase = ini.Get_Bool(Name(), "BaseNormal", IsBase);
Power = ini.Get_Int(Name(), "Power", (Power > 0) ? Power : -Drain); Power = ini.Get_Int(Name(), "Power", (Power > 0) ? Power : -Drain);
char customPalName[512];
if(ini.Get_String(Name(), "Snow", "", &customPalName[0], sizeof(customPalName)) > 0) { if(ini.Get_String(Name(), "Snow", "", &customPalName[0], sizeof(customPalName)) > 0) {
CustomTheatrePalette[THEATER_SNOW] = MFCD::Retrieve(customPalName); CustomTheatrePalette[THEATER_SNOW] = MFCD::Retrieve(customPalName);
} }
@@ -4022,6 +4024,9 @@ bool BuildingTypeClass::Read_INI(CCINIClass & ini)
CustomTheatrePalette[THEATER_TEMPERATE] = MFCD::Retrieve(customPalName); CustomTheatrePalette[THEATER_TEMPERATE] = MFCD::Retrieve(customPalName);
} }
if (ini.Get_String(Name(), "IdleAnim", "", &idleAnimName[0], sizeof(idleAnimName)) > 0) {
IdleAnimShape = MFCD::Retrieve(idleAnimName);
}
if (Power < 0) { if (Power < 0) {
Drain = -Power; Drain = -Power;
+9
View File
@@ -480,9 +480,18 @@ void BuildingClass::Draw_It(int x, int y, WindowNumberType window) const
else { else {
Techno_Draw_Object(shapefile, Shape_Number(), x, y, window); Techno_Draw_Object(shapefile, Shape_Number(), x, y, window);
} }
// jmarshall end
// jmarshall idle animation
if (Class->IdleAnimShape != NULL) {
int shapeNum = animFrameNum;
shapeNum = shapeNum % Get_Build_Frame_Count(Class->IdleAnimShape);
Techno_Draw_Object(Class->IdleAnimShape, shapeNum, x, y, window);
}
CCGlobalOveridePalette = NULL; CCGlobalOveridePalette = NULL;
// jmarshall end // jmarshall end
IsTheaterShape = false; IsTheaterShape = false;
/* /*
+3 -2
View File
@@ -3696,8 +3696,9 @@ void CC_Draw_Shape(void const * shapefile, int shapenum, int x, int y, WindowNum
if (shapefile != NULL && shapenum != -1) { if (shapefile != NULL && shapenum != -1) {
int width = Get_Build_Frame_Width(shapefile, shapenum); // With TS tiles, the smaller image buffer gets blit into a buffer that's the size of the entire image.
int height = Get_Build_Frame_Height(shapefile, shapenum); int width = Get_Build_Frame_Width(shapefile, -1);
int height = Get_Build_Frame_Height(shapefile, -1);
#ifdef NEVER #ifdef NEVER
/* /*
+1
View File
@@ -726,6 +726,7 @@ unsigned short Get_Build_Frame_Count(void const *dataptr);
bool Get_Build_TiberianSun_Format(void const* dataptr); bool Get_Build_TiberianSun_Format(void const* dataptr);
unsigned short Get_Build_Frame_X(void const *dataptr, int frame); unsigned short Get_Build_Frame_X(void const *dataptr, int frame);
unsigned short Get_Build_Frame_Y(void const *dataptr, int frame); unsigned short Get_Build_Frame_Y(void const *dataptr, int frame);
bool Get_Build_Is_Compressed(void const* dataptr, int frame);
unsigned short Get_Build_Frame_Width(void const *dataptr, int frame); unsigned short Get_Build_Frame_Width(void const *dataptr, int frame);
unsigned short Get_Build_Frame_Height(void const *dataptr, int frame); unsigned short Get_Build_Frame_Height(void const *dataptr, int frame);
bool Get_Build_Frame_Palette(void const *dataptr, void *palette); bool Get_Build_Frame_Palette(void const *dataptr, void *palette);
+34 -4
View File
@@ -19,6 +19,7 @@
Originally this file came from Chronoshift, and we still have some legacy bits from their code in here, Originally this file came from Chronoshift, and we still have some legacy bits from their code in here,
however this file has been **heavily** modified by IceColdDuke(Justin Marshall) to render with OpenGL. however this file has been **heavily** modified by IceColdDuke(Justin Marshall) to render with OpenGL.
We also added Tiberian Sun SHP format render support, this code uses some code from XCC.
============================ ============================
*/ */
@@ -42,6 +43,8 @@ using std::memcpy;
#define SHAPE_TRANSPARENT 0x40 #define SHAPE_TRANSPARENT 0x40
char shape_ts_global[2048 * 2048];
struct ShapeHeaderStruct struct ShapeHeaderStruct
{ {
uint16_t m_FrameCount; uint16_t m_FrameCount;
@@ -212,6 +215,23 @@ int TiberianSunSHPDecode(const byte* s, byte* d, int cx, int cy)
return w - d; return w - d;
} }
INT_PTR Build_Full_Frame(int frameX, int frameY, int frameWidth, int frameHeight, int imageWidth, int imageHeight, byte *uncompressedBuffer) {
if (frameWidth == imageWidth && frameHeight == imageHeight) {
return (INT_PTR)uncompressedBuffer;
}
memset(shape_ts_global, 0, imageWidth * imageHeight);
byte* w = (byte *)shape_ts_global + frameX + imageWidth * frameY;
for (int y = 0; y < frameHeight; y++)
{
memcpy(w, uncompressedBuffer, frameWidth);
uncompressedBuffer += frameWidth;
w += imageWidth;
}
return (INT_PTR)shape_ts_global;
}
INT_PTR Build_Frame(void const* dataptr, unsigned short framenumber, void* buffptr) { INT_PTR Build_Frame(void const* dataptr, unsigned short framenumber, void* buffptr) {
// Check to see if we need to render a Tiberian Sun SHP file. // Check to see if we need to render a Tiberian Sun SHP file.
@@ -221,10 +241,20 @@ INT_PTR Build_Frame(void const* dataptr, unsigned short framenumber, void* buffp
} }
byte* frame_offset = (byte *)Get_Build_TS_FrameOffset(dataptr, framenumber); byte* frame_offset = (byte *)Get_Build_TS_FrameOffset(dataptr, framenumber);
int frameX = Get_Build_Frame_Width(dataptr, framenumber); int frameWidth = Get_Build_Frame_Width(dataptr, framenumber);
int frameY = Get_Build_Frame_Height(dataptr, framenumber); int frameHeight = Get_Build_Frame_Height(dataptr, framenumber);
TiberianSunSHPDecode(frame_offset, (byte *)buffptr, frameX, frameY);
return (INT_PTR)buffptr; int frame_X = Get_Build_Frame_X(dataptr, framenumber);
int frame_Y = Get_Build_Frame_Y(dataptr, framenumber);
int imageWidth = Get_Build_Frame_Width(dataptr, -1);
int imageHeight = Get_Build_Frame_Height(dataptr, -1);
if (Get_Build_Is_Compressed(dataptr, framenumber)) {
TiberianSunSHPDecode(frame_offset, (byte*)buffptr, frameWidth, frameHeight);
return (INT_PTR)Build_Full_Frame(frame_X, frame_Y, frameWidth, frameHeight, imageWidth, imageHeight, (byte *)buffptr);
}
return (INT_PTR)Build_Full_Frame(frame_X, frame_Y, frameWidth, frameHeight, imageWidth, imageHeight, frame_offset);
} }
// Regular Red Alert sprite. // Regular Red Alert sprite.
+1
View File
@@ -819,6 +819,7 @@ class BuildingTypeClass : public TechnoTypeClass {
static Image_t* WarFactoryHDOverlay; static Image_t* WarFactoryHDOverlay;
const void* CustomTheatrePalette[3]; const void* CustomTheatrePalette[3];
const void* IdleAnimShape;
private: private:
/* /*
+1 -1
View File
@@ -23,11 +23,11 @@ UseSmallInfantry=No
NoCD=Yes NoCD=Yes
CounterstrikeEnabled=Yes CounterstrikeEnabled=Yes
AftermathEnabled=Yes AftermathEnabled=Yes
ScoreVolume=0.5
GameSpeed=2 GameSpeed=2
ScrollRate=5 ScrollRate=5
Brightness=0.5 Brightness=0.5
Volume=0.375 Volume=0.375
ScoreVolume=0.5
MultiplayerScoreVolume=0.5 MultiplayerScoreVolume=0.5
Contrast=0.5 Contrast=0.5
Color=0.5 Color=0.5
+1
View File
@@ -1420,6 +1420,7 @@ Capturable=true
Crewed=yes Crewed=yes
Snow=eapal1sno.pal Snow=eapal1sno.pal
Temperate=eapal1tem.pal Temperate=eapal1tem.pal
IdleAnim=EACNST_A.SHP
; refinery ; refinery
[PROC] [PROC]