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);
}
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. *
@@ -574,6 +585,11 @@ unsigned short Get_Build_Frame_Width(void const *dataptr, int frame)
{
if (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;
}
@@ -582,7 +598,6 @@ unsigned short Get_Build_Frame_Width(void const *dataptr, int frame)
return(0);
}
/***********************************************************************************************
* 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 (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(((RedAlertShapeHeader const *)dataptr)->height);
+7 -2
View File
@@ -2946,6 +2946,7 @@ BuildingTypeClass::BuildingTypeClass(
{
memset(CustomTheatrePalette, 0, sizeof(CustomTheatrePalette));
IdleAnimShape = NULL;
Anims[BSTATE_CONSTRUCTION].Start = 0;
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)
{
char customPalName[512];
char idleAnimName[512];
if (TechnoTypeClass::Read_INI(ini)) {
Speed = ini.Get_Bool(Name(), "WaterBound", (Speed == SPEED_FLOAT)) ? SPEED_FLOAT : SPEED_NONE;
Capacity = ini.Get_Int(Name(), "Storage", Capacity);
@@ -4013,8 +4017,6 @@ bool BuildingTypeClass::Read_INI(CCINIClass & ini)
IsBase = ini.Get_Bool(Name(), "BaseNormal", IsBase);
Power = ini.Get_Int(Name(), "Power", (Power > 0) ? Power : -Drain);
char customPalName[512];
if(ini.Get_String(Name(), "Snow", "", &customPalName[0], sizeof(customPalName)) > 0) {
CustomTheatrePalette[THEATER_SNOW] = MFCD::Retrieve(customPalName);
}
@@ -4022,6 +4024,9 @@ bool BuildingTypeClass::Read_INI(CCINIClass & ini)
CustomTheatrePalette[THEATER_TEMPERATE] = MFCD::Retrieve(customPalName);
}
if (ini.Get_String(Name(), "IdleAnim", "", &idleAnimName[0], sizeof(idleAnimName)) > 0) {
IdleAnimShape = MFCD::Retrieve(idleAnimName);
}
if (Power < 0) {
Drain = -Power;
+9
View File
@@ -480,9 +480,18 @@ void BuildingClass::Draw_It(int x, int y, WindowNumberType window) const
else {
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;
// jmarshall end
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) {
int width = Get_Build_Frame_Width(shapefile, shapenum);
int height = Get_Build_Frame_Height(shapefile, shapenum);
// With TS tiles, the smaller image buffer gets blit into a buffer that's the size of the entire image.
int width = Get_Build_Frame_Width(shapefile, -1);
int height = Get_Build_Frame_Height(shapefile, -1);
#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);
unsigned short Get_Build_Frame_X(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_Height(void const *dataptr, int frame);
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,
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
char shape_ts_global[2048 * 2048];
struct ShapeHeaderStruct
{
uint16_t m_FrameCount;
@@ -212,6 +215,23 @@ int TiberianSunSHPDecode(const byte* s, byte* d, int cx, int cy)
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) {
// 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);
int frameX = Get_Build_Frame_Width(dataptr, framenumber);
int frameY = Get_Build_Frame_Height(dataptr, framenumber);
TiberianSunSHPDecode(frame_offset, (byte *)buffptr, frameX, frameY);
return (INT_PTR)buffptr;
int frameWidth = Get_Build_Frame_Width(dataptr, framenumber);
int frameHeight = Get_Build_Frame_Height(dataptr, framenumber);
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.
+1
View File
@@ -819,6 +819,7 @@ class BuildingTypeClass : public TechnoTypeClass {
static Image_t* WarFactoryHDOverlay;
const void* CustomTheatrePalette[3];
const void* IdleAnimShape;
private:
/*
+1 -1
View File
@@ -23,11 +23,11 @@ UseSmallInfantry=No
NoCD=Yes
CounterstrikeEnabled=Yes
AftermathEnabled=Yes
ScoreVolume=0.5
GameSpeed=2
ScrollRate=5
Brightness=0.5
Volume=0.375
ScoreVolume=0.5
MultiplayerScoreVolume=0.5
Contrast=0.5
Color=0.5
+1
View File
@@ -1420,6 +1420,7 @@ Capturable=true
Crewed=yes
Snow=eapal1sno.pal
Temperate=eapal1tem.pal
IdleAnim=EACNST_A.SHP
; refinery
[PROC]