Merge branch 'master' into NoShifts

This commit is contained in:
asasas9500 2020-08-25 19:25:28 -03:00
commit c06fa6f9e2
86 changed files with 3179 additions and 2273 deletions

View file

@ -142,8 +142,7 @@ void lara_as_climbdown(ITEM_INFO* item, COLL_INFO* coll)//46BA4(<), 47008(<) (F)
void lara_col_climbing(ITEM_INFO* item, COLL_INFO* coll)//469B0, 46E14 (F) void lara_col_climbing(ITEM_INFO* item, COLL_INFO* coll)//469B0, 46E14 (F)
{ {
if (!LaraCheckForLetGo(item, coll) if (!LaraCheckForLetGo(item, coll) && item->animNumber == LA_LADDER_UP)
&& item->animNumber == LA_LADDER_UP)
{ {
int frame = item->frameNumber - g_Level.Anims[LA_LADDER_UP].frameBase; int frame = item->frameNumber - g_Level.Anims[LA_LADDER_UP].frameBase;
int yShift; int yShift;
@ -272,8 +271,7 @@ void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
int shiftRight, shiftLeft; int shiftRight, shiftLeft;
int ledgeRight, ledgeLeft; int ledgeRight, ledgeLeft;
if (LaraCheckForLetGo(item, coll) if (LaraCheckForLetGo(item, coll) || item->animNumber != LA_LADDER_IDLE)
|| item->animNumber != LA_LADDER_IDLE)
return; return;
if (!(TrInput & IN_FORWARD)) if (!(TrInput & IN_FORWARD))
@ -428,38 +426,38 @@ int LaraTestClimbPos(ITEM_INFO* item, int front, int right, int origin, int heig
{ {
int x; int x;
int z; int z;
int xfront = 0; int xFront = 0;
int zfront = 0; int zFront = 0;
switch (GetQuadrant(item->pos.yRot)) switch (GetQuadrant(item->pos.yRot))
{ {
case NORTH: case NORTH:
x = item->pos.xPos + right; x = item->pos.xPos + right;
z = item->pos.zPos + front; z = item->pos.zPos + front;
zfront = 256; zFront = 256;
break; break;
case EAST: case EAST:
x = item->pos.xPos + front; x = item->pos.xPos + front;
z = item->pos.zPos - right; z = item->pos.zPos - right;
xfront = 256; xFront = 256;
break; break;
case SOUTH: case SOUTH:
x = item->pos.xPos - right; x = item->pos.xPos - right;
z = item->pos.zPos - front; z = item->pos.zPos - front;
zfront = -256; zFront = -256;
break; break;
case WEST: case WEST:
default: default:
x = item->pos.xPos - front; x = item->pos.xPos - front;
z = item->pos.zPos + right; z = item->pos.zPos + right;
xfront = -256; xFront = -256;
break; break;
} }
return LaraTestClimb(x, item->pos.yPos + origin, z, xfront, zfront, height, item->roomNumber, shift); return LaraTestClimb(x, item->pos.yPos + origin, z, xFront, zFront, height, item->roomNumber, shift);
} }
void LaraDoClimbLeftRight(ITEM_INFO* item, COLL_INFO* coll, int result, int shift)//46100, 46564 (F) void LaraDoClimbLeftRight(ITEM_INFO* item, COLL_INFO* coll, int result, int shift)//46100, 46564 (F)

View file

@ -372,23 +372,17 @@ void LaraGun() // (F) (D)
|| LaraItem->currentAnimState == LS_CROUCH_TURN_RIGHT) || LaraItem->currentAnimState == LS_CROUCH_TURN_RIGHT)
&& (Lara.requestGunType == WEAPON_HK && (Lara.requestGunType == WEAPON_HK
|| Lara.requestGunType == WEAPON_CROSSBOW || Lara.requestGunType == WEAPON_CROSSBOW
#if 1
|| Lara.requestGunType == WEAPON_SHOTGUN))
#else
|| Lara.requestGunType == WEAPON_SHOTGUN || Lara.requestGunType == WEAPON_SHOTGUN
|| Lara.requestGunType == WEAPON_HARPOON_GUN)) || Lara.requestGunType == WEAPON_HARPOON_GUN))
#endif
{ {
if (Lara.gunType == WEAPON_FLARE) if (Lara.gunType == WEAPON_FLARE)
Lara.requestGunType = WEAPON_FLARE; Lara.requestGunType = WEAPON_FLARE;
} }
else if (Lara.requestGunType == WEAPON_FLARE else if (Lara.requestGunType == WEAPON_FLARE
#if 0
|| Lara.Vehicle == NO_ITEM || Lara.Vehicle == NO_ITEM
&& (Lara.requestGunType == WEAPON_HARPOON_GUN && (Lara.requestGunType == WEAPON_HARPOON_GUN
#endif
|| Lara.waterStatus == LW_ABOVE_WATER || Lara.waterStatus == LW_ABOVE_WATER
|| Lara.waterStatus == LW_WADE || Lara.waterStatus == LW_WADE)
&& Lara.waterSurfaceDist > -Weapons[Lara.gunType].gunHeight) && Lara.waterSurfaceDist > -Weapons[Lara.gunType].gunHeight)
{ {
if (Lara.gunType == WEAPON_FLARE) if (Lara.gunType == WEAPON_FLARE)
@ -417,14 +411,19 @@ void LaraGun() // (F) (D)
} }
else if (Lara.gunStatus == LG_READY) else if (Lara.gunStatus == LG_READY)
{ {
#if 0 if ((TrInput & IN_DRAW)
if ((TrInput & IN_DRAW) || Lara.requestGunType != Lara.gunType || Lara.gunType != WEAPON_HARPOON_GUN && Lara.waterStatus != LW_ABOVE_WATER && Lara.waterStatus != LW_WADE || Lara.waterSurfaceDist < -Weapons[Lara.gunType].gunHeight) || Lara.requestGunType != Lara.gunType)
#else Lara.gunStatus = LG_UNDRAW_GUNS;
if ((TrInput & IN_DRAW) || Lara.requestGunType != Lara.gunType || Lara.waterStatus != LW_ABOVE_WATER && Lara.waterStatus != LW_WADE || Lara.waterSurfaceDist < -Weapons[Lara.gunType].gunHeight) else if (Lara.gunType != WEAPON_HARPOON_GUN
#endif && Lara.waterStatus != LW_ABOVE_WATER
&& (Lara.waterStatus != LW_WADE
|| Lara.waterSurfaceDist < -Weapons[Lara.gunType].gunHeight))
Lara.gunStatus = LG_UNDRAW_GUNS; Lara.gunStatus = LG_UNDRAW_GUNS;
} }
else if (Lara.gunStatus == LG_HANDS_BUSY && (TrInput & IN_FLARE) && LaraItem->currentAnimState == LS_CRAWL_IDLE && LaraItem->animNumber == LA_CRAWL_IDLE) else if (Lara.gunStatus == LG_HANDS_BUSY
&& (TrInput & IN_FLARE)
&& LaraItem->currentAnimState == LS_CRAWL_IDLE
&& LaraItem->animNumber == LA_CRAWL_IDLE)
{ {
Lara.requestGunType = WEAPON_FLARE; Lara.requestGunType = WEAPON_FLARE;
} }
@ -448,11 +447,9 @@ void LaraGun() // (F) (D)
case WEAPON_SHOTGUN: case WEAPON_SHOTGUN:
case WEAPON_CROSSBOW: case WEAPON_CROSSBOW:
case WEAPON_HK: case WEAPON_HK:
#if 0
case WEAPON_GRENADE_LAUNCHER: case WEAPON_GRENADE_LAUNCHER:
case WEAPON_ROCKET_LAUNCHER: case WEAPON_ROCKET_LAUNCHER:
case WEAPON_HARPOON_GUN: case WEAPON_HARPOON_GUN:
#endif
if (Camera.type != CINEMATIC_CAMERA && Camera.type != LOOK_CAMERA && Camera.type != HEAVY_CAMERA) if (Camera.type != CINEMATIC_CAMERA && Camera.type != LOOK_CAMERA && Camera.type != HEAVY_CAMERA)
Camera.type = COMBAT_CAMERA; Camera.type = COMBAT_CAMERA;
draw_shotgun(Lara.gunType); draw_shotgun(Lara.gunType);
@ -473,7 +470,6 @@ void LaraGun() // (F) (D)
break; break;
case LG_UNDRAW_GUNS: case LG_UNDRAW_GUNS:
//LARA_MESHES(ID_LARA, LM_HEAD);
Lara.meshPtrs[LM_HEAD] = Objects[ID_LARA_SKIN].meshIndex + LM_HEAD; Lara.meshPtrs[LM_HEAD] = Objects[ID_LARA_SKIN].meshIndex + LM_HEAD;
switch (Lara.gunType) switch (Lara.gunType)
@ -487,11 +483,9 @@ void LaraGun() // (F) (D)
case WEAPON_SHOTGUN: case WEAPON_SHOTGUN:
case WEAPON_CROSSBOW: case WEAPON_CROSSBOW:
case WEAPON_HK: case WEAPON_HK:
#if 0
case WEAPON_GRENADE_LAUNCHER: case WEAPON_GRENADE_LAUNCHER:
case WEAPON_ROCKET_LAUNCHER: case WEAPON_ROCKET_LAUNCHER:
case WEAPON_HARPOON_GUN: case WEAPON_HARPOON_GUN:
#endif
undraw_shotgun(Lara.gunType); undraw_shotgun(Lara.gunType);
break; break;
@ -506,10 +500,8 @@ void LaraGun() // (F) (D)
case LG_READY: case LG_READY:
if (!(TrInput & IN_ACTION)) if (!(TrInput & IN_ACTION))
//LARA_MESHES(ID_LARA, LM_HEAD);
Lara.meshPtrs[LM_HEAD] = Objects[ID_LARA_SKIN].meshIndex + LM_HEAD; Lara.meshPtrs[LM_HEAD] = Objects[ID_LARA_SKIN].meshIndex + LM_HEAD;
else else
//LARA_MESHES(ID_LARA_SCREAM, LM_HEAD);
Lara.meshPtrs[LM_HEAD] = Objects[ID_LARA_SCREAM].meshIndex + LM_HEAD; Lara.meshPtrs[LM_HEAD] = Objects[ID_LARA_SCREAM].meshIndex + LM_HEAD;
if (Camera.type != CINEMATIC_CAMERA && Camera.type != LOOK_CAMERA && Camera.type != HEAVY_CAMERA) if (Camera.type != CINEMATIC_CAMERA && Camera.type != LOOK_CAMERA && Camera.type != HEAVY_CAMERA)
@ -534,11 +526,9 @@ void LaraGun() // (F) (D)
case WEAPON_SHOTGUN: case WEAPON_SHOTGUN:
case WEAPON_CROSSBOW: case WEAPON_CROSSBOW:
case WEAPON_HK: case WEAPON_HK:
#if 0
case WEAPON_GRENADE_LAUNCHER: case WEAPON_GRENADE_LAUNCHER:
case WEAPON_ROCKET_LAUNCHER: case WEAPON_ROCKET_LAUNCHER:
case WEAPON_HARPOON_GUN: case WEAPON_HARPOON_GUN:
#endif
case WEAPON_REVOLVER: case WEAPON_REVOLVER:
RifleHandler(Lara.gunType); RifleHandler(Lara.gunType);
break; break;

View file

@ -23,6 +23,15 @@ typedef struct WEAPON_INFO
byte drawFrame; byte drawFrame;
short sampleNum; short sampleNum;
}; };
constexpr auto WSTATE_AIM = 0;
constexpr auto WSTATE_DRAW = 1;
constexpr auto WSTATE_UW_AIM = 6;
constexpr auto WSTATE_RECOIL = 2;
constexpr auto WSTATE_UW_RECOIL = 8;
constexpr auto WSTATE_UNAIM = 4;
constexpr auto WSTATE_UW_UNAIM = 7;
extern WEAPON_INFO Weapons[static_cast<int>(LARA_WEAPON_TYPE::NUM_WEAPONS)]; extern WEAPON_INFO Weapons[static_cast<int>(LARA_WEAPON_TYPE::NUM_WEAPONS)];
void SmashItem(short itemNum); void SmashItem(short itemNum);

File diff suppressed because it is too large Load diff

View file

@ -18,7 +18,11 @@ constexpr auto CROSSBOW_AMMO2 = 2;
constexpr auto CROSSBOW_AMMO3 = 2; constexpr auto CROSSBOW_AMMO3 = 2;
constexpr auto CROSSBOW_HIT_RADIUS = 128; constexpr auto CROSSBOW_HIT_RADIUS = 128;
constexpr auto CROSSBOW_EXPLODE_RADIUS = SECTOR(2); constexpr auto CROSSBOW_EXPLODE_RADIUS = SECTOR(2);
constexpr auto GRENADE_HIT_RADIUS = 128;
constexpr auto GRENADE_EXPLODE_RADIUS = SECTOR(2); constexpr auto GRENADE_EXPLODE_RADIUS = SECTOR(2);
constexpr auto ROCKET_HIT_RADIUS = 128;
constexpr auto ROCKET_EXPLODE_RADIUS = SECTOR(2);
constexpr auto HARPOON_HIT_RADIUS = 128;
void FireGrenade(); void FireGrenade();
void ControlGrenade(short itemNumber); void ControlGrenade(short itemNumber);
@ -30,12 +34,15 @@ void AnimateShotgun(int weaponType);
void ControlCrossbowBolt(short itemNumber); void ControlCrossbowBolt(short itemNumber);
void FireCrossbow(PHD_3DPOS* pos); void FireCrossbow(PHD_3DPOS* pos);
void RifleHandler(int weaponType); void RifleHandler(int weaponType);
void DoGrenadeDamageOnBaddie(ITEM_INFO* src, ITEM_INFO* dest); void DoExplosiveDamageOnBaddie(ITEM_INFO* src, ITEM_INFO* dest, int weapon);
void TriggerUnderwaterExplosion(ITEM_INFO* item); void TriggerUnderwaterExplosion(ITEM_INFO* item, int flag);
void undraw_shotgun_meshes(int weapon); void undraw_shotgun_meshes(int weapon);
void undraw_shotgun(int weapon); void undraw_shotgun(int weapon);
void draw_shotgun_meshes(int weaponType); void draw_shotgun_meshes(int weaponType);
void FireHK(int mode); void FireHK(int mode);
void FireShotgun(); void FireShotgun();
void DoCrossbowDamage(ITEM_INFO* item1, ITEM_INFO* item2, signed int search); void HitSpecial(ITEM_INFO* projectile, ITEM_INFO* target, int flags);
void ready_shotgun(int weaponType); void ready_shotgun(int weaponType);
void SomeSparkEffect(int x, int y, int z, int count);
void FireRocket();
void ControlRocket(short itemNumber);

View file

@ -79,7 +79,7 @@ enum LARA_STATE
LS_LADDER_STOP = 59, LS_LADDER_STOP = 59,
LS_LADDER_RIGHT = 60, LS_LADDER_RIGHT = 60,
LS_LADDER_DOWN = 61, LS_LADDER_DOWN = 61,
LS_TEST_1 = 62, LS_TEST_1 = 62, // Used for auto monkey up jump.
LS_TEST_2 = 63, LS_TEST_2 = 63,
LS_TEST_3 = 64, LS_TEST_3 = 64,
LS_WADE_FORWARD = 65, LS_WADE_FORWARD = 65,
@ -621,8 +621,7 @@ enum LARA_ANIM
LA_ROPE_HANG_IDLE_UNUSED = 408, // Rope hang (looped) LA_ROPE_HANG_IDLE_UNUSED = 408, // Rope hang (looped)
LA_ROPE_SWING_TO_REACH_UNUSED_3 = 409, // Rope swing > reach, 3rd unused opportunity LA_ROPE_SWING_TO_REACH_UNUSED_3 = 409, // Rope swing > reach, 3rd unused opportunity
LA_ROPE_SWING_TO_REACH_UNUSED_2 = 410, // Rope swing > reach, 2nd unused opportunity LA_ROPE_SWING_TO_REACH_UNUSED_2 = 410, // Rope swing > reach, 2nd unused opportunity
// TODO: confirm dispatch. LA_ROPE_SWING_TO_REACH_UNUSED_1 = 411, // Rope swing > reach, 1st unused opportunity
LA_ROPE_SWING_TO_REACH_UNUSED_1 = 411, // Rope swing > reach, 1stunused opportunity
LA_DOUBLEDOOR_OPEN_PUSH = 412, // Push double doors LA_DOUBLEDOOR_OPEN_PUSH = 412, // Push double doors
LA_BUTTON_LARGE_PUSH = 413, // Push big button LA_BUTTON_LARGE_PUSH = 413, // Push big button
LA_JUMPSWITCH_PULL = 414, // Pull jumpswitch LA_JUMPSWITCH_PULL = 414, // Pull jumpswitch
@ -643,7 +642,7 @@ enum LARA_ANIM
LA_TORCH_LIGHT_2 = 428, // Light torch with flame 2-3 clicks high LA_TORCH_LIGHT_2 = 428, // Light torch with flame 2-3 clicks high
LA_TORCH_LIGHT_3 = 429, // Light torch with flame 4-5 clicks high LA_TORCH_LIGHT_3 = 429, // Light torch with flame 4-5 clicks high
LA_TORCH_LIGHT_4 = 430, // Light torch with flame 6-7 clicks high LA_TORCH_LIGHT_4 = 430, // Light torch with flame 6-7 clicks high
LA_TORCH_LIGHT_5 = 431, // Light torch with flame greater than 7 clicks LA_TORCH_LIGHT_5 = 431, // Light torch with flame higher than 7 clicks
LA_DETONATOR_USE = 432, // Use mine detonator LA_DETONATOR_USE = 432, // Use mine detonator
LA_CORRECT_POSITION_FRONT = 433, // Adjust position forward LA_CORRECT_POSITION_FRONT = 433, // Adjust position forward
LA_CORRECT_POSITION_LEFT = 434, // Adjust position left LA_CORRECT_POSITION_LEFT = 434, // Adjust position left

View file

@ -60,7 +60,7 @@ int CollideStaticObjects(COLL_INFO* coll, int x, int y, int z, short roomNumber,
for (int i = 0; i < numRooms; i++) for (int i = 0; i < numRooms; i++)
{ {
room = &g_Level.Rooms[roomList[i]]; room = &g_Level.Rooms[roomList[i]];
for (int j = room->mesh.size(); j > 0; j--, mesh++) for (int j = 0; j < room->mesh.size(); j++, mesh++)
{ {
mesh = &room->mesh[j]; mesh = &room->mesh[j];
STATIC_INFO* sInfo = &StaticObjects[mesh->staticNumber]; STATIC_INFO* sInfo = &StaticObjects[mesh->staticNumber];
@ -195,7 +195,7 @@ int GetCollidedObjects(ITEM_INFO* collidingItem, int radius, int onlyVisible, IT
{ {
ITEM_INFO* item = &g_Level.Items[itemNumber]; ITEM_INFO* item = &g_Level.Items[itemNumber];
if (item == collidingItem || !ignoreLara && item == LaraItem) if (item == collidingItem || ignoreLara && item == LaraItem)
{ {
itemNumber = item->nextItem; itemNumber = item->nextItem;
continue; continue;
@ -219,7 +219,7 @@ int GetCollidedObjects(ITEM_INFO* collidingItem, int radius, int onlyVisible, IT
ANIM_FRAME* framePtr = GetBestFrame(item); ANIM_FRAME* framePtr = GetBestFrame(item);
if (Objects[item->objectNumber].drawRoutine if ((Objects[item->objectNumber].drawRoutine || item->objectNumber == ID_LARA)
&& item->meshBits && item->meshBits
&& (!onlyVisible || item->status != ITEM_INVISIBLE) && (!onlyVisible || item->status != ITEM_INVISIBLE)
&& dx >= -2048 && dx >= -2048

View file

@ -254,7 +254,7 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
// Does the player want to enter inventory? // Does the player want to enter inventory?
SetDebounce = false; SetDebounce = false;
if (CurrentLevel != 0 && !g_Renderer.IsFading()) if (CurrentLevel != 0 && !g_Renderer.isFading())
{ {
if ((DbInput & IN_DESELECT || g_Inventory.GetEnterObject() != NO_ITEM) && !CutSeqTriggered && LaraItem->hitPoints > 0) if ((DbInput & IN_DESELECT || g_Inventory.GetEnterObject() != NO_ITEM) && !CutSeqTriggered && LaraItem->hitPoints > 0)
{ {
@ -372,7 +372,7 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
// Clear dynamic lights // Clear dynamic lights
ClearDynamicLights(); ClearDynamicLights();
ClearFires(); ClearFires();
g_Renderer.ClearDynamicLights(); g_Renderer.clearDynamicLights();
GotLaraSpheres = false; GotLaraSpheres = false;
@ -477,7 +477,7 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
InItemControlLoop = false; InItemControlLoop = false;
KillMoveItems(); KillMoveItems();
g_Renderer.UpdateLaraAnimations(true); g_Renderer.updateLaraAnimations(true);
// Update Lara's ponytails // Update Lara's ponytails
HairControl(0, 0, 0); HairControl(0, 0, 0);
@ -584,7 +584,7 @@ unsigned CALLBACK GameMain(void *)
TIME_Init(); TIME_Init();
// Do a fixed time title image // Do a fixed time title image
g_Renderer.DoTitleImage(); g_Renderer.renderTitleImage();
// Execute the LUA gameflow and play the game // Execute the LUA gameflow and play the game
g_GameFlow->DoGameflow(); g_GameFlow->DoGameflow();
@ -747,18 +747,18 @@ GAME_STATUS DoLevel(int index, int ambient, bool loadFromSavegame)
int nframes = 2; int nframes = 2;
// First control phase // First control phase
g_Renderer.ResetAnimations(); g_Renderer.resetAnimations();
GAME_STATUS result = ControlPhase(nframes, 0); GAME_STATUS result = ControlPhase(nframes, 0);
// Fade in screen // Fade in screen
g_Renderer.FadeIn(); g_Renderer.fadeIn();
// The game loop, finally! // The game loop, finally!
while (true) while (true)
{ {
nframes = DrawPhaseGame(); nframes = DrawPhaseGame();
g_Renderer.ResetAnimations(); g_Renderer.resetAnimations();
result = ControlPhase(nframes, 0); result = ControlPhase(nframes, 0);
if (result == GAME_STATUS_EXIT_TO_TITLE || if (result == GAME_STATUS_EXIT_TO_TITLE ||
result == GAME_STATUS_LOAD_GAME || result == GAME_STATUS_LOAD_GAME ||
@ -2198,9 +2198,9 @@ int GetTargetOnLOS(GAME_VECTOR *src, GAME_VECTOR *dest, int DrawTarget, int firi
else else
{ {
item = &g_Level.Items[itemNumber]; item = &g_Level.Items[itemNumber];
if (item->objectNumber != ID_SHOOT_SWITCH1 && item->objectNumber != ID_SHOOT_SWITCH2) if (item->objectNumber < ID_SHOOT_SWITCH1 && item->objectNumber > ID_SHOOT_SWITCH4)
{ {
if (Objects[item->objectNumber].explodableMeshbits & ShatterItem.bit && LaserSight) if ((Objects[item->objectNumber].explodableMeshbits & ShatterItem.bit) && LaserSight)
{ {
if (!Objects[item->objectNumber].intelligent) if (!Objects[item->objectNumber].intelligent)
{ {
@ -2283,10 +2283,17 @@ int GetTargetOnLOS(GAME_VECTOR *src, GAME_VECTOR *dest, int DrawTarget, int firi
ExplodeItemNode(item, Objects[item->objectNumber].nmeshes - 1, 0, 64); ExplodeItemNode(item, Objects[item->objectNumber].nmeshes - 1, 0, 64);
if (item->triggerFlags == 444 && item->objectNumber == ID_SHOOT_SWITCH2) if (item->triggerFlags == 444 && item->objectNumber == ID_SHOOT_SWITCH2)
{ {
// TR5 ID_SWITCH_TYPE_8/ID_SHOOT_SWITCH2
ProcessExplodingSwitchType8(item); ProcessExplodingSwitchType8(item);
} }
else else
{ {
if (item->objectNumber == ID_SHOOT_SWITCH3)
{
// TR4 ID_SWITCH_TYPE7
ExplodeItemNode(item, Objects[item->objectNumber].nmeshes - 1, 0, 64);
}
if (item->flags & IFLAG_ACTIVATION_MASK && (item->flags & IFLAG_ACTIVATION_MASK) != IFLAG_ACTIVATION_MASK) if (item->flags & IFLAG_ACTIVATION_MASK && (item->flags & IFLAG_ACTIVATION_MASK) != IFLAG_ACTIVATION_MASK)
{ {
room = item->roomNumber; room = item->roomNumber;
@ -2940,7 +2947,7 @@ void AnimateItem(ITEM_INFO *item)
// Update matrices // Update matrices
short itemNumber = item - g_Level.Items.data(); short itemNumber = item - g_Level.Items.data();
g_Renderer.UpdateItemAnimations(itemNumber, true); g_Renderer.updateItemAnimations(itemNumber, true);
} }
void DoFlipMap(short group) void DoFlipMap(short group)
@ -2969,7 +2976,7 @@ void DoFlipMap(short group)
AddRoomFlipItems(r); AddRoomFlipItems(r);
g_Renderer.FlipRooms(i, r->flippedRoom); g_Renderer.flipRooms(i, r->flippedRoom);
} }
} }
@ -3315,3 +3322,10 @@ int IsRoomOutside(int x, int y, int z)
return -2; return -2;
} }
void GetFloorAndTestTriggers(int x, int y, int z, short roomNumber, int heavy, int heavyFlags)
{
FLOOR_INFO* floor = GetFloor(x, y, z, &roomNumber);
GetFloorHeight(floor, x, y, z);
TestTriggers(TriggerIndex, heavy, heavyFlags);
}

View file

@ -193,5 +193,6 @@ int GetWaterHeight(int x, int y, int z, short roomNumber);
int is_object_in_room(short roomNumber, short objectNumber); int is_object_in_room(short roomNumber, short objectNumber);
void InterpolateAngle(short angle, short* rotation, short* outAngle, int shift); void InterpolateAngle(short angle, short* rotation, short* outAngle, int shift);
int IsRoomOutside(int x, int y, int z); int IsRoomOutside(int x, int y, int z);
void GetFloorAndTestTriggers(int x, int y, int z, short roomNumber, int heavy, int heavyFlags);
unsigned CALLBACK GameMain(void*); unsigned CALLBACK GameMain(void*);

View file

@ -168,9 +168,24 @@ void GetLaraJointPosition(PHD_VECTOR* pos, int LM_enum)
LM_enum = LM_HEAD; LM_enum = LM_HEAD;
Vector3 p = Vector3(pos->x, pos->y, pos->z); Vector3 p = Vector3(pos->x, pos->y, pos->z);
g_Renderer.GetLaraAbsBonePosition(&p, LM_enum); g_Renderer.getLaraAbsBonePosition(&p, LM_enum);
pos->x = p.x; pos->x = p.x;
pos->y = p.y; pos->y = p.y;
pos->z = p.z; pos->z = p.z;
} }
void ClampRotation(PHD_3DPOS* pos, short angle, short rot)
{
if (angle <= rot)
{
if (angle >= -rot)
pos->yRot += angle;
else
pos->yRot -= rot;
}
else
{
pos->yRot += rot;
}
}

View file

@ -20,3 +20,4 @@ bool TIME_Init();
bool TIME_Reset(); bool TIME_Reset();
void DrawAnimatingItem(ITEM_INFO* item); void DrawAnimatingItem(ITEM_INFO* item);
void GetLaraJointPosition(PHD_VECTOR* pos, int LM_enum); void GetLaraJointPosition(PHD_VECTOR* pos, int LM_enum);
void ClampRotation(PHD_3DPOS* pos, short angle, short rot);

View file

@ -247,10 +247,10 @@ void ExplosionFX(ITEM_INFO* item)//39694(<), 39B94(<) (F)
void SwapCrowbar(ITEM_INFO* item)//39638(<), 39B38(<) (F) void SwapCrowbar(ITEM_INFO* item)//39638(<), 39B38(<) (F)
{ {
if (Lara.meshPtrs[LM_RHAND] == Objects[ID_LARA].meshIndex + LM_RHAND) if (Lara.meshPtrs[LM_RHAND] == Objects[ID_LARA_SKIN].meshIndex + LM_RHAND)
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_CROWBAR_ANIM].meshIndex + LM_RHAND; Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_CROWBAR_ANIM].meshIndex + LM_RHAND;
else else
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA].meshIndex + LM_RHAND; Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
} }
void ActivateKey(ITEM_INFO* item)//39624(<), 39B24(<) (F) void ActivateKey(ITEM_INFO* item)//39624(<), 39B24(<) (F)

View file

@ -14,6 +14,7 @@
#include "spark.h" #include "spark.h"
#include "explosion.h" #include "explosion.h"
#include <Game\drip.h> #include <Game\drip.h>
#include <Game\bubble.h>
using T5M::Renderer::g_Renderer; using T5M::Renderer::g_Renderer;
using T5M::Effects::Explosion::TriggerExplosion; using T5M::Effects::Explosion::TriggerExplosion;
using namespace T5M::Effects::Spark; using namespace T5M::Effects::Spark;
@ -434,6 +435,55 @@ void TriggerExplosionSparks(int x, int y, int z, int extraTrig, int dynamic, int
TriggerExplosion(Vector3(x, y, z), 512, true, false, true, roomNumber); TriggerExplosion(Vector3(x, y, z), 512, true, false, true, roomNumber);
} }
void TriggerExplosionBubbles(int x, int y, int z, short roomNumber)
{
int dx = LaraItem->pos.xPos - x;
int dz = LaraItem->pos.zPos - z;
if (dx >= -ANGLE(90) && dx <= ANGLE(90) && dz >= -ANGLE(90) && dz <= ANGLE(90))
{
SPARKS* spark = &Sparks[GetFreeSpark()];
spark->sR = -128;
spark->dR = -128;
spark->dG = -128;
spark->dB = -128;
spark->on = 1;
spark->life = 24;
spark->sLife = 24;
spark->sG = 64;
spark->sB = 0;
spark->colFadeSpeed = 8;
spark->fadeToBlack = 12;
spark->transType = COLADD;
spark->x = x;
spark->y = y;
spark->z = z;
spark->xVel = 0;
spark->yVel = 0;
spark->zVel = 0;
spark->friction = 0;
spark->flags = SP_UNDERWEXP | SP_DEF | SP_SCALE;
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + 13;
spark->scalar = 3;
spark->gravity = 0;
spark->maxYvel = 0;
int size = (GetRandomControl() & 7) + 63;
spark->sSize = size >> 1;
spark->size = size >> 1;
spark->dSize = 2 * size;
for (int i = 0; i < 8; i++)
{
PHD_VECTOR pos;
pos.x = (GetRandomControl() & 0x1FF) + x - 256;
pos.y = (GetRandomControl() & 0x7F) + y - 64;
pos.z = (GetRandomControl() & 0x1FF) + z - 256;
CreateBubble(&pos, roomNumber, 6, 15, 0, 0, 0, 0);
}
}
}
void TriggerExplosionSmokeEnd(int x, int y, int z, int uw) void TriggerExplosionSmokeEnd(int x, int y, int z, int uw)
{ {
SPARKS* spark = &Sparks[GetFreeSpark()]; SPARKS* spark = &Sparks[GetFreeSpark()];
@ -761,9 +811,9 @@ void TriggerSuperJetFlame(ITEM_INFO* item, int yvel, int deadly)//32EAC, 333AC (
sptr->z = (GetRandomControl() & 0x1F) + item->pos.zPos - 16; sptr->z = (GetRandomControl() & 0x1F) + item->pos.zPos - 16;
sptr->friction = 51; sptr->friction = 51;
sptr->maxYvel = 0; sptr->maxYvel = 0;
sptr->flags = 538; sptr->flags = SP_EXPDEF | SP_ROTATE | SP_DEF | SP_SCALE;
if (deadly) if (deadly)
sptr->flags = 539; sptr->flags = SP_EXPDEF | SP_ROTATE | SP_DEF | SP_SCALE | SP_FLAT;
sptr->scalar = 2; sptr->scalar = 2;
sptr->dSize = (GetRandomControl() & 0xF) + (size >> 6) + 16; sptr->dSize = (GetRandomControl() & 0xF) + (size >> 6) + 16;
sptr->sSize = sptr->size = sptr->dSize >> 1; sptr->sSize = sptr->size = sptr->dSize >> 1;
@ -1163,7 +1213,7 @@ void KillAllCurrentItems(short itemNumber)
void TriggerDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b) void TriggerDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b)
{ {
g_Renderer.AddDynamicLight(x, y, z, falloff, r, g, b); g_Renderer.addDynamicLight(x, y, z, falloff, r, g, b);
} }
// Really needed? // Really needed?
@ -1301,6 +1351,56 @@ void TriggerRocketFlame(int x, int y, int z, int xv, int yv, int zv, int itemNum
sptr->size = sptr->sSize = size; sptr->size = sptr->sSize = size;
} }
void TriggerRocketFire(int x, int y, int z)
{
SPARKS* sptr = &Sparks[GetFreeSpark()];
sptr->on = true;
sptr->sR = sptr->sG = (GetRandomControl() & 0x1F) + 48;
sptr->sB = (GetRandomControl() & 0x3F) - 64;
sptr->dR = (GetRandomControl() & 0x3F) - 64;
sptr->dG = (GetRandomControl() & 0x3F) - 128;
sptr->dB = 32;
sptr->colFadeSpeed = 4 + (GetRandomControl() & 3);
sptr->fadeToBlack = 12;
sptr->sLife = sptr->life = (GetRandomControl() & 3) + 20;
sptr->transType = COLADD;
sptr->extras = 0;
sptr->dynamic = -1;
sptr->x = x + ((GetRandomControl() & 15) - 8);
sptr->y = y + ((GetRandomControl() & 15) - 8);
sptr->z = z + ((GetRandomControl() & 15) - 8);
sptr->xVel = ((GetRandomControl() & 255) - 128);
sptr->yVel = -(GetRandomControl() & 3) - 4;
sptr->zVel = ((GetRandomControl() & 255) - 128);
sptr->friction = 4;
if (GetRandomControl() & 1)
{
sptr->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF;
sptr->rotAng = GetRandomControl() & 4095;
if (GetRandomControl() & 1)
sptr->rotAdd = -(GetRandomControl() & 15) - 16;
else
sptr->rotAdd = (GetRandomControl() & 15) + 16;
}
else
sptr->flags = SP_SCALE | SP_DEF | SP_EXPDEF;
// TODO: right sprite
sptr->def = Objects[ID_DEFAULT_SPRITES].meshIndex;
sptr->scalar = 3;
sptr->gravity = -(GetRandomControl() & 3) - 4;
sptr->maxYvel = -(GetRandomControl() & 3) - 4;
int size = (GetRandomControl() & 7) + 32;
sptr->size = sptr->sSize = size >> 2;
}
void TriggerRocketSmoke(int x, int y, int z, int bodyPart) void TriggerRocketSmoke(int x, int y, int z, int bodyPart)
{ {
SPARKS* sptr = &Sparks[GetFreeSpark()]; SPARKS* sptr = &Sparks[GetFreeSpark()];

View file

@ -214,3 +214,5 @@ void GrenadeExplosionEffects(int x, int y, int z, short roomNumber);
void TriggerMetalSparks(int x, int y, int z, int xv, int yv, int zv, int additional); void TriggerMetalSparks(int x, int y, int z, int xv, int yv, int zv, int additional);
void WadeSplash(ITEM_INFO* item, int wh, int wd); void WadeSplash(ITEM_INFO* item, int wh, int wd);
void Splash(ITEM_INFO* item); void Splash(ITEM_INFO* item);
void TriggerRocketFire(int x, int y, int z);
void TriggerExplosionBubbles(int x, int y, int z, short roomNumber);

View file

@ -146,7 +146,7 @@ void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
} }
Matrix world; Matrix world;
g_Renderer.GetBoneMatrix(Lara.itemNumber, LM_HEAD, &world); g_Renderer.getBoneMatrix(Lara.itemNumber, LM_HEAD, &world);
if (ponytail) if (ponytail)
{ {

View file

@ -36,7 +36,7 @@ void DrawHealthBarOverlay(int value)
color2 = 0xA0A000; color2 = 0xA0A000;
else else
color2 = 0xA00000; color2 = 0xA00000;
g_Renderer.DrawBar(value, ::g_HealthBar); g_Renderer.drawBar(value, ::g_HealthBar);
} }
} }
@ -44,7 +44,7 @@ void DrawHealthBar(float value)
{ {
if (CurrentLevel) if (CurrentLevel)
{ {
g_Renderer.DrawBar(value, ::g_HealthBar); g_Renderer.drawBar(value, ::g_HealthBar);
} }
} }
@ -137,7 +137,7 @@ void DrawAirBar(float value)
{ {
if (CurrentLevel) if (CurrentLevel)
{ {
g_Renderer.DrawBar(value, ::g_AirBar); g_Renderer.drawBar(value, ::g_AirBar);
} }
} }
@ -183,7 +183,7 @@ void DrawDashBar(int value)
{ {
if (CurrentLevel) if (CurrentLevel)
{ {
g_Renderer.DrawBar(value, ::g_DashBar); g_Renderer.drawBar(value, ::g_DashBar);
} }
} }
@ -194,12 +194,12 @@ int DrawAllPickups()
if (PickupX > 0) if (PickupX > 0)
{ {
PickupX += -PickupX >> 5; PickupX += -PickupX >> 5;
return g_Renderer.DrawPickup(Pickups[CurrentPickup].objectNumber); g_Renderer.drawPickup(Pickups[CurrentPickup].objectNumber);
} }
else else
{ {
Pickups[CurrentPickup].life--; Pickups[CurrentPickup].life--;
return g_Renderer.DrawPickup(Pickups[CurrentPickup].objectNumber); g_Renderer.drawPickup(Pickups[CurrentPickup].objectNumber);
} }
} }
else if (Pickups[CurrentPickup].life == 0) else if (Pickups[CurrentPickup].life == 0)
@ -209,13 +209,13 @@ int DrawAllPickups()
if (PickupVel < 16) if (PickupVel < 16)
PickupVel++; PickupVel++;
PickupX += PickupVel >> 2; PickupX += PickupVel >> 2;
return g_Renderer.DrawPickup(Pickups[CurrentPickup].objectNumber); g_Renderer.drawPickup(Pickups[CurrentPickup].objectNumber);
} }
else else
{ {
Pickups[CurrentPickup].life = -1; Pickups[CurrentPickup].life = -1;
PickupVel = 0; PickupVel = 0;
return g_Renderer.DrawPickup(Pickups[CurrentPickup].objectNumber); g_Renderer.drawPickup(Pickups[CurrentPickup].objectNumber);
} }
} }
@ -230,7 +230,7 @@ int DrawAllPickups()
CurrentPickup = pickupIndex; CurrentPickup = pickupIndex;
if (i != MAX_COLLECTED_PICKUPS) if (i != MAX_COLLECTED_PICKUPS)
return g_Renderer.DrawPickup(Pickups[CurrentPickup].objectNumber); g_Renderer.drawPickup(Pickups[CurrentPickup].objectNumber);
CurrentPickup = 0; CurrentPickup = 0;

View file

@ -726,7 +726,7 @@ int Inventory::DoInventory()
passportResult == INV_RESULT_LOAD_GAME) passportResult == INV_RESULT_LOAD_GAME)
{ {
// Fade out // Fade out
g_Renderer.FadeOut(); g_Renderer.fadeOut();
for (int i = 0; i < FADE_FRAMES_COUNT; i++) for (int i = 0; i < FADE_FRAMES_COUNT; i++)
{ {
UpdateSceneAndDrawInventory(); UpdateSceneAndDrawInventory();
@ -1565,16 +1565,17 @@ void Inventory::UseCurrentItem()
} }
// TODO: can cause problem with harpoongun in underwater and wading ! // TODO: can cause problem with harpoongun in underwater and wading !
bool canUseWeapons = !(LaraItem->currentAnimState == LS_CRAWL_IDLE || bool canUseWeapons = (LaraItem->currentAnimState != LS_CRAWL_IDLE &&
LaraItem->currentAnimState == LS_CRAWL_FORWARD || LaraItem->currentAnimState != LS_CRAWL_FORWARD &&
LaraItem->currentAnimState == LS_CRAWL_TURN_LEFT || LaraItem->currentAnimState != LS_CRAWL_TURN_LEFT &&
LaraItem->currentAnimState == LS_CRAWL_TURN_RIGHT || LaraItem->currentAnimState != LS_CRAWL_TURN_RIGHT &&
LaraItem->currentAnimState == LS_CRAWL_BACK || LaraItem->currentAnimState != LS_CRAWL_BACK &&
LaraItem->currentAnimState == LS_CRAWL_TO_HANG || LaraItem->currentAnimState != LS_CRAWL_TO_HANG &&
LaraItem->currentAnimState == LS_CROUCH_IDLE || LaraItem->currentAnimState != LS_CROUCH_IDLE &&
LaraItem->currentAnimState == LS_CROUCH_TURN_LEFT || LaraItem->currentAnimState != LS_CROUCH_TURN_LEFT &&
LaraItem->currentAnimState == LS_CROUCH_TURN_RIGHT || LaraItem->currentAnimState != LS_CROUCH_TURN_RIGHT &&
Lara.waterStatus != LW_ABOVE_WATER); (Lara.waterStatus != LW_UNDERWATER
|| (Lara.waterStatus == LW_UNDERWATER && objectNumber == ID_HARPOON_ITEM)));
// Pistols // Pistols
if (objectNumber == ID_PISTOLS_ITEM) if (objectNumber == ID_PISTOLS_ITEM)
@ -1709,6 +1710,44 @@ void Inventory::UseCurrentItem()
return; return;
} }
// Harpoon gun
if (objectNumber == ID_HARPOON_ITEM)
{
if (canUseWeapons)
{
Lara.requestGunType = WEAPON_HARPOON_GUN;
if (!Lara.gunStatus && Lara.gunType == WEAPON_HARPOON_GUN)
Lara.gunStatus = LG_DRAW_GUNS;
SoundEffect(SFX_MENU_CHOOSE, NULL, 0);
}
else
{
SayNo();
}
return;
}
// Rocket launcher
if (objectNumber == ID_ROCKET_LAUNCHER_ITEM)
{
if (canUseWeapons)
{
Lara.requestGunType = WEAPON_ROCKET_LAUNCHER;
if (!Lara.gunStatus && Lara.gunType == WEAPON_ROCKET_LAUNCHER)
Lara.gunStatus = LG_DRAW_GUNS;
SoundEffect(SFX_MENU_CHOOSE, NULL, 0);
}
else
{
SayNo();
}
return;
}
// HK // HK
if (objectNumber == ID_HK_ITEM) if (objectNumber == ID_HK_ITEM)
{ {
@ -1804,7 +1843,7 @@ bool Inventory::UpdateSceneAndDrawInventory()
if (CurrentLevel == 0 && g_GameFlow->TitleType == TITLE_FLYBY) if (CurrentLevel == 0 && g_GameFlow->TitleType == TITLE_FLYBY)
{ {
g_Renderer.DrawTitle(); g_Renderer.renderTitle();
Camera.numberFrames = g_Renderer.SyncRenderer(); Camera.numberFrames = g_Renderer.SyncRenderer();
nframes = Camera.numberFrames; nframes = Camera.numberFrames;
@ -1812,7 +1851,7 @@ bool Inventory::UpdateSceneAndDrawInventory()
} }
else else
{ {
g_Renderer.DrawInventory(); g_Renderer.renderInventory();
g_Renderer.SyncRenderer(); g_Renderer.SyncRenderer();
} }
@ -1831,7 +1870,7 @@ int Inventory::DoTitleInventory()
m_activeRing = INV_RING_OPTIONS; m_activeRing = INV_RING_OPTIONS;
// Fade in // Fade in
g_Renderer.FadeIn(); g_Renderer.fadeIn();
for (int i = 0; i < FADE_FRAMES_COUNT; i++) for (int i = 0; i < FADE_FRAMES_COUNT; i++)
{ {
UpdateSceneAndDrawInventory(); UpdateSceneAndDrawInventory();
@ -1931,7 +1970,7 @@ int Inventory::DoTitleInventory()
CloseRing(INV_RING_OPTIONS, true); CloseRing(INV_RING_OPTIONS, true);
// Fade out // Fade out
g_Renderer.FadeOut(); g_Renderer.fadeOut();
for (int i = 0; i < FADE_FRAMES_COUNT; i++) for (int i = 0; i < FADE_FRAMES_COUNT; i++)
{ {
UpdateSceneAndDrawInventory(); UpdateSceneAndDrawInventory();
@ -2651,7 +2690,7 @@ void Inventory::DoGraphicsSettings()
memcpy(&ring->Configuration, &g_Configuration, sizeof(GameConfiguration)); memcpy(&ring->Configuration, &g_Configuration, sizeof(GameConfiguration));
// Get current display mode // Get current display mode
vector<RendererVideoAdapter>* adapters = g_Renderer.GetAdapters(); vector<RendererVideoAdapter>* adapters = g_Renderer.getAdapters();
RendererVideoAdapter* adapter = &(*adapters)[ring->Configuration.Adapter]; RendererVideoAdapter* adapter = &(*adapters)[ring->Configuration.Adapter];
ring->SelectedVideoMode = 0; ring->SelectedVideoMode = 0;
for (int i = 0; i < adapter->DisplayModes.size(); i++) for (int i = 0; i < adapter->DisplayModes.size(); i++)
@ -2782,7 +2821,7 @@ void Inventory::DoGraphicsSettings()
SaveConfiguration(); SaveConfiguration();
// Reset screen and go back // Reset screen and go back
g_Renderer.ChangeScreenResolution(ring->Configuration.Width, ring->Configuration.Height, g_Renderer.changeScreenResolution(ring->Configuration.Width, ring->Configuration.Height,
ring->Configuration.RefreshRate, ring->Configuration.Windowed); ring->Configuration.RefreshRate, ring->Configuration.Windowed);
closeObject = true; closeObject = true;

View file

@ -279,12 +279,12 @@ void InitialiseFXArray(int allocmem)
NextFxActive = NO_ITEM; NextFxActive = NO_ITEM;
NextFxFree = 0; NextFxFree = 0;
for (int i = 1; i < NUM_EFFECTS; i++, fx++) for (int i = 0; i < NUM_EFFECTS; i++)
{ {
fx = &EffectList[i]; fx = &EffectList[i];
fx->nextFx = i; fx->nextFx = i + 1;
} }
fx->nextFx = -1; EffectList[NUM_EFFECTS - 1].nextFx = NO_ITEM;
} }
void RemoveDrawnItem(short itemNum) void RemoveDrawnItem(short itemNum)

View file

@ -11,10 +11,16 @@ int malloc_used;
TGPool* gameMemory; TGPool* gameMemory;
void init_game_malloc() noexcept void init_game_malloc() noexcept
{ {
#if CUSTOM_MEMORY
gameMemory = new TGPool(8 * 1024 * 1024); gameMemory = new TGPool(8 * 1024 * 1024);
#endif
} }
void game_free(void* ptr) noexcept void game_free(void* ptr) noexcept
{ {
#if CUSTOM_MEMORY
gameMemory->free(ptr); gameMemory->free(ptr);
#else
delete[] ptr;
#endif
} }

View file

@ -11,7 +11,11 @@ extern T5M::Memory::TGPool* gameMemory;
template <typename T,typename ... Args> template <typename T,typename ... Args>
[[nodiscard]] T* game_malloc(size_t count = 1,Args&&...args) noexcept { [[nodiscard]] T* game_malloc(size_t count = 1,Args&&...args) noexcept {
#if CUSTOM_MEMORY
return gameMemory->malloc<T>(count,std::forward<Args>(args)...); return gameMemory->malloc<T>(count,std::forward<Args>(args)...);
#else
return new T[count]{std::forward<Args>(args)...};
#endif
} }
void init_game_malloc() noexcept; void init_game_malloc() noexcept;
void game_free(void* ptr) noexcept; void game_free(void* ptr) noexcept;

View file

@ -50,13 +50,13 @@ void TargetNearestEntity(ITEM_INFO* item, CREATURE_INFO* creature)
void GetRoomList(short roomNumber, short* roomArray, short* numRooms) void GetRoomList(short roomNumber, short* roomArray, short* numRooms)
{ {
if (*numRooms <= 0)
return;
short numDoors, * door, adjoiningRoom; short numDoors, * door, adjoiningRoom;
int i, j; int i, j;
bool adjoiningRoomFound; bool adjoiningRoomFound;
roomArray[0] = roomNumber; roomArray[0] = roomNumber;
*numRooms = 1;
ROOM_INFO* room = &g_Level.Rooms[roomNumber]; ROOM_INFO* room = &g_Level.Rooms[roomNumber];
for (i = 0; i < room->doors.size(); i++) for (i = 0; i < room->doors.size(); i++)
@ -74,7 +74,10 @@ void GetRoomList(short roomNumber, short* roomArray, short* numRooms)
} }
if (!adjoiningRoomFound) if (!adjoiningRoomFound)
roomArray[*(numRooms++)] = adjoiningRoom; {
roomArray[*numRooms] = adjoiningRoom;
*numRooms = *numRooms + 1;
}
} }
} }

View file

@ -44,6 +44,7 @@ typedef struct MESH_INFO
short shade; short shade;
short flags; short flags;
short staticNumber; short staticNumber;
short hitPoints;
}; };
typedef struct LIGHTINFO typedef struct LIGHTINFO

View file

@ -24,47 +24,47 @@ ChunkWriter* SaveGame::m_writer;
vector<LuaVariable> SaveGame::m_luaVariables; vector<LuaVariable> SaveGame::m_luaVariables;
int SaveGame::LastSaveGame; int SaveGame::LastSaveGame;
ChunkId* SaveGame::m_chunkGameStatus; std::unique_ptr<ChunkId> SaveGame::m_chunkGameStatus;
ChunkId* SaveGame::m_chunkItems; std::unique_ptr<ChunkId> SaveGame::m_chunkItems;
ChunkId* SaveGame::m_chunkItem; std::unique_ptr<ChunkId> SaveGame::m_chunkItem;
ChunkId* SaveGame::m_chunkLara; std::unique_ptr<ChunkId> SaveGame::m_chunkLara;
ChunkId* SaveGame::m_chunkLuaVariable; std::unique_ptr<ChunkId> SaveGame::m_chunkLuaVariable;
ChunkId* SaveGame::m_chunkStaticFlags; std::unique_ptr<ChunkId> SaveGame::m_chunkStaticFlags;
ChunkId* SaveGame::m_chunkVehicle; std::unique_ptr<ChunkId> SaveGame::m_chunkVehicle;
ChunkId* SaveGame::m_chunkSequenceSwitch; std::unique_ptr<ChunkId> SaveGame::m_chunkSequenceSwitch;
ChunkId* SaveGame::m_chunkFlybyFlags; std::unique_ptr<ChunkId> SaveGame::m_chunkFlybyFlags;
ChunkId* SaveGame::m_chunkCdFlags; std::unique_ptr<ChunkId> SaveGame::m_chunkCdFlags;
ChunkId* SaveGame::m_chunkCamera; std::unique_ptr<ChunkId> SaveGame::m_chunkCamera;
ChunkId* SaveGame::m_chunkFlipStats; std::unique_ptr<ChunkId> SaveGame::m_chunkFlipStats;
ChunkId* SaveGame::m_chunkFlipMap; std::unique_ptr<ChunkId> SaveGame::m_chunkFlipMap;
ChunkId* SaveGame::m_chunkItemDummy; std::unique_ptr<ChunkId> SaveGame::m_chunkItemDummy;
ChunkId* SaveGame::m_chunkStatistics; std::unique_ptr<ChunkId> SaveGame::m_chunkStatistics;
ChunkId* SaveGame::m_chunkItemAnims; std::unique_ptr<ChunkId> SaveGame::m_chunkItemAnims;
ChunkId* SaveGame::m_chunkItemMeshes; std::unique_ptr<ChunkId> SaveGame::m_chunkItemMeshes;
ChunkId* SaveGame::m_chunkItemFlags; std::unique_ptr<ChunkId> SaveGame::m_chunkItemFlags;
ChunkId* SaveGame::m_chunkItemHitPoints; std::unique_ptr<ChunkId> SaveGame::m_chunkItemHitPoints;
ChunkId* SaveGame::m_chunkItemPosition; std::unique_ptr<ChunkId> SaveGame::m_chunkItemPosition;
ChunkId* SaveGame::m_chunkItemIntelligentData; std::unique_ptr<ChunkId> SaveGame::m_chunkItemIntelligentData;
ChunkId* SaveGame::m_chunkSpecialItemBurningTorch; std::unique_ptr<ChunkId> SaveGame::m_chunkSpecialItemBurningTorch;
ChunkId* SaveGame::m_chunkSpecialItemChaff; std::unique_ptr<ChunkId> SaveGame::m_chunkSpecialItemChaff;
ChunkId* SaveGame::m_chunkSpecialItemTorpedo; std::unique_ptr<ChunkId> SaveGame::m_chunkSpecialItemTorpedo;
ChunkId* SaveGame::m_chunkSpecialItemCrossbowBolt; std::unique_ptr<ChunkId> SaveGame::m_chunkSpecialItemCrossbowBolt;
ChunkId* SaveGame::m_chunkSpecialItemFlare; std::unique_ptr<ChunkId> SaveGame::m_chunkSpecialItemFlare;
ChunkId* SaveGame::m_chunkItemQuadInfo; std::unique_ptr<ChunkId> SaveGame::m_chunkItemQuadInfo;
ChunkId* SaveGame::m_chunkBats; std::unique_ptr<ChunkId> SaveGame::m_chunkBats;
ChunkId* SaveGame::m_chunkRats; std::unique_ptr<ChunkId> SaveGame::m_chunkRats;
ChunkId* SaveGame::m_chunkSpiders; std::unique_ptr<ChunkId> SaveGame::m_chunkSpiders;
ChunkId* SaveGame::m_chunkLaraExtraInfo; std::unique_ptr<ChunkId> SaveGame::m_chunkLaraExtraInfo;
ChunkId* SaveGame::m_chunkWeaponInfo; std::unique_ptr<ChunkId> SaveGame::m_chunkWeaponInfo;
ChunkId* SaveGame::m_chunkPuzzle; std::unique_ptr<ChunkId> SaveGame::m_chunkPuzzle;
ChunkId* SaveGame::m_chunkKey; std::unique_ptr<ChunkId> SaveGame::m_chunkKey;
ChunkId* SaveGame::m_chunkPickup; std::unique_ptr<ChunkId> SaveGame::m_chunkPickup;
ChunkId* SaveGame::m_chunkExamine; std::unique_ptr<ChunkId> SaveGame::m_chunkExamine;
ChunkId* SaveGame::m_chunkPuzzleCombo; std::unique_ptr<ChunkId> SaveGame::m_chunkPuzzleCombo;
ChunkId* SaveGame::m_chunkKeyCombo; std::unique_ptr<ChunkId> SaveGame::m_chunkKeyCombo;
ChunkId* SaveGame::m_chunkPickupCombo; std::unique_ptr<ChunkId> SaveGame::m_chunkPickupCombo;
ChunkId* SaveGame::m_chunkExamineCombo; std::unique_ptr<ChunkId> SaveGame::m_chunkExamineCombo;
ChunkId* SaveGame::m_chunkWeaponItem; std::unique_ptr<ChunkId> SaveGame::m_chunkWeaponItem;
SAVEGAME_INFO Savegame; SAVEGAME_INFO Savegame;
extern vector<AudioTrack> g_AudioTracks; extern vector<AudioTrack> g_AudioTracks;
@ -77,7 +77,7 @@ void SaveGame::saveItems()
{ {
// Save level items // Save level items
for (int i = 0; i < g_Level.NumItems; i++) for (int i = 0; i < g_Level.NumItems; i++)
m_writer->WriteChunkWithChildren(m_chunkItem, &saveItem, i, 0); m_writer->WriteChunkWithChildren(m_chunkItem.get(), &saveItem, i, 0);
// Save items created at runtime (flares, missiles...) // Save items created at runtime (flares, missiles...)
for (int i = g_Level.NumItems; i < NUM_ITEMS; i++) for (int i = g_Level.NumItems; i < NUM_ITEMS; i++)
@ -87,17 +87,17 @@ void SaveGame::saveItems()
{ {
// Some items are very special and are saved in specific functions, all the others use the general function // Some items are very special and are saved in specific functions, all the others use the general function
if (item->objectNumber == ID_BURNING_TORCH_ITEM) if (item->objectNumber == ID_BURNING_TORCH_ITEM)
m_writer->WriteChunk(m_chunkSpecialItemBurningTorch, &saveBurningTorch, i, 1); m_writer->WriteChunk(m_chunkSpecialItemBurningTorch.get(), &saveBurningTorch, i, 1);
else if (item->objectNumber == ID_CHAFF) else if (item->objectNumber == ID_CHAFF)
m_writer->WriteChunk(m_chunkSpecialItemChaff, &saveChaff, i, 1); m_writer->WriteChunk(m_chunkSpecialItemChaff.get(), &saveChaff, i, 1);
else if (item->objectNumber == ID_TORPEDO) else if (item->objectNumber == ID_TORPEDO)
m_writer->WriteChunk(m_chunkSpecialItemTorpedo, &saveTorpedo, i, 1); m_writer->WriteChunk(m_chunkSpecialItemTorpedo.get(), &saveTorpedo, i, 1);
else if (item->objectNumber == ID_CROSSBOW_BOLT) else if (item->objectNumber == ID_CROSSBOW_BOLT)
m_writer->WriteChunk(m_chunkSpecialItemCrossbowBolt, &saveCrossbowBolt, i, 1); m_writer->WriteChunk(m_chunkSpecialItemCrossbowBolt.get(), &saveCrossbowBolt, i, 1);
else if (item->objectNumber == ID_FLARE_ITEM) else if (item->objectNumber == ID_FLARE_ITEM)
m_writer->WriteChunk(m_chunkSpecialItemFlare, &saveFlare, i, 1); m_writer->WriteChunk(m_chunkSpecialItemFlare.get(), &saveFlare, i, 1);
else else
m_writer->WriteChunkWithChildren(m_chunkItem, &saveItem, i, 1); m_writer->WriteChunkWithChildren(m_chunkItem.get(), &saveItem, i, 1);
} }
} }
@ -105,17 +105,17 @@ void SaveGame::saveItems()
if (Objects[ID_BATS_EMITTER].loaded) if (Objects[ID_BATS_EMITTER].loaded)
for (int i = 0; i < NUM_BATS; i++) for (int i = 0; i < NUM_BATS; i++)
if (Bats[i].on) if (Bats[i].on)
m_writer->WriteChunk(m_chunkBats, &saveBats, i, 0); m_writer->WriteChunk(m_chunkBats.get(), &saveBats, i, 0);
if (Objects[ID_RATS_EMITTER].loaded) if (Objects[ID_RATS_EMITTER].loaded)
for (int i = 0; i < NUM_RATS; i++) for (int i = 0; i < NUM_RATS; i++)
if (Rats[i].on) if (Rats[i].on)
m_writer->WriteChunk(m_chunkRats, &saveRats, i, 0); m_writer->WriteChunk(m_chunkRats.get(), &saveRats, i, 0);
if (Objects[ID_SPIDERS_EMITTER].loaded) if (Objects[ID_SPIDERS_EMITTER].loaded)
for (int i = 0; i < NUM_SPIDERS; i++) for (int i = 0; i < NUM_SPIDERS; i++)
if (Spiders[i].on) if (Spiders[i].on)
m_writer->WriteChunk(m_chunkSpiders, &saveSpiders, i, 0); m_writer->WriteChunk(m_chunkSpiders.get(), &saveSpiders, i, 0);
} }
void SaveGame::saveItem(int itemNumber, int runtimeItem) void SaveGame::saveItem(int itemNumber, int runtimeItem)
@ -149,29 +149,29 @@ void SaveGame::saveItem(int itemNumber, int runtimeItem)
if (hasData) if (hasData)
{ {
m_writer->WriteChunkInt(m_chunkItemDummy, 1); m_writer->WriteChunkInt(m_chunkItemDummy.get(), 1);
if (obj->saveAnim) if (obj->saveAnim)
m_writer->WriteChunk(m_chunkItemAnims, &saveItemAnims, itemNumber, 0); m_writer->WriteChunk(m_chunkItemAnims.get(), &saveItemAnims, itemNumber, 0);
if (obj->savePosition) if (obj->savePosition)
m_writer->WriteChunk(m_chunkItemPosition, &saveItemPosition, itemNumber, 0); m_writer->WriteChunk(m_chunkItemPosition.get(), &saveItemPosition, itemNumber, 0);
if (obj->saveHitpoints) if (obj->saveHitpoints)
m_writer->WriteChunk(m_chunkItemHitPoints, &saveItemHitPoints, itemNumber, 0); m_writer->WriteChunk(m_chunkItemHitPoints.get(), &saveItemHitPoints, itemNumber, 0);
if (obj->saveFlags) if (obj->saveFlags)
m_writer->WriteChunkWithChildren(m_chunkItemFlags, &saveItemFlags, itemNumber, 0); m_writer->WriteChunkWithChildren(m_chunkItemFlags.get(), &saveItemFlags, itemNumber, 0);
if (obj->saveMesh) if (obj->saveMesh)
m_writer->WriteChunk(m_chunkItemMeshes, &saveItemMesh, itemNumber, 0); m_writer->WriteChunk(m_chunkItemMeshes.get(), &saveItemMesh, itemNumber, 0);
if (obj->intelligent && item->data != NULL) if (obj->intelligent && item->data != NULL)
m_writer->WriteChunk(m_chunkItemIntelligentData, &saveItemIntelligentData, itemNumber, 0); m_writer->WriteChunk(m_chunkItemIntelligentData.get(), &saveItemIntelligentData, itemNumber, 0);
} }
else else
{ {
m_writer->WriteChunkInt(m_chunkItemDummy, 1); m_writer->WriteChunkInt(m_chunkItemDummy.get(), 1);
} }
} }
@ -187,25 +187,25 @@ void SaveGame::saveGameStatus(int arg1, int arg2)
// Now the sub-chunks // Now the sub-chunks
for (int i = 0; i < g_Level.Rooms.size(); i++) for (int i = 0; i < g_Level.Rooms.size(); i++)
for (int j = 0; j < g_Level.Rooms[i].mesh.size(); j++) for (int j = 0; j < g_Level.Rooms[i].mesh.size(); j++)
m_writer->WriteChunk(m_chunkStaticFlags, &saveStaticFlag, i, j); m_writer->WriteChunk(m_chunkStaticFlags.get(), &saveStaticFlag, i, j);
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
m_writer->WriteChunk(m_chunkSequenceSwitch, &saveSequenceSwitch, i, SequenceUsed[i]); m_writer->WriteChunk(m_chunkSequenceSwitch.get(), &saveSequenceSwitch, i, SequenceUsed[i]);
for (int i = 0; i < NumberSpotcams; i++) for (int i = 0; i < NumberSpotcams; i++)
m_writer->WriteChunk(m_chunkFlybyFlags, &saveFlybyFlags, i, SpotCam[i].flags); m_writer->WriteChunk(m_chunkFlybyFlags.get(), &saveFlybyFlags, i, SpotCam[i].flags);
for (int i = 0; i < g_AudioTracks.size(); i++) for (int i = 0; i < g_AudioTracks.size(); i++)
m_writer->WriteChunk(m_chunkCdFlags, &saveCdFlags, i, g_AudioTracks[i].Mask); m_writer->WriteChunk(m_chunkCdFlags.get(), &saveCdFlags, i, g_AudioTracks[i].Mask);
for (int i = 0; i < NumberCameras; i++) for (int i = 0; i < NumberCameras; i++)
m_writer->WriteChunk(m_chunkCamera, &saveCamera, i, FixedCameras[i].flags); m_writer->WriteChunk(m_chunkCamera.get(), &saveCamera, i, FixedCameras[i].flags);
for (int i = 0; i < 255; i++) for (int i = 0; i < 255; i++)
m_writer->WriteChunk(m_chunkFlipStats, &saveFlipStats, i, FlipStats[i]); m_writer->WriteChunk(m_chunkFlipStats.get(), &saveFlipStats, i, FlipStats[i]);
for (int i = 0; i < 255; i++) for (int i = 0; i < 255; i++)
m_writer->WriteChunk(m_chunkFlipMap, &saveFlipMap, i, FlipMap[i]); m_writer->WriteChunk(m_chunkFlipMap.get(), &saveFlipMap, i, FlipMap[i]);
} }
void SaveGame::saveLara(int arg1, int arg2) void SaveGame::saveLara(int arg1, int arg2)
@ -222,64 +222,64 @@ void SaveGame::saveLara(int arg1, int arg2)
// Lara weapon data // Lara weapon data
if (Lara.weaponItem != NO_ITEM) if (Lara.weaponItem != NO_ITEM)
m_writer->WriteChunk(m_chunkWeaponItem, &saveWeaponItem, Lara.weaponItem, 0); m_writer->WriteChunk(m_chunkWeaponItem.get(), &saveWeaponItem, Lara.weaponItem, 0);
// Save Lara extra info // Save Lara extra info
m_writer->WriteChunk(m_chunkLaraExtraInfo, &saveLaraExtraInfo, 0, 0); m_writer->WriteChunk(m_chunkLaraExtraInfo.get(), &saveLaraExtraInfo, 0, 0);
// Save carried weapons // Save carried weapons
for (int i = 0; i < NUM_WEAPONS; i++) for (int i = 0; i < NUM_WEAPONS; i++)
{ {
m_writer->WriteChunk(m_chunkWeaponInfo, &saveWeaponInfo, i, 0); m_writer->WriteChunk(m_chunkWeaponInfo.get(), &saveWeaponInfo, i, 0);
} }
// Save carried puzzles, keys, pickups and examines // Save carried puzzles, keys, pickups and examines
for (int i = 0; i < NUM_PUZZLES; i++) for (int i = 0; i < NUM_PUZZLES; i++)
{ {
if (Lara.Puzzles[i] > 0) if (Lara.Puzzles[i] > 0)
m_writer->WriteChunk(m_chunkPuzzle, &savePuzzle, i, Lara.Puzzles[i]); m_writer->WriteChunk(m_chunkPuzzle.get(), &savePuzzle, i, Lara.Puzzles[i]);
} }
for (int i = 0; i < NUM_PUZZLES * 2; i++) for (int i = 0; i < NUM_PUZZLES * 2; i++)
{ {
if (Lara.PuzzlesCombo[i] > 0) if (Lara.PuzzlesCombo[i] > 0)
m_writer->WriteChunk(m_chunkPuzzleCombo, &savePuzzle, i, Lara.PuzzlesCombo[i]); m_writer->WriteChunk(m_chunkPuzzleCombo.get(), &savePuzzle, i, Lara.PuzzlesCombo[i]);
} }
for (int i = 0; i < NUM_KEYS; i++) for (int i = 0; i < NUM_KEYS; i++)
{ {
if (Lara.Keys[i] > 0) if (Lara.Keys[i] > 0)
m_writer->WriteChunk(m_chunkKey, &savePuzzle, i, Lara.Keys[i]); m_writer->WriteChunk(m_chunkKey.get(), &savePuzzle, i, Lara.Keys[i]);
} }
for (int i = 0; i < NUM_KEYS * 2; i++) for (int i = 0; i < NUM_KEYS * 2; i++)
{ {
if (Lara.KeysCombo[i] > 0) if (Lara.KeysCombo[i] > 0)
m_writer->WriteChunk(m_chunkKeyCombo, &savePuzzle, i, Lara.KeysCombo[i]); m_writer->WriteChunk(m_chunkKeyCombo.get(), &savePuzzle, i, Lara.KeysCombo[i]);
} }
for (int i = 0; i < NUM_PICKUPS; i++) for (int i = 0; i < NUM_PICKUPS; i++)
{ {
if (Lara.Pickups[i] > 0) if (Lara.Pickups[i] > 0)
m_writer->WriteChunk(m_chunkPickup, &savePuzzle, i, Lara.Pickups[i]); m_writer->WriteChunk(m_chunkPickup.get(), &savePuzzle, i, Lara.Pickups[i]);
} }
for (int i = 0; i < NUM_PICKUPS * 2; i++) for (int i = 0; i < NUM_PICKUPS * 2; i++)
{ {
if (Lara.PickupsCombo[i] > 0) if (Lara.PickupsCombo[i] > 0)
m_writer->WriteChunk(m_chunkPickupCombo, &savePuzzle, i, Lara.PickupsCombo[i]); m_writer->WriteChunk(m_chunkPickupCombo.get(), &savePuzzle, i, Lara.PickupsCombo[i]);
} }
for (int i = 0; i < NUM_EXAMINES; i++) for (int i = 0; i < NUM_EXAMINES; i++)
{ {
if (Lara.Examines[i] > 0) if (Lara.Examines[i] > 0)
m_writer->WriteChunk(m_chunkExamine, &savePuzzle, i, Lara.Examines[i]); m_writer->WriteChunk(m_chunkExamine.get(), &savePuzzle, i, Lara.Examines[i]);
} }
for (int i = 0; i < NUM_EXAMINES * 2; i++) for (int i = 0; i < NUM_EXAMINES * 2; i++)
{ {
if (Lara.ExaminesCombo[i] > 0) if (Lara.ExaminesCombo[i] > 0)
m_writer->WriteChunk(m_chunkExamineCombo, &savePuzzle, i, Lara.ExaminesCombo[i]); m_writer->WriteChunk(m_chunkExamineCombo.get(), &savePuzzle, i, Lara.ExaminesCombo[i]);
} }
} }
@ -337,7 +337,7 @@ void SaveGame::saveVariables()
m_luaVariables.clear(); m_luaVariables.clear();
//g_GameScript->GetVariables(&m_luaVariables); //g_GameScript->GetVariables(&m_luaVariables);
for (int i = 0; i < m_luaVariables.size(); i++) for (int i = 0; i < m_luaVariables.size(); i++)
m_writer->WriteChunk(m_chunkLuaVariable, &saveVariable, i, 0); m_writer->WriteChunk(m_chunkLuaVariable.get(), &saveVariable, i, 0);
} }
void SaveGame::saveVariable(int arg1, int arg2) void SaveGame::saveVariable(int arg1, int arg2)
@ -407,47 +407,6 @@ void SaveGame::Start()
void SaveGame::End() void SaveGame::End()
{ {
delete m_chunkGameStatus;
delete m_chunkItems;
delete m_chunkItem;
delete m_chunkLara;
delete m_chunkLuaVariable;
delete m_chunkStaticFlags;
delete m_chunkVehicle;
delete m_chunkFlipMap;
delete m_chunkFlipStats;
delete m_chunkFlybyFlags;
delete m_chunkSequenceSwitch;
delete m_chunkCdFlags;
delete m_chunkCamera;
delete m_chunkItemDummy;
delete m_chunkStatistics;
delete m_chunkItemAnims;
delete m_chunkItemMeshes;
delete m_chunkItemFlags;
delete m_chunkItemHitPoints;
delete m_chunkItemPosition;
delete m_chunkItemIntelligentData;
delete m_chunkSpecialItemBurningTorch;
delete m_chunkSpecialItemChaff;
delete m_chunkSpecialItemTorpedo;
delete m_chunkSpecialItemCrossbowBolt;
delete m_chunkSpecialItemFlare;
delete m_chunkItemQuadInfo;
delete m_chunkBats;
delete m_chunkRats;
delete m_chunkSpiders;
delete m_chunkLaraExtraInfo;
delete m_chunkWeaponInfo;
delete m_chunkPuzzle;
delete m_chunkKey;
delete m_chunkPickup;
delete m_chunkExamine;
delete m_chunkPuzzleCombo;
delete m_chunkKeyCombo;
delete m_chunkPickupCombo;
delete m_chunkExamineCombo;
delete m_chunkWeaponItem;
} }
bool SaveGame::Save(char* fileName) bool SaveGame::Save(char* fileName)
@ -468,9 +427,9 @@ bool SaveGame::Save(char* fileName)
LEB128::Write(m_stream, ++LastSaveGame); LEB128::Write(m_stream, ++LastSaveGame);
// Now we write chunks // Now we write chunks
m_writer->WriteChunk(m_chunkStatistics, &saveStatistics, 0, 0); m_writer->WriteChunk(m_chunkStatistics.get(), &saveStatistics, 0, 0);
m_writer->WriteChunkWithChildren(m_chunkGameStatus, &saveGameStatus, 0, 0); m_writer->WriteChunkWithChildren(m_chunkGameStatus.get(), &saveGameStatus, 0, 0);
m_writer->WriteChunkWithChildren(m_chunkLara, &saveLara, 0, 0); m_writer->WriteChunkWithChildren(m_chunkLara.get(), &saveLara, 0, 0);
saveItems(); saveItems();
saveVariables(); saveVariables();
@ -631,31 +590,31 @@ bool SaveGame::readVariable()
bool SaveGame::readSavegameChunks(ChunkId* chunkId, int maxSize, int arg) bool SaveGame::readSavegameChunks(ChunkId* chunkId, int maxSize, int arg)
{ {
if (chunkId->EqualsTo(m_chunkGameStatus)) if (chunkId->EqualsTo(m_chunkGameStatus.get()))
return readGameStatus(); return readGameStatus();
else if (chunkId->EqualsTo(m_chunkLara)) else if (chunkId->EqualsTo(m_chunkLara.get()))
return readLara(); return readLara();
else if (chunkId->EqualsTo(m_chunkItem)) else if (chunkId->EqualsTo(m_chunkItem.get()))
return readItem(); return readItem();
else if (chunkId->EqualsTo(m_chunkLuaVariable)) else if (chunkId->EqualsTo(m_chunkLuaVariable.get()))
return readVariable(); return readVariable();
else if (chunkId->EqualsTo(m_chunkStatistics)) else if (chunkId->EqualsTo(m_chunkStatistics.get()))
return readStatistics(); return readStatistics();
else if (chunkId->EqualsTo(m_chunkSpecialItemBurningTorch)) else if (chunkId->EqualsTo(m_chunkSpecialItemBurningTorch.get()))
return readBurningTorch(); return readBurningTorch();
else if (chunkId->EqualsTo(m_chunkSpecialItemChaff)) else if (chunkId->EqualsTo(m_chunkSpecialItemChaff.get()))
return readChaff(); return readChaff();
else if (chunkId->EqualsTo(m_chunkSpecialItemTorpedo)) else if (chunkId->EqualsTo(m_chunkSpecialItemTorpedo.get()))
return readTorpedo(); return readTorpedo();
else if (chunkId->EqualsTo(m_chunkSpecialItemCrossbowBolt)) else if (chunkId->EqualsTo(m_chunkSpecialItemCrossbowBolt.get()))
return readCrossbowBolt(); return readCrossbowBolt();
else if (chunkId->EqualsTo(m_chunkSpecialItemFlare)) else if (chunkId->EqualsTo(m_chunkSpecialItemFlare.get()))
return readFlare(); return readFlare();
else if (chunkId->EqualsTo(m_chunkBats)) else if (chunkId->EqualsTo(m_chunkBats.get()))
return readBats(); return readBats();
else if (chunkId->EqualsTo(m_chunkRats)) else if (chunkId->EqualsTo(m_chunkRats.get()))
return readRats(); return readRats();
else if (chunkId->EqualsTo(m_chunkSpiders)) else if (chunkId->EqualsTo(m_chunkSpiders.get()))
return readSpiders(); return readSpiders();
return false; return false;
@ -735,7 +694,7 @@ void SaveGame::saveStaticFlag(int arg1, int arg2)
bool SaveGame::readLaraChunks(ChunkId* chunkId, int maxSize, int arg) bool SaveGame::readLaraChunks(ChunkId* chunkId, int maxSize, int arg)
{ {
if (chunkId->EqualsTo(m_chunkLaraExtraInfo)) if (chunkId->EqualsTo(m_chunkLaraExtraInfo.get()))
{ {
Lara.Binoculars = LEB128::ReadByte(m_stream); Lara.Binoculars = LEB128::ReadByte(m_stream);
Lara.Lasersight = LEB128::ReadByte(m_stream); Lara.Lasersight = LEB128::ReadByte(m_stream);
@ -753,7 +712,7 @@ bool SaveGame::readLaraChunks(ChunkId* chunkId, int maxSize, int arg)
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkWeaponInfo)) else if (chunkId->EqualsTo(m_chunkWeaponInfo.get()))
{ {
int id = LEB128::ReadInt32(m_stream); int id = LEB128::ReadInt32(m_stream);
CarriedWeaponInfo* weapon = &Lara.Weapons[id]; CarriedWeaponInfo* weapon = &Lara.Weapons[id];
@ -766,55 +725,55 @@ bool SaveGame::readLaraChunks(ChunkId* chunkId, int maxSize, int arg)
weapon->HasSilencer = LEB128::ReadByte(m_stream); weapon->HasSilencer = LEB128::ReadByte(m_stream);
weapon->HasLasersight = LEB128::ReadByte(m_stream); weapon->HasLasersight = LEB128::ReadByte(m_stream);
} }
else if (chunkId->EqualsTo(m_chunkPuzzle)) else if (chunkId->EqualsTo(m_chunkPuzzle.get()))
{ {
int id = LEB128::ReadInt32(m_stream); int id = LEB128::ReadInt32(m_stream);
int quantity = LEB128::ReadInt32(m_stream); int quantity = LEB128::ReadInt32(m_stream);
Lara.Puzzles[id] = quantity; Lara.Puzzles[id] = quantity;
} }
else if (chunkId->EqualsTo(m_chunkPuzzleCombo)) else if (chunkId->EqualsTo(m_chunkPuzzleCombo.get()))
{ {
int id = LEB128::ReadInt32(m_stream); int id = LEB128::ReadInt32(m_stream);
int quantity = LEB128::ReadInt32(m_stream); int quantity = LEB128::ReadInt32(m_stream);
Lara.PuzzlesCombo[id] = quantity; Lara.PuzzlesCombo[id] = quantity;
} }
else if (chunkId->EqualsTo(m_chunkKey)) else if (chunkId->EqualsTo(m_chunkKey.get()))
{ {
int id = LEB128::ReadInt32(m_stream); int id = LEB128::ReadInt32(m_stream);
int quantity = LEB128::ReadInt32(m_stream); int quantity = LEB128::ReadInt32(m_stream);
Lara.Keys[id] = quantity; Lara.Keys[id] = quantity;
} }
else if (chunkId->EqualsTo(m_chunkKeyCombo)) else if (chunkId->EqualsTo(m_chunkKeyCombo.get()))
{ {
int id = LEB128::ReadInt32(m_stream); int id = LEB128::ReadInt32(m_stream);
int quantity = LEB128::ReadInt32(m_stream); int quantity = LEB128::ReadInt32(m_stream);
Lara.KeysCombo[id] = quantity; Lara.KeysCombo[id] = quantity;
} }
else if (chunkId->EqualsTo(m_chunkPickup)) else if (chunkId->EqualsTo(m_chunkPickup.get()))
{ {
int id = LEB128::ReadInt32(m_stream); int id = LEB128::ReadInt32(m_stream);
int quantity = LEB128::ReadInt32(m_stream); int quantity = LEB128::ReadInt32(m_stream);
Lara.Pickups[id] = quantity; Lara.Pickups[id] = quantity;
} }
else if (chunkId->EqualsTo(m_chunkPickupCombo)) else if (chunkId->EqualsTo(m_chunkPickupCombo.get()))
{ {
int id = LEB128::ReadInt32(m_stream); int id = LEB128::ReadInt32(m_stream);
int quantity = LEB128::ReadInt32(m_stream); int quantity = LEB128::ReadInt32(m_stream);
Lara.PickupsCombo[id] = quantity; Lara.PickupsCombo[id] = quantity;
} }
else if (chunkId->EqualsTo(m_chunkExamine)) else if (chunkId->EqualsTo(m_chunkExamine.get()))
{ {
int id = LEB128::ReadInt32(m_stream); int id = LEB128::ReadInt32(m_stream);
int quantity = LEB128::ReadInt32(m_stream); int quantity = LEB128::ReadInt32(m_stream);
Lara.Examines[id] = quantity; Lara.Examines[id] = quantity;
} }
else if (chunkId->EqualsTo(m_chunkExamineCombo)) else if (chunkId->EqualsTo(m_chunkExamineCombo.get()))
{ {
int id = LEB128::ReadInt32(m_stream); int id = LEB128::ReadInt32(m_stream);
int quantity = LEB128::ReadInt32(m_stream); int quantity = LEB128::ReadInt32(m_stream);
Lara.ExaminesCombo[id] = quantity; Lara.ExaminesCombo[id] = quantity;
} }
else if (chunkId->EqualsTo(m_chunkWeaponItem)) else if (chunkId->EqualsTo(m_chunkWeaponItem.get()))
{ {
short weaponItemNum = CreateItem(); short weaponItemNum = CreateItem();
Lara.weaponItem = weaponItemNum; Lara.weaponItem = weaponItemNum;
@ -835,7 +794,7 @@ bool SaveGame::readLaraChunks(ChunkId* chunkId, int maxSize, int arg)
bool SaveGame::readGameStatusChunks(ChunkId* chunkId, int maxSize, int arg) bool SaveGame::readGameStatusChunks(ChunkId* chunkId, int maxSize, int arg)
{ {
if (chunkId->EqualsTo(m_chunkStaticFlags)) if (chunkId->EqualsTo(m_chunkStaticFlags.get()))
{ {
short roomIndex = LEB128::ReadInt16(m_stream); short roomIndex = LEB128::ReadInt16(m_stream);
short staticIndex = LEB128::ReadInt16(m_stream); short staticIndex = LEB128::ReadInt16(m_stream);
@ -857,14 +816,14 @@ bool SaveGame::readGameStatusChunks(ChunkId* chunkId, int maxSize, int arg)
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkFlipStats)) else if (chunkId->EqualsTo(m_chunkFlipStats.get()))
{ {
short index = LEB128::ReadInt16(m_stream); short index = LEB128::ReadInt16(m_stream);
short value = LEB128::ReadInt16(m_stream); short value = LEB128::ReadInt16(m_stream);
//FlipStats[index] = value; //FlipStats[index] = value;
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkFlipMap)) else if (chunkId->EqualsTo(m_chunkFlipMap.get()))
{ {
short index = LEB128::ReadInt16(m_stream); short index = LEB128::ReadInt16(m_stream);
short value = LEB128::ReadInt16(m_stream); short value = LEB128::ReadInt16(m_stream);
@ -873,7 +832,7 @@ bool SaveGame::readGameStatusChunks(ChunkId* chunkId, int maxSize, int arg)
DoFlipMap(index); DoFlipMap(index);
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkCdFlags)) else if (chunkId->EqualsTo(m_chunkCdFlags.get()))
{ {
short index = LEB128::ReadInt16(m_stream); short index = LEB128::ReadInt16(m_stream);
printf("Index: %d\n", index); printf("Index: %d\n", index);
@ -882,21 +841,21 @@ bool SaveGame::readGameStatusChunks(ChunkId* chunkId, int maxSize, int arg)
g_AudioTracks[index].Mask = value; g_AudioTracks[index].Mask = value;
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkCamera)) else if (chunkId->EqualsTo(m_chunkCamera.get()))
{ {
short index = LEB128::ReadInt16(m_stream); short index = LEB128::ReadInt16(m_stream);
short value = LEB128::ReadInt16(m_stream); short value = LEB128::ReadInt16(m_stream);
FixedCameras[index].flags = value; FixedCameras[index].flags = value;
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkSequenceSwitch)) else if (chunkId->EqualsTo(m_chunkSequenceSwitch.get()))
{ {
short index = LEB128::ReadInt16(m_stream); short index = LEB128::ReadInt16(m_stream);
short value = LEB128::ReadInt16(m_stream); short value = LEB128::ReadInt16(m_stream);
SequenceUsed[index] = value; SequenceUsed[index] = value;
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkFlybyFlags)) else if (chunkId->EqualsTo(m_chunkFlybyFlags.get()))
{ {
int index = LEB128::ReadInt16(m_stream); int index = LEB128::ReadInt16(m_stream);
int value = LEB128::ReadInt16(m_stream); int value = LEB128::ReadInt16(m_stream);
@ -946,9 +905,9 @@ bool SaveGame::readItemChunks(ChunkId* chunkId, int maxSize, int itemNumber)
{ {
ITEM_INFO* item = &g_Level.Items[itemNumber]; ITEM_INFO* item = &g_Level.Items[itemNumber];
if (chunkId->EqualsTo(m_chunkItemDummy)) if (chunkId->EqualsTo(m_chunkItemDummy.get()))
return m_reader->ReadChunkInt32(maxSize); return m_reader->ReadChunkInt32(maxSize);
else if (chunkId->EqualsTo(m_chunkItemAnims)) else if (chunkId->EqualsTo(m_chunkItemAnims.get()))
{ {
item->currentAnimState = LEB128::ReadInt16(m_stream); item->currentAnimState = LEB128::ReadInt16(m_stream);
item->goalAnimState = LEB128::ReadInt16(m_stream); item->goalAnimState = LEB128::ReadInt16(m_stream);
@ -958,7 +917,7 @@ bool SaveGame::readItemChunks(ChunkId* chunkId, int maxSize, int itemNumber)
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkItemPosition)) else if (chunkId->EqualsTo(m_chunkItemPosition.get()))
{ {
item->pos.xPos = LEB128::ReadInt32(m_stream); item->pos.xPos = LEB128::ReadInt32(m_stream);
item->pos.yPos = LEB128::ReadInt32(m_stream); item->pos.yPos = LEB128::ReadInt32(m_stream);
@ -976,13 +935,13 @@ bool SaveGame::readItemChunks(ChunkId* chunkId, int maxSize, int itemNumber)
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkItemHitPoints)) else if (chunkId->EqualsTo(m_chunkItemHitPoints.get()))
{ {
item->hitPoints = LEB128::ReadInt16(m_stream); item->hitPoints = LEB128::ReadInt16(m_stream);
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkItemFlags)) else if (chunkId->EqualsTo(m_chunkItemFlags.get()))
{ {
item->flags = LEB128::ReadInt16(m_stream); item->flags = LEB128::ReadInt16(m_stream);
byte active = LEB128::ReadByte(m_stream); byte active = LEB128::ReadByte(m_stream);
@ -1007,7 +966,7 @@ bool SaveGame::readItemChunks(ChunkId* chunkId, int maxSize, int itemNumber)
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkItemIntelligentData)) else if (chunkId->EqualsTo(m_chunkItemIntelligentData.get()))
{ {
EnableBaddieAI(itemNumber, 1); EnableBaddieAI(itemNumber, 1);
@ -1052,7 +1011,7 @@ bool SaveGame::readItemChunks(ChunkId* chunkId, int maxSize, int itemNumber)
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkItemQuadInfo)) else if (chunkId->EqualsTo(m_chunkItemQuadInfo.get()))
{ {
QUAD_INFO* quadInfo = game_malloc<QUAD_INFO>(); QUAD_INFO* quadInfo = game_malloc<QUAD_INFO>();
m_stream->ReadBytes(reinterpret_cast<byte*>(quadInfo), sizeof(QUAD_INFO)); m_stream->ReadBytes(reinterpret_cast<byte*>(quadInfo), sizeof(QUAD_INFO));
@ -1061,7 +1020,7 @@ bool SaveGame::readItemChunks(ChunkId* chunkId, int maxSize, int itemNumber)
return true; return true;
} }
else if (chunkId->EqualsTo(m_chunkItemMeshes)) else if (chunkId->EqualsTo(m_chunkItemMeshes.get()))
{ {
item->meshBits = LEB128::ReadInt32(m_stream); item->meshBits = LEB128::ReadInt32(m_stream);
item->swapMeshFlags = LEB128::ReadInt32(m_stream); item->swapMeshFlags = LEB128::ReadInt32(m_stream);

View file

@ -69,47 +69,47 @@ private:
static ChunkWriter* m_writer; static ChunkWriter* m_writer;
static std::vector<LuaVariable> m_luaVariables; static std::vector<LuaVariable> m_luaVariables;
static ChunkId* m_chunkGameStatus; static std::unique_ptr<ChunkId> m_chunkGameStatus;
static ChunkId* m_chunkItems; static std::unique_ptr<ChunkId> m_chunkItems;
static ChunkId* m_chunkItem; static std::unique_ptr<ChunkId> m_chunkItem;
static ChunkId* m_chunkLara; static std::unique_ptr<ChunkId> m_chunkLara;
static ChunkId* m_chunkLuaVariable; static std::unique_ptr<ChunkId> m_chunkLuaVariable;
static ChunkId* m_chunkStaticFlags; static std::unique_ptr<ChunkId> m_chunkStaticFlags;
static ChunkId* m_chunkVehicle; static std::unique_ptr<ChunkId> m_chunkVehicle;
static ChunkId* m_chunkSequenceSwitch; static std::unique_ptr<ChunkId> m_chunkSequenceSwitch;
static ChunkId* m_chunkFlybyFlags; static std::unique_ptr<ChunkId> m_chunkFlybyFlags;
static ChunkId* m_chunkCdFlags; static std::unique_ptr<ChunkId> m_chunkCdFlags;
static ChunkId* m_chunkCamera; static std::unique_ptr<ChunkId> m_chunkCamera;
static ChunkId* m_chunkFlipStats; static std::unique_ptr<ChunkId> m_chunkFlipStats;
static ChunkId* m_chunkFlipMap; static std::unique_ptr<ChunkId> m_chunkFlipMap;
static ChunkId* m_chunkItemDummy; static std::unique_ptr<ChunkId> m_chunkItemDummy;
static ChunkId* m_chunkStatistics; static std::unique_ptr<ChunkId> m_chunkStatistics;
static ChunkId* m_chunkItemAnims; static std::unique_ptr<ChunkId> m_chunkItemAnims;
static ChunkId* m_chunkItemMeshes; static std::unique_ptr<ChunkId> m_chunkItemMeshes;
static ChunkId* m_chunkItemFlags; static std::unique_ptr<ChunkId> m_chunkItemFlags;
static ChunkId* m_chunkItemHitPoints; static std::unique_ptr<ChunkId> m_chunkItemHitPoints;
static ChunkId* m_chunkItemPosition; static std::unique_ptr<ChunkId> m_chunkItemPosition;
static ChunkId* m_chunkItemIntelligentData; static std::unique_ptr<ChunkId> m_chunkItemIntelligentData;
static ChunkId* m_chunkSpecialItemBurningTorch; static std::unique_ptr<ChunkId> m_chunkSpecialItemBurningTorch;
static ChunkId* m_chunkSpecialItemChaff; static std::unique_ptr<ChunkId> m_chunkSpecialItemChaff;
static ChunkId* m_chunkSpecialItemTorpedo; static std::unique_ptr<ChunkId> m_chunkSpecialItemTorpedo;
static ChunkId* m_chunkSpecialItemCrossbowBolt; static std::unique_ptr<ChunkId> m_chunkSpecialItemCrossbowBolt;
static ChunkId* m_chunkSpecialItemFlare; static std::unique_ptr<ChunkId> m_chunkSpecialItemFlare;
static ChunkId* m_chunkItemQuadInfo; static std::unique_ptr<ChunkId> m_chunkItemQuadInfo;
static ChunkId* m_chunkRats; static std::unique_ptr<ChunkId> m_chunkRats;
static ChunkId* m_chunkSpiders; static std::unique_ptr<ChunkId> m_chunkSpiders;
static ChunkId* m_chunkBats; static std::unique_ptr<ChunkId> m_chunkBats;
static ChunkId* m_chunkLaraExtraInfo; static std::unique_ptr<ChunkId> m_chunkLaraExtraInfo;
static ChunkId* m_chunkWeaponInfo; static std::unique_ptr<ChunkId> m_chunkWeaponInfo;
static ChunkId* m_chunkPuzzle; static std::unique_ptr<ChunkId> m_chunkPuzzle;
static ChunkId* m_chunkKey; static std::unique_ptr<ChunkId> m_chunkKey;
static ChunkId* m_chunkPickup; static std::unique_ptr<ChunkId> m_chunkPickup;
static ChunkId* m_chunkExamine; static std::unique_ptr<ChunkId> m_chunkExamine;
static ChunkId* m_chunkPuzzleCombo; static std::unique_ptr<ChunkId> m_chunkPuzzleCombo;
static ChunkId* m_chunkKeyCombo; static std::unique_ptr<ChunkId> m_chunkKeyCombo;
static ChunkId* m_chunkPickupCombo; static std::unique_ptr<ChunkId> m_chunkPickupCombo;
static ChunkId* m_chunkExamineCombo; static std::unique_ptr<ChunkId> m_chunkExamineCombo;
static ChunkId* m_chunkWeaponItem; static std::unique_ptr<ChunkId> m_chunkWeaponItem;
static void saveGameStatus(int arg1, int arg2); static void saveGameStatus(int arg1, int arg2);
static void saveLara(int arg1, int arg2); static void saveLara(int arg1, int arg2);

View file

@ -10,7 +10,14 @@ namespace T5M {
namespace Effects { namespace Effects {
namespace Smoke { namespace Smoke {
std::array<SmokeParticle, 128> SmokeParticles; std::array<SmokeParticle, 128> SmokeParticles;
SmokeParticle& getFreeSmokeParticle()
{
for(int i = 0; i < SmokeParticles.size(); i++){
if(!SmokeParticles[i].active)
return SmokeParticles[i];
}
return SmokeParticles[0];
}
void UpdateSmokeParticles() void UpdateSmokeParticles()
{ {
for (int i = 0; i < SmokeParticles.size(); i++) { for (int i = 0; i < SmokeParticles.size(); i++) {
@ -70,23 +77,15 @@ namespace T5M {
s.room = room; s.room = room;
} }
SmokeParticle& getFreeSmokeParticle()
{
for (int i = 0; i < SmokeParticles.size(); i++) {
if (!SmokeParticles[i].active)
return SmokeParticles[i];
}
return SmokeParticles[0];
}
void TriggerGunSmokeParticles(int x, int y, int z, short xv, short yv, short zv, byte initial, int weaponType, byte count) void TriggerGunSmokeParticles(int x, int y, int z, short xv, short yv, short zv, byte initial, int weaponType, byte count)
{ {
SmokeParticle& s = getFreeSmokeParticle(); SmokeParticle& s = getFreeSmokeParticle();
s = {}; s = {};
s.active = true; s.active = true;
s.position = Vector3(x, y, z); s.position = Vector3(x, y, z);
Vector3(xv, yv, zv).Normalize(s.velocity); Vector3 dir = Vector3(xv, yv, zv);
s.velocity *= frand() * 24 + 16; dir.Normalize();
s.velocity = dir;
s.gravity = -.1f; s.gravity = -.1f;
s.affectedByWind = g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND; s.affectedByWind = g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND;
s.sourceColor = Vector4(.4, .4, .4, 1); s.sourceColor = Vector4(.4, .4, .4, 1);
@ -98,9 +97,10 @@ namespace T5M {
s.sourceSize = size *2; s.sourceSize = size *2;
s.destinationSize = size * 8; s.destinationSize = size * 8;
s.terminalVelocity = 0; s.terminalVelocity = 0;
s.friction = 0.90f; s.friction = 0.88f;
s.life = frand() * 30 + 60; s.life = frand() * 30 + 60;
s.velocity = getRandomVectorInCone(s.velocity, 10);
s.velocity *= frand() * 14 + 16;
} }
else else
{ {
@ -111,13 +111,14 @@ namespace T5M {
s.terminalVelocity = 0; s.terminalVelocity = 0;
s.friction = 0.97f; s.friction = 0.97f;
s.life = frand() * 20 + 42; s.life = frand() * 20 + 42;
s.velocity *= frand() * 24 + 16;
} }
s.position = Vector3(x, y, z); s.position = Vector3(x, y, z);
s.position += Vector3(frandMinMax(-8, 8), frandMinMax(-8, 8), frandMinMax(-8, 8)); s.position += Vector3(frandMinMax(-8, 8), frandMinMax(-8, 8), frandMinMax(-8, 8));
s.angularVelocity = frandMinMax(-PI / 4, PI / 4); s.angularVelocity = frandMinMax(-PI / 4, PI / 4);
s.angularDrag = 0.8f; s.angularDrag = 0.95f;
s.room = LaraItem->roomNumber; s.room = LaraItem->roomNumber;
} }

View file

@ -32,7 +32,6 @@ namespace T5M{
void UpdateSmokeParticles(); void UpdateSmokeParticles();
void TriggerFlareSmoke(const DirectX::SimpleMath::Vector3& pos, DirectX::SimpleMath::Vector3& direction, int age, int room); void TriggerFlareSmoke(const DirectX::SimpleMath::Vector3& pos, DirectX::SimpleMath::Vector3& direction, int age, int room);
SmokeParticle& getFreeSmokeParticle();
void TriggerGunSmokeParticles(int x, int y, int z, short xv, short yv, short zv, byte initial, int weaponType, byte count); void TriggerGunSmokeParticles(int x, int y, int z, short xv, short yv, short zv, byte initial, int weaponType, byte count);
} }

View file

@ -20,7 +20,7 @@ int GetSpheres(ITEM_INFO* item, SPHERE* ptr, int worldSpace, Matrix local)
BoundingSphere spheres[MAX_SPHERES]; BoundingSphere spheres[MAX_SPHERES];
short itemNumber = (item - g_Level.Items.data()); short itemNumber = (item - g_Level.Items.data());
int num = g_Renderer.GetSpheres(itemNumber, spheres, worldSpace, local); int num = g_Renderer.getSpheres(itemNumber, spheres, worldSpace, local);
for (int i = 0; i < MAX_SPHERES; i++) for (int i = 0; i < MAX_SPHERES; i++)
{ {
@ -168,7 +168,7 @@ void GetJointAbsPosition(ITEM_INFO* item, PHD_VECTOR* vec, int joint)
// Use matrices done in the renderer and transform the input vector // Use matrices done in the renderer and transform the input vector
Vector3 p = Vector3(vec->x, vec->y, vec->z); Vector3 p = Vector3(vec->x, vec->y, vec->z);
g_Renderer.GetItemAbsBonePosition(itemNumber, &p, joint); g_Renderer.getItemAbsBonePosition(itemNumber, &p, joint);
// Store the result // Store the result
vec->x = p.x; vec->x = p.x;

View file

@ -165,7 +165,7 @@ void InitialiseSpotCam(short Sequence)
if ((s->flags & SCF_DISABLE_LARA_CONTROLS)) if ((s->flags & SCF_DISABLE_LARA_CONTROLS))
{ {
DisableLaraControl = 1; DisableLaraControl = 1;
g_Renderer.EnableCinematicBars(true); g_Renderer.enableCinematicBars(true);
//SetFadeClip(16, 1); //SetFadeClip(16, 1);
} }
@ -659,7 +659,7 @@ void CalculateSpotCameras()
{ {
//SetFadeClip(16, 1); //SetFadeClip(16, 1);
if (CurrentLevel) if (CurrentLevel)
g_Renderer.EnableCinematicBars(true); g_Renderer.enableCinematicBars(true);
DisableLaraControl = true; DisableLaraControl = true;
} }
@ -760,7 +760,7 @@ void CalculateSpotCameras()
} }
//SetFadeClip(0, 1); //SetFadeClip(0, 1);
g_Renderer.EnableCinematicBars(false); g_Renderer.enableCinematicBars(false);
UseSpotCam = 0; UseSpotCam = 0;
DisableLaraControl = 0; DisableLaraControl = 0;
@ -870,7 +870,7 @@ void CalculateSpotCameras()
} }
else else
{ {
g_Renderer.EnableCinematicBars(false); g_Renderer.enableCinematicBars(false);
UseSpotCam = false; UseSpotCam = false;
DisableLaraControl = false; DisableLaraControl = false;
Camera.speed = 1; Camera.speed = 1;

View file

@ -4,6 +4,6 @@
#include "Renderer11.h" #include "Renderer11.h"
namespace T5M::Renderer { namespace T5M::Renderer {
void PrintString(int x, int y, int unk1, char* string, int unk2) { void PrintString(int x, int y, int unk1, char* string, int unk2) {
g_Renderer.PrintString(x, y, string, D3DCOLOR_RGBA(0xFF, 0xFF, 0xFF, 255), 0); g_Renderer.drawString(x, y, string, D3DCOLOR_RGBA(0xFF, 0xFF, 0xFF, 255), 0);
} }
} }

View file

@ -11,6 +11,13 @@
#include "GameFlowScript.h" #include "GameFlowScript.h"
#include "smoke.h" #include "smoke.h"
#include "drip.h" #include "drip.h"
#include <effects.h>
#include "Renderer11.h"
#include <effects.h>
#include <draw.h>
using std::vector;
using T5M::Renderer::g_Renderer;
char FlareTable[121] = char FlareTable[121] =
{ {
@ -1205,151 +1212,110 @@ int ExplodingDeath(short itemNumber, int meshBits, short flags)
TO_RAD(item->pos.zRot) TO_RAD(item->pos.zRot)
); );
// PHD_MATH: int bit = 1;
/*phd_PushUnitMatrix();
MatrixPtr[M03] = 0; if ((bit & meshBits) && (bit & item->meshBits))
MatrixPtr[M13] = 0;
MatrixPtr[M23] = 0;
phd_RotYXZ(item->pos.yRot, item->pos.xRot, item->pos.zRot);
phd_TranslateRel(frame[6], frame[7], frame[8]);
short* rotation = &frame[9];
gar_RotYXZsuperpack(&rotation, 0);
short* extraRotation = (short*)item->data;
int* bone = &Bones[obj->boneIndex];
int bits = 1;
if (meshBits & 1 && item->meshBits & 1)
{ {
if (flags & 0x100 || !(GetRandomControl() & 3)) if ((GetRandomControl() & 3) == 0)
{ {
Matrix boneMatrix = g_Renderer->GetBoneMatrix(item, 0); short fxNumber = CreateNewEffect(item->roomNumber);
int fxNumber = CreateNewEffect(item->roomNumber);
if (fxNumber != NO_ITEM) if (fxNumber != NO_ITEM)
{ {
FX_INFO* fx = &Effects[fxNumber]; FX_INFO* fx = &EffectList[fxNumber];
fx->pos.xPos = item->pos.xPos + boneMatrix.Translation().x; // (MatrixPtr[M03] >> W2V_SHIFT);
fx->pos.yPos = item->pos.yPos + boneMatrix.Translation().y; // (MatrixPtr[M13] >> W2V_SHIFT);
fx->pos.zPos = item->pos.zPos + boneMatrix.Translation().z; // (MatrixPtr[M23] >> W2V_SHIFT);
fx->roomNumber = item->roomNumber;
fx->pos.yRot = 0;
fx->pos.zRot = 0;
fx->pos.xRot = 0;
if (flags & 0x10) Matrix boneMatrix;
{ g_Renderer.getBoneMatrix(itemNumber, 0, &boneMatrix);
fx->speed = 0; boneMatrix = world * boneMatrix;
}
else fx->pos.xPos = boneMatrix.Translation().x + item->pos.xPos;
fx->pos.yPos = boneMatrix.Translation().y + item->pos.yPos;
fx->pos.zPos = boneMatrix.Translation().z + item->pos.zPos;
fx->roomNumber = item->roomNumber;
fx->pos.xRot = 0;
fx->pos.yRot = GetRandomControl() * 2;
if (!(flags & 0x10))
{ {
if (flags & 0x20) if (flags & 0x20)
fx->speed = GetRandomControl() >> 12; fx->speed = GetRandomControl() >> 12;
else else
fx->speed = GetRandomControl() >> 8; fx->speed = GetRandomControl() >> 8;
} }
if (flags & 0x40) if (flags & 0x40)
{
fx->fallspeed = 0; fx->fallspeed = 0;
}
else else
{ {
if ((flags & 0x80u) == 0) if ((flags & 0x80) == 0)
fx->fallspeed = -(GetRandomControl() >> 8); fx->fallspeed = -(GetRandomControl() >> 8);
else else
fx->fallspeed = -(GetRandomControl() >> 12); fx->fallspeed = -(GetRandomControl() >> 12);
} }
fx->frameNumber = obj->meshIndex;
fx->objectNumber = ID_BODY_PART; fx->objectNumber = ID_BODY_PART;
fx->frameNumber = obj->meshIndex;
fx->shade = 16912; fx->shade = 16912;
fx->flag2 = damage; fx->flag2 = flags;
}
if (item->objectNumber == ID_CRUMBLING_FLOOR) item->meshBits -= bit;
}
}
for (int i = 1; i < obj->nmeshes; i++)
{ {
fx->speed = 0; Matrix boneMatrix;
fx->fallspeed = 0; g_Renderer.getBoneMatrix(itemNumber, i, &boneMatrix);
fx->counter = 61; boneMatrix = world * boneMatrix;
}
else bit <<= 1;
if ((bit & meshBits) && (bit & item->meshBits))
{ {
fx->counter = 0; if ((GetRandomControl() & 3) == 0 && (flags & 0x100))
}
fx->flag1 = 0;
}
item->meshBits--;
}
}
for (int i = 1; i < obj->nmeshes; i++, bone += 3)
{ {
bits <<= 1; short fxNumber = CreateNewEffect(item->roomNumber);
if (bits & meshBits && bits & item->meshBits && (damage & 0x100 || !(GetRandomControl() & 3)))
{
Matrix boneMatrix = g_Renderer->GetBoneMatrix(item, i);
Matrix matrix = boneMatrix * world;
int fxNumber = CreateNewEffect(item->roomNumber);
if (fxNumber != NO_ITEM) if (fxNumber != NO_ITEM)
{ {
FX_INFO* fx = &Effects[fxNumber]; FX_INFO* fx = &EffectList[fxNumber];
fx->pos.xPos = item->pos.xPos + matrix.Translation().x; // (MatrixPtr[3] >> 14);
fx->pos.yPos = item->pos.yPos + matrix.Translation().y; // (MatrixPtr[7] >> 14); fx->pos.xPos = boneMatrix.Translation().x + item->pos.xPos;
fx->pos.zPos = item->pos.zPos + matrix.Translation().z; // (MatrixPtr[11] >> 14); fx->pos.yPos = boneMatrix.Translation().y + item->pos.yPos;
fx->pos.zPos = boneMatrix.Translation().z + item->pos.zPos;
fx->roomNumber = item->roomNumber; fx->roomNumber = item->roomNumber;
fx->pos.yRot = 0;
fx->pos.zRot = 0;
fx->pos.xRot = 0; fx->pos.xRot = 0;
if (damage & 0x10) fx->pos.yRot = GetRandomControl() * 2;
if (!(flags & 0x10))
{ {
fx->speed = 0; if (flags & 0x20)
}
else
{
if (damage & 0x20)
fx->speed = GetRandomControl() >> 12; fx->speed = GetRandomControl() >> 12;
else else
fx->speed = GetRandomControl() >> 8; fx->speed = GetRandomControl() >> 8;
} }
if (damage & 0x40)
{ if (flags & 0x40)
fx->fallspeed = 0; fx->fallspeed = 0;
}
else else
{ {
if ((damage & 0x80u) == 0) if ((flags & 0x80) == 0)
fx->fallspeed = -(GetRandomControl() >> 8); fx->fallspeed = -(GetRandomControl() >> 8);
else else
fx->fallspeed = -(GetRandomControl() >> 12); fx->fallspeed = -(GetRandomControl() >> 12);
} }
fx->objectNumber = ID_BODY_PART; fx->objectNumber = ID_BODY_PART;
fx->shade = 16912; fx->shade = 16912;
fx->flag2 = damage; fx->flag2 = flags;
fx->frameNumber = obj->meshIndex + 2 * i; fx->frameNumber = obj->meshIndex + i;
if (item->objectNumber == ID_CRUMBLING_FLOOR)
{
fx->speed = 0;
fx->fallspeed = 0;
fx->counter = 61;
}
else
{
fx->counter = 0;
}
fx->flag1 = 0;
} }
item->meshBits -= bits; item->meshBits -= bit;
}
}
} }
}*/
return (item->meshBits == 0); return item->meshBits == 0;
} }
int GetFreeShockwave()// (F) int GetFreeShockwave()// (F)
@ -1617,9 +1583,9 @@ void TriggerExplosionBubble(int x, int y, int z, short roomNum)// (F)
{ {
GAME_VECTOR pos; GAME_VECTOR pos;
pos.x = item->pos.x_pos; pos.x = item->pos.xPos;
pos.y = item->pos.y_pos; pos.y = item->pos.yPos;
pos.z = item->pos.z_pos; pos.z = item->pos.zPos;
pos.roomNumber = item->roomNumber; pos.roomNumber = item->roomNumber;
SetUpLensFlare(0, 0, 0, &pos); SetUpLensFlare(0, 0, 0, &pos);

View file

@ -1325,7 +1325,7 @@ float TO_RAD(short angle)
const float frand() const float frand()
{ {
float result = float((float)rand() / RAND_MAX); float result = float(static_cast<float>(rand()) / RAND_MAX);
return result; return result;
} }
@ -1339,6 +1339,24 @@ const float lerp(float v0, float v1, float t)
return (1 - t) * v0 + t * v1; return (1 - t) * v0 + t * v1;
} }
const Vector3 getRandomVector()
{
Vector3 v = {frandMinMax(-1,1),frandMinMax(-1,1),frandMinMax(-1,1)};
v.Normalize();
return v;
}
const Vector3 getRandomVectorInCone(const Vector3& direction, const float angleDegrees)
{
float x = frandMinMax(-angleDegrees, angleDegrees) * RADIAN;
float y = frandMinMax(-angleDegrees, angleDegrees) * RADIAN;
float z = frandMinMax(-angleDegrees, angleDegrees) * RADIAN;
Matrix m = Matrix::CreateRotationX(x)* Matrix::CreateRotationY(y) * Matrix::CreateRotationZ(z);
Vector3 result = direction.TransformNormal(direction, m);
result.Normalize();
return result;
}
// FIXME: game code still expects << 2 >> W2V_SHIFT so we multiply by 16384.0f // FIXME: game code still expects << 2 >> W2V_SHIFT so we multiply by 16384.0f
int phd_sin(short a) int phd_sin(short a)
{ {

View file

@ -14,14 +14,24 @@ constexpr auto WALL_SIZE = 1024;
constexpr auto STEPUP_HEIGHT = ((STEP_SIZE * 3) / 2); constexpr auto STEPUP_HEIGHT = ((STEP_SIZE * 3) / 2);
constexpr auto BAD_JUMP_CEILING = ((STEP_SIZE * 3) / 4); constexpr auto BAD_JUMP_CEILING = ((STEP_SIZE * 3) / 4);
#define SQUARE(x) ((x)*(x)) template<typename T>
#define CLAMP(x, a, b) ((x)<(a)?(a):((x)>(b)?(b):(x))) constexpr auto SQUARE(T x) { return ((x)*(x)); }
#define SIGN(x) ((0 < (x)) - ((x) < 0)) template<typename T1, typename T2, typename T3>
#define CLAMPADD(x, a, b) ((x)<(a)?((x)+(a)):((x)>(b)?((x)-(b)):0)) constexpr auto CLAMP(T1 x, T2 a, T3 b) { return ((x)<(a)?(a):((x)>(b)?(b):(x))); }
#define CLICK(x) ((x) * STEP_SIZE) template<typename T>
#define SECTOR(x) ((x) * WALL_SIZE) constexpr auto SIGN(T x) { return ((0 < (x)) - ((x) < 0)); }
#define HIDWORD(l) ((DWORD)(((DWORDLONG)(l)>>32)&0xFFFFFFFF)) template<typename T1, typename T2, typename T3>
constexpr auto CLAMPADD(T1 x, T2 a, T3 b) { return ((x)<(a)?((x)+(a)):((x)>(b)?((x)-(b)):0)); }
template<typename T>
constexpr auto CLICK(T x) { return ((x) * STEP_SIZE); }
template<typename T>
constexpr auto SECTOR(T x) { return ((x) * WALL_SIZE); }
template<typename T>
constexpr auto HIDWORD(T l) { return ((DWORD)(((DWORDLONG)(l)>>32)&0xFFFFFFFF)); }
template<typename T>
constexpr auto MESH_BITS(T x) {
return (1 << x);
}
short ANGLE(float angle); short ANGLE(float angle);
float TO_DEGREES(short angle); float TO_DEGREES(short angle);
float TO_RAD(short angle); float TO_RAD(short angle);
@ -35,6 +45,8 @@ int phd_cos(short a);
const float frand(); const float frand();
const float frandMinMax(float min, float max); const float frandMinMax(float min, float max);
const float lerp(float v0, float v1, float t); const float lerp(float v0, float v1, float t);
const Vector3 getRandomVector();
const Vector3 getRandomVectorInCone(const Vector3& direction,const float angleDegrees);
int mGetAngle(int x1, int y1, int x2, int y2); int mGetAngle(int x1, int y1, int x2, int y2);
int phd_atan(int dz, int dx); int phd_atan(int dz, int dx);
void phd_GetVectorAngles(int x, int y, int z, short* angles); void phd_GetVectorAngles(int x, int y, int z, short* angles);

View file

@ -179,7 +179,7 @@ static void SkidooExplode(ITEM_INFO* skidoo)
{ {
if (g_Level.Rooms[skidoo->roomNumber].flags & ENV_FLAG_WATER) if (g_Level.Rooms[skidoo->roomNumber].flags & ENV_FLAG_WATER)
{ {
TriggerUnderwaterExplosion(skidoo); TriggerUnderwaterExplosion(skidoo, 1);
} }
else else
{ {

View file

@ -142,7 +142,7 @@ static void QuadbikeExplode(ITEM_INFO* item)
{ {
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER) if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
{ {
TriggerUnderwaterExplosion(item); TriggerUnderwaterExplosion(item, 1);
} }
else else
{ {

View file

@ -9,6 +9,7 @@
#include "effect.h" #include "effect.h"
#include "setup.h" #include "setup.h"
#include "level.h" #include "level.h"
#include <draw.h>
enum BADDY_STATES { enum BADDY_STATES {
STATE_BADDY_STOP = 0, STATE_BADDY_STOP = 0,
@ -157,21 +158,6 @@ enum BADDY_SWAP_MESH_FLAGS {
BITE_INFO baddyGun = { 0, -16, 200, 11 }; BITE_INFO baddyGun = { 0, -16, 200, 11 };
BITE_INFO baddySword = { 0, 0, 0, 15 }; BITE_INFO baddySword = { 0, 0, 0, 15 };
void ClampRotation(PHD_3DPOS *pos, short angle, short rot)
{
if (angle <= rot)
{
if (angle >= -rot)
pos->yRot += angle;
else
pos->yRot -= rot;
}
else
{
pos->yRot += rot;
}
}
void InitialiseBaddy(short itemNum) void InitialiseBaddy(short itemNum)
{ {
ITEM_INFO* item = &g_Level.Items[itemNum]; ITEM_INFO* item = &g_Level.Items[itemNum];

View file

@ -0,0 +1,402 @@
#include <tr4_enemy_jeep.h>
#include <framework.h>
#include <items.h>
#include <level.h>
#include <Box.h>
#include <trmath.h>
#include <control.h>
#include <lara.h>
#include <sphere.h>
#include <effect2.h>
#include <lot.h>
#include <tomb4fx.h>
#include <sound.h>
#include <draw.h>
void EnemyJeepLaunchGrenade(ITEM_INFO* item)
{
short grenadeItemNumber = CreateItem();
if (grenadeItemNumber != NO_ITEM)
{
ITEM_INFO* grenadeItem = &g_Level.Items[grenadeItemNumber];
grenadeItem->shade = -15856;
grenadeItem->objectNumber = ID_GRENADE;
grenadeItem->roomNumber = item->roomNumber;
InitialiseItem(grenadeItemNumber);
grenadeItem->pos.xRot = item->pos.xRot;
grenadeItem->pos.yRot = item->pos.yRot + -ANGLE(180);
grenadeItem->pos.zRot = 0;
grenadeItem->pos.xPos = item->pos.xPos + (1024 * phd_sin(grenadeItem->pos.yRot) >> W2V_SHIFT);
grenadeItem->pos.yPos = item->pos.yPos - 768;
grenadeItem->pos.zPos = item->pos.xPos + (1024 * phd_cos(grenadeItem->pos.yRot) >> W2V_SHIFT);
SmokeCountL = 32;
SmokeWeapon = 5;
for (int i = 0; i < 5; i++)
{
TriggerGunSmoke(item->pos.xPos, item->pos.yPos, item->pos.zPos, 0, 0, 0, 1, 5, 32);
}
if (GetRandomControl() & 3)
{
grenadeItem->itemFlags[0] = 1;
}
else
{
grenadeItem->itemFlags[0] = 2;
}
grenadeItem->speed = 32;
grenadeItem->currentAnimState = grenadeItem->pos.xRot;
grenadeItem->fallspeed = -32 * phd_sin(grenadeItem->pos.xRot) >> W2V_SHIFT;
grenadeItem->goalAnimState = grenadeItem->pos.yRot;
grenadeItem->requiredAnimState = 0;
grenadeItem->hitPoints = 120;
AddActiveItem(grenadeItemNumber);
}
}
void InitialiseEnemyJeep(short itemNumber)
{
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->itemFlags[0] = -80;
if (g_Level.NumItems > 0)
{
for (int i = 0; i < g_Level.NumItems; i++)
{
ITEM_INFO* other = &g_Level.Items[i];
if (other == item || other->triggerFlags != item->triggerFlags)
continue;
item->itemFlags[1] = i;
other->itemFlags[0] = -80;
other->pos.yPos = item->pos.yPos - 1024;
}
}
}
void EnemyJeepControl(short itemNumber)
{
if (CreatureActive(itemNumber))
{
ITEM_INFO* item = &g_Level.Items[itemNumber];
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
int x = item->pos.xPos;
int y = item->pos.yPos;
int z = item->pos.zPos;
int dx = 682 * phd_sin(item->pos.yRot) >> W2V_SHIFT;
int dz = 682 * phd_cos(item->pos.yRot) >> W2V_SHIFT;
short roomNumber = item->roomNumber;
FLOOR_INFO* floor = GetFloor(x - dz, y, z - dx, &roomNumber);
int height1 = GetFloorHeight(floor, x - dz, y, z - dx);
if (abs(item->pos.yPos - height1) > 768)
{
item->pos.yRot += ANGLE(2);
item->pos.xPos += (dz / 64);
item->pos.zPos += (dx / 64);
height1 = y;
}
roomNumber = item->roomNumber;
floor = GetFloor(x + dz, y, z - dx, &roomNumber);
int height2 = GetFloorHeight(floor, x + dz, y, z - dx);
if (abs(item->pos.yPos - height2) > 768)
{
item->pos.yRot -= ANGLE(2);
item->pos.xPos -= (dz / 64);
item->pos.zPos += (dx / 64);
height2 = y;
}
short zRot = phd_atan(1364, height2 - height1);
roomNumber = item->roomNumber;
floor = GetFloor(x + dx, y, z + dz, &roomNumber);
int height3 = GetFloorHeight(floor, x + dx, y, z + dz);
if (abs(y - height3) > 768)
{
height3 = y;
}
roomNumber = item->roomNumber;
floor = GetFloor(x - dx, y, z - dz, &roomNumber);
int height4 = GetFloorHeight(floor, x - dx, y, z - dz);
if (abs(y - height4) > 768)
{
height4 = y;
}
short xRot = phd_atan(1364, height4 - height3);
AI_INFO info;
CreatureAIInfo(item, &info);
ITEM_INFO* target = &creature->aiTarget;
creature->enemy = target;
short angle;
int distance;
if (target == LaraItem)
{
angle = info.angle;
distance = info.distance;
}
else
{
dx = LaraItem->pos.xPos - item->pos.xPos;
dz = LaraItem->pos.zPos - item->pos.zPos;
angle = phd_atan(dz, dx) - item->pos.yRot;
if (dx > 32000 || dx < -32000 || dz > 32000 || dz < -32000)
distance = 0x7FFFFFFF;
else
distance = SQUARE(dx) + SQUARE(dz);
}
PHD_VECTOR pos;
switch (item->currentAnimState)
{
case 0:
case 2:
item->itemFlags[0] -= 128;
if (item->itemFlags[0] < 0)
item->itemFlags[0] = 0;
item->meshBits = -98305;
pos.x = 0;
pos.y = -144;
pos.z = -1024;
GetJointAbsPosition(item, &pos, 11);
TriggerDynamicLight(pos.x, pos.y, pos.z, 10, 64, 0, 0);
if (item->requiredAnimState)
item->goalAnimState = item->requiredAnimState;
else if (info.distance > SQUARE(1024) || Lara.location >= item->itemFlags[3])
item->goalAnimState = 1;
break;
case 1:
creature->maximumTurn = item->itemFlags[0] / 16;
item->itemFlags[0] += 37;
if (item->itemFlags[0] > 8704)
item->itemFlags[0] = 8704;
item->meshBits = -147457;
if (info.angle <= 256)
{
if (info.angle < -256)
{
item->goalAnimState = 3;
}
}
else
{
item->goalAnimState = 4;
}
break;
case 3:
case 4:
item->itemFlags[0] += 18;
if (item->itemFlags[0] > 8704)
item->itemFlags[0] = 8704;
item->goalAnimState = 1;
break;
case 5:
if (item->itemFlags[0] < 1184)
item->itemFlags[0] = 1184;
break;
default:
break;
}
if (height3 <= item->floor + 512)
{
if (height4 > item->floor + 512 && item->currentAnimState != 5)
{
item->itemFlags[1] = 0;
item->animNumber = Objects[item->objectNumber].animIndex + 8;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = 5;
item->goalAnimState = 1;
}
}
else
{
creature->LOT.requiredBox |= 8;
if (item->itemFlags[1] > 0)
{
item->itemFlags[1] -= 8;
if (item->itemFlags[1]<0)
creature->LOT.requiredBox &= ~8;
item->pos.yPos += item->itemFlags[1] / 64;
}
else
{
item->itemFlags[1] = 2 * xRot;
creature->LOT.requiredBox |= 8u;
}
if (creature->LOT.requiredBox & 8)
{
creature->maximumTurn = 0;
item->goalAnimState = 1;
}
}
if (info.distance < SQUARE(1536) || item->itemFlags[3] == -2)
creature->reachedGoal = true;
if (creature->reachedGoal)
{
GetFloorAndTestTriggers(target->pos.xPos, target->pos.yPos, target->pos.zPos, target->roomNumber, 1, 0);
if (Lara.location < item->itemFlags[3] && item->currentAnimState != 2 && item->goalAnimState != 2)
{
item->animNumber = Objects[item->objectNumber].animIndex + 1;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = 2;
item->currentAnimState = 2;
if (target->flags & 4)
{
item->pos.xPos = target->pos.xPos;
item->pos.yPos = target->pos.yPos;
item->pos.zPos = target->pos.zPos;
item->pos.xRot = target->pos.xRot;
item->pos.yRot = target->pos.yRot;
item->pos.zRot = target->pos.zRot;
if (item->roomNumber != target->roomNumber)
ItemNewRoom(itemNumber, target->roomNumber);
}
}
if (distance > SQUARE(2048) && distance < SQUARE(10240) && !item->itemFlags[2] && (angle < -20480 || angle > 20480))
{
EnemyJeepLaunchGrenade(item);
item->itemFlags[2] = 150;
}
if (target->flags == 62)
{
item->status = ITEM_INVISIBLE;
RemoveActiveItem(itemNumber);
DisableBaddieAI(itemNumber);
}
if (Lara.location >= item->itemFlags[3] || !(target->flags & 4))
{
creature->reachedGoal = false;
item->itemFlags[3]++;
creature->enemy = NULL;
AIOBJECT* aiObject = NULL;
for (int i = 0; i < g_Level.AIObjects.size(); i++)
{
aiObject = &g_Level.AIObjects[i];
if (g_Level.AIObjects[i].triggerFlags == item->itemFlags[3] && g_Level.AIObjects[i].roomNumber != NO_ROOM)
{
aiObject = &g_Level.AIObjects[i];
break;
}
}
if (aiObject != NULL)
{
creature->enemy = target;
target->objectNumber = aiObject->objectNumber;
target->roomNumber = aiObject->roomNumber;
target->pos.xPos = aiObject->x;
target->pos.yPos = aiObject->y;
target->pos.zPos = aiObject->z;
target->pos.yRot = aiObject->yRot;
target->flags = aiObject->flags;
target->triggerFlags = aiObject->triggerFlags;
target->boxNumber = aiObject->boxNumber;
if (!(aiObject->flags & 0x20))
{
target->pos.xPos += 256 * phd_sin(target->pos.yRot) >> W2V_SHIFT;
target->pos.zPos += 256 * phd_cos(target->pos.yRot) >> W2V_SHIFT;
}
}
}
}
item->itemFlags[2]--;
if (item->itemFlags[2] < 0)
item->itemFlags[2] = 0;
if (abs(xRot - item->pos.xRot) < 256)
item->pos.xRot = xRot;
else if (xRot < item->pos.xRot)
item->pos.xRot -= 256;
else
item->pos.xRot += 256;
if (abs(zRot - item->pos.zRot) < 256)
item->pos.zRot = zRot;
else if (zRot < item->pos.zRot)
item->pos.zRot -= 256;
else
item->pos.zRot += 256;
item->itemFlags[0] += -2 - xRot / 512;
if (item->itemFlags[0] < 0)
item->itemFlags[0] = 0;
dx = item->itemFlags[0] * phd_sin(-2 - xRot / 512) >> W2V_SHIFT;
dz = item->itemFlags[0] * phd_cos(-2 - xRot / 512) >> W2V_SHIFT;
item->pos.xPos += dx / 64;
item->pos.zPos += dz / 64;
for (int i = 0; i < 4; i++)
{
creature->jointRotation[i] -= item->itemFlags[0];
}
if (!creature->reachedGoal)
ClampRotation(&item->pos, info.angle, item->itemFlags[0] / 16);
creature->maximumTurn = 0;
AnimateItem(item);
floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
item->floor = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
if (item->roomNumber != roomNumber)
ItemNewRoom(itemNumber, roomNumber);
if (item->pos.yPos < item->floor)
item->gravityStatus = true;
else
{
item->fallspeed = 0;
item->pos.yPos = item->floor;
item->gravityStatus = false;
}
SoundEffect(SFX_TR4_JEEP_MOVE, &item->pos, (item->itemFlags[0] << 10) + 16777220);
}
}

View file

@ -0,0 +1,5 @@
#pragma once
#include <items.h>
void InitialiseEnemyJeep(short itemNumber);
void EnemyJeepControl(short itemNumber);

View file

@ -17,7 +17,7 @@ void InitialiseSphinx(short itemNumber)
ClearItem(itemNumber); ClearItem(itemNumber);
item->animNumber = Objects[item->animNumber].animIndex + 1; item->animNumber = Objects[item->objectNumber].animIndex + 1;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase; item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = 1; item->goalAnimState = 1;
item->currentAnimState = 1; item->currentAnimState = 1;

View file

@ -590,7 +590,7 @@ static void JeepExplode(ITEM_INFO* item)
{ {
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER) if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
{ {
TriggerUnderwaterExplosion(item); TriggerUnderwaterExplosion(item, 1);
} }
else else
{ {

View file

@ -462,7 +462,7 @@ static void MotorBikeExplode(ITEM_INFO* item)
{ {
if (g_Level.Rooms[item->roomNumber].flags & (ENV_FLAG_WATER|ENV_FLAG_SWAMP)) if (g_Level.Rooms[item->roomNumber].flags & (ENV_FLAG_WATER|ENV_FLAG_SWAMP))
{ {
TriggerUnderwaterExplosion(item); TriggerUnderwaterExplosion(item, 1);
} }
else else
{ {

View file

@ -56,6 +56,7 @@
#include "objects.h" #include "objects.h"
#include "setup.h" #include "setup.h"
#include "level.h" #include "level.h"
#include "tr4_enemy_jeep.h"
static void StartBaddy(OBJECT_INFO* obj) static void StartBaddy(OBJECT_INFO* obj)
{ {
@ -645,6 +646,29 @@ static void StartBaddy(OBJECT_INFO* obj)
obj->saveAnim = true; obj->saveAnim = true;
obj->zoneType = ZONE_BASIC; obj->zoneType = ZONE_BASIC;
} }
obj = &Objects[ID_ENEMY_JEEP];
if (obj->loaded)
{
obj->initialise = InitialiseEnemyJeep;
obj->control = EnemyJeepControl;
obj->collision = CreatureCollision;
obj->saveFlags = true;
obj->savePosition = true;
obj->saveAnim = true;
obj->intelligent = true;
obj->saveHitpoints = true;
obj->pivotLength = 500;
obj->shadowSize = 128;
obj->radius = 512;
obj->hitPoints = 40;
obj->zoneType = ZONE_BASIC;
g_Level.Bones[obj->boneIndex + 4 * 8] |= ROT_X;
g_Level.Bones[obj->boneIndex + 4 * 9] |= ROT_X;
g_Level.Bones[obj->boneIndex + 4 * 11] |= ROT_X;
g_Level.Bones[obj->boneIndex + 4 * 12] |= ROT_X;
}
} }
static void StartObject(OBJECT_INFO* obj) static void StartObject(OBJECT_INFO* obj)

View file

@ -586,7 +586,7 @@ void TorpedoControl(short itemNumber)
{ {
LaraItem->hitStatus = true; LaraItem->hitStatus = true;
KillItem(itemNumber); KillItem(itemNumber);
TriggerUnderwaterExplosion(item); TriggerUnderwaterExplosion(item, 1);
SoundEffect(SFX_UNDERWATER_EXPLOSION, &item->pos, 2); SoundEffect(SFX_UNDERWATER_EXPLOSION, &item->pos, 2);
SoundEffect(SFX_LARA_UNDERWATER_HIT, &LaraItem->pos, 2); SoundEffect(SFX_LARA_UNDERWATER_HIT, &LaraItem->pos, 2);
LaraItem->hitPoints -= 200; LaraItem->hitPoints -= 200;
@ -623,7 +623,7 @@ void TorpedoControl(short itemNumber)
item->pos.xPos = x; item->pos.xPos = x;
item->pos.yPos = y; item->pos.yPos = y;
item->pos.zPos = z; item->pos.zPos = z;
TriggerUnderwaterExplosion(item); TriggerUnderwaterExplosion(item, 1);
SoundEffect(SFX_UNDERWATER_EXPLOSION, &item->pos, 2); SoundEffect(SFX_UNDERWATER_EXPLOSION, &item->pos, 2);
KillItem(itemNumber); KillItem(itemNumber);
} }

View file

@ -1177,6 +1177,7 @@ static void StartProjectiles(OBJECT_INFO *obj)
InitProjectile(obj, MissileControl, ID_IMP_ROCK, true); InitProjectile(obj, MissileControl, ID_IMP_ROCK, true);
InitProjectile(obj, TorpedoControl, ID_TORPEDO); InitProjectile(obj, TorpedoControl, ID_TORPEDO);
InitProjectile(obj, ControlGrenade, ID_GRENADE); InitProjectile(obj, ControlGrenade, ID_GRENADE);
InitProjectile(obj, ControlRocket, ID_ROCKET);
InitProjectile(obj, ControlHarpoonBolt, ID_HARPOON); InitProjectile(obj, ControlHarpoonBolt, ID_HARPOON);
InitProjectile(obj, ControlCrossbowBolt, ID_CROSSBOW_BOLT); InitProjectile(obj, ControlCrossbowBolt, ID_CROSSBOW_BOLT);
} }

View file

@ -0,0 +1,35 @@
#pragma once
#include <d3d11.h>
#include "Utils.h"
#include "debug/debug.h"
namespace T5M::Renderer {
template <typename CBuff>
class ConstantBuffer {
ComPtr<ID3D11Buffer> buffer;
public:
ConstantBuffer() = default;
ConstantBuffer(ID3D11Device* device) {
D3D11_BUFFER_DESC desc = {};
desc.ByteWidth = sizeof(CBuff);
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
Utils::throwIfFailed(device->CreateBuffer(&desc, NULL, buffer.GetAddressOf()));
buffer->SetPrivateData(WKPDID_D3DDebugObjectName, 32, typeid(CBuff).name());
}
ID3D11Buffer** get() {
return buffer.GetAddressOf();
}
void updateData(CBuff& data,ID3D11DeviceContext* ctx) {
D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT res = ctx->Map(buffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (SUCCEEDED(res)) {
void* dataPtr = (mappedResource.pData);
memcpy(dataPtr, &data, sizeof(CBuff));
ctx->Unmap(buffer.Get(), 0);
} else
logD("Could not update constant buffer ", this);
}
};
}

View file

@ -32,8 +32,8 @@ namespace T5M::Renderer
z >= r->z && z <= r->z + r->ySize * 1024.0f); z >= r->z && z <= r->z + r->ySize * 1024.0f);
} }
vector<RendererVideoAdapter> *Renderer11::GetAdapters() std::vector<T5M::Renderer::RendererVideoAdapter>* Renderer11::getAdapters()
{ {
return &m_adapters; return &m_adapters;
} }
@ -247,7 +247,7 @@ namespace T5M::Renderer
return GetFrame_D2(&item, framePtr, rate); return GetFrame_D2(&item, framePtr, rate);
} }
void Renderer11::UpdateItemAnimations(int itemNumber, bool force) void Renderer11::updateItemAnimations(int itemNumber, bool force)
{ {
RendererItem *itemToDraw = &m_items[itemNumber]; RendererItem *itemToDraw = &m_items[itemNumber];
itemToDraw->Id = itemNumber; itemToDraw->Id = itemNumber;
@ -327,7 +327,7 @@ namespace T5M::Renderer
if (item->objectNumber == ID_LARA) if (item->objectNumber == ID_LARA)
continue; continue;
UpdateItemAnimations(itemToDraw->Id, false); updateItemAnimations(itemToDraw->Id, false);
} }
} }
@ -410,9 +410,9 @@ namespace T5M::Renderer
if (meshPtr->positions.size() == 0) if (meshPtr->positions.size() == 0)
return mesh; return mesh;
mesh->Positions.reserve(meshPtr->positions.size()); mesh->Positions.resize(meshPtr->positions.size());
for (int i = 0; i < meshPtr->positions.size(); i++) for (int i = 0; i < meshPtr->positions.size(); i++)
mesh->Positions.push_back(meshPtr->positions[i]); mesh->Positions[i] = meshPtr->positions[i];
for (int n = 0; n < meshPtr->buckets.size(); n++) for (int n = 0; n < meshPtr->buckets.size(); n++)
{ {
@ -427,14 +427,17 @@ namespace T5M::Renderer
bucket = &mesh->Buckets[bucketIndex]; bucket = &mesh->Buckets[bucketIndex];
bucket->Vertices.reserve(levelBucket->numQuads * 4 + levelBucket->numTriangles * 3); bucket->Vertices.resize(levelBucket->numQuads * 4 + levelBucket->numTriangles * 3);
bucket->Indices.reserve(levelBucket->numQuads * 6 + levelBucket->numTriangles * 3); bucket->Indices.resize(levelBucket->numQuads * 6 + levelBucket->numTriangles * 3);
int lastVertex = 0;
int lastIndex = 0;
for (int p = 0; p < levelBucket->polygons.size(); p++) for (int p = 0; p < levelBucket->polygons.size(); p++)
{ {
POLYGON* poly = &levelBucket->polygons[p]; POLYGON* poly = &levelBucket->polygons[p];
int baseVertices = bucket->Vertices.size(); int baseVertices = lastVertex; // bucket->Vertices.size();
for (int k = 0; k < poly->indices.size(); k++) for (int k = 0; k < poly->indices.size(); k++)
{ {
@ -463,23 +466,34 @@ namespace T5M::Renderer
/*if (isHairs) /*if (isHairs)
vertex.Bone = v;*/ vertex.Bone = v;*/
bucket->Vertices.push_back(vertex); bucket->Vertices[lastVertex++] = vertex;
} }
if (poly->shape == 0) if (poly->shape == 0)
{ {
bucket->Indices.push_back(baseVertices); bucket->Indices[lastIndex++] = baseVertices;
bucket->Indices[lastIndex++] = baseVertices + 1;
bucket->Indices[lastIndex++] = baseVertices + 3;
bucket->Indices[lastIndex++] = baseVertices + 2;
bucket->Indices[lastIndex++] = baseVertices + 3;
bucket->Indices[lastIndex++] = baseVertices + 1;
/*bucket->Indices.push_back(baseVertices);
bucket->Indices.push_back(baseVertices + 1); bucket->Indices.push_back(baseVertices + 1);
bucket->Indices.push_back(baseVertices + 3); bucket->Indices.push_back(baseVertices + 3);
bucket->Indices.push_back(baseVertices + 2); bucket->Indices.push_back(baseVertices + 2);
bucket->Indices.push_back(baseVertices + 3); bucket->Indices.push_back(baseVertices + 3);
bucket->Indices.push_back(baseVertices + 1); bucket->Indices.push_back(baseVertices + 1);*/
} }
else else
{ {
bucket->Indices.push_back(baseVertices); bucket->Indices[lastIndex++] = baseVertices;
bucket->Indices[lastIndex++] = baseVertices + 1;
bucket->Indices[lastIndex++] = baseVertices + 2;
/*bucket->Indices.push_back(baseVertices);
bucket->Indices.push_back(baseVertices + 1); bucket->Indices.push_back(baseVertices + 1);
bucket->Indices.push_back(baseVertices + 2); bucket->Indices.push_back(baseVertices + 2);*/
} }
} }
} }
@ -503,11 +517,11 @@ namespace T5M::Renderer
return -1; return -1;
} }
bool Renderer11::IsFullsScreen() bool Renderer11::isFullsScreen()
{ {
return (!Windowed); return (!Windowed);
} }
bool Renderer11::IsFading() bool Renderer11::isFading()
{ {
return false; return false;
return (m_fadeStatus != FADEMODE_NONE); return (m_fadeStatus != FADEMODE_NONE);
@ -518,14 +532,12 @@ namespace T5M::Renderer
gameCamera = RenderView(cam, roll, fov, 32, 102400, g_Configuration.Width, g_Configuration.Height); gameCamera = RenderView(cam, roll, fov, 32, 102400, g_Configuration.Width, g_Configuration.Height);
} }
bool Renderer11::EnumerateVideoModes() void Renderer11::EnumerateVideoModes()
{ {
HRESULT res; HRESULT res;
IDXGIFactory *dxgiFactory = NULL; IDXGIFactory *dxgiFactory = NULL;
res = CreateDXGIFactory(__uuidof(IDXGIFactory), (void **)&dxgiFactory); Utils::throwIfFailed(CreateDXGIFactory(__uuidof(IDXGIFactory), (void **)&dxgiFactory));
if (FAILED(res))
return false;
IDXGIAdapter *dxgiAdapter = NULL; IDXGIAdapter *dxgiAdapter = NULL;
@ -542,32 +554,22 @@ namespace T5M::Renderer
adapter.Index = i; adapter.Index = i;
adapter.Name = videoCardDescription; adapter.Name = videoCardDescription;
logD("Adapter %d", i);
printf("Adapter %d\n", i); logD("Device Name : ", videoCardDescription);
printf("\t Device Name: %s\n", videoCardDescription); ComPtr<IDXGIOutput> output;
if(FAILED(dxgiAdapter->EnumOutputs(0, output.GetAddressOf())))
IDXGIOutput *output = NULL; continue;
res = dxgiAdapter->EnumOutputs(0, &output);
if (FAILED(res))
return false;
UINT numModes = 0; UINT numModes = 0;
DXGI_MODE_DESC *displayModes = NULL; std::vector<DXGI_MODE_DESC> displayModes;
DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
// Get the number of elements // Get the number of elements
res = output->GetDisplayModeList(format, 0, &numModes, NULL); Utils::throwIfFailed(output->GetDisplayModeList(format, 0, &numModes, NULL));
if (FAILED(res))
return false;
// Get the list // Get the list
displayModes = new DXGI_MODE_DESC[numModes]; displayModes.resize(numModes);
res = output->GetDisplayModeList(format, 0, &numModes, displayModes); Utils::throwIfFailed(output->GetDisplayModeList(format, 0, &numModes, displayModes.data()));
if (FAILED(res))
{
delete displayModes;
return false;
}
for (int j = 0; j < numModes; j++) for (int j = 0; j < numModes; j++)
{ {
@ -598,17 +600,14 @@ namespace T5M::Renderer
continue; continue;
adapter.DisplayModes.push_back(newMode); adapter.DisplayModes.push_back(newMode);
printf("\t\t %d x %d %d Hz\n", newMode.Width, newMode.Height, newMode.RefreshRate); logD("W: ", newMode.Width,"H: ", newMode.Height," ", newMode.RefreshRate, "Hz");
} }
m_adapters.push_back(adapter); m_adapters.push_back(adapter);
delete displayModes;
} }
dxgiFactory->Release(); dxgiFactory->Release();
return true;
} }
int SortLightsFunction(RendererLight *a, RendererLight *b) int SortLightsFunction(RendererLight *a, RendererLight *b)
@ -794,9 +793,9 @@ namespace T5M::Renderer
return box.Intersects(sphere); return box.Intersects(sphere);
} }
void Renderer11::GetLaraBonePosition(Vector3 *pos, int bone) {} void Renderer11::getLaraBonePosition(Vector3 *pos, int bone) {}
void Renderer11::FlipRooms(short roomNumber1, short roomNumber2) void Renderer11::flipRooms(short roomNumber1, short roomNumber2)
{ {
RendererRoom temporary; RendererRoom temporary;
@ -812,14 +811,14 @@ namespace T5M::Renderer
return m_meshes[meshIndex]; return m_meshes[meshIndex];
} }
void Renderer11::GetLaraAbsBonePosition(Vector3 *pos, int joint) void Renderer11::getLaraAbsBonePosition(Vector3 *pos, int joint)
{ {
Matrix world = m_moveableObjects[ID_LARA]->AnimationTransforms[joint]; Matrix world = m_moveableObjects[ID_LARA]->AnimationTransforms[joint];
world = world * m_LaraWorldMatrix; world = world * m_LaraWorldMatrix;
*pos = Vector3::Transform(*pos, world); *pos = Vector3::Transform(*pos, world);
} }
void Renderer11::GetItemAbsBonePosition(int itemNumber, Vector3 *pos, int joint) void Renderer11::getItemAbsBonePosition(int itemNumber, Vector3 *pos, int joint)
{ {
RendererItem *rendererItem = &m_items[itemNumber]; RendererItem *rendererItem = &m_items[itemNumber];
rendererItem->Id = itemNumber; rendererItem->Id = itemNumber;
@ -832,16 +831,16 @@ namespace T5M::Renderer
if (!rendererItem->DoneAnimations) if (!rendererItem->DoneAnimations)
{ {
if (itemNumber == Lara.itemNumber) if (itemNumber == Lara.itemNumber)
UpdateLaraAnimations(false); updateLaraAnimations(false);
else else
UpdateItemAnimations(itemNumber, false); updateItemAnimations(itemNumber, false);
} }
Matrix world = rendererItem->AnimationTransforms[joint] * rendererItem->World; Matrix world = rendererItem->AnimationTransforms[joint] * rendererItem->World;
*pos = Vector3::Transform(*pos, world); *pos = Vector3::Transform(*pos, world);
} }
int Renderer11::GetSpheres(short itemNumber, BoundingSphere *spheres, char worldSpace, Matrix local) int Renderer11::getSpheres(short itemNumber, BoundingSphere *spheres, char worldSpace, Matrix local)
{ {
RendererItem *rendererItem = &m_items[itemNumber]; RendererItem *rendererItem = &m_items[itemNumber];
rendererItem->Id = itemNumber; rendererItem->Id = itemNumber;
@ -854,9 +853,9 @@ namespace T5M::Renderer
if (!rendererItem->DoneAnimations) if (!rendererItem->DoneAnimations)
{ {
if (itemNumber == Lara.itemNumber) if (itemNumber == Lara.itemNumber)
UpdateLaraAnimations(false); updateLaraAnimations(false);
else else
UpdateItemAnimations(itemNumber, false); updateItemAnimations(itemNumber, false);
} }
int x, y, z; int x, y, z;
@ -898,9 +897,19 @@ namespace T5M::Renderer
return moveable.ObjectMeshes.size(); return moveable.ObjectMeshes.size();
} }
void Renderer11::GetBoneMatrix(short itemNumber, int joint, Matrix *outMatrix) void Renderer11::getBoneMatrix(short itemNumber, int joint, Matrix *outMatrix)
{ {
RendererObject &obj = *m_moveableObjects[ID_LARA]; if (itemNumber == Lara.itemNumber)
{
RendererObject& obj = *m_moveableObjects[ID_LARA];
*outMatrix = obj.AnimationTransforms[joint] * m_LaraWorldMatrix; *outMatrix = obj.AnimationTransforms[joint] * m_LaraWorldMatrix;
} }
else
{
updateItemAnimations(itemNumber, true);
RendererItem& item = m_items[itemNumber];
RendererObject& obj = *m_moveableObjects[item.Item->objectNumber];
*outMatrix = obj.AnimationTransforms[joint] * item.World;
}
}
} // namespace T5M::Renderer } // namespace T5M::Renderer

View file

@ -93,7 +93,6 @@ typedef enum RENDERER_FADE_STATUS
constexpr auto TEXTURE_HEIGHT = 256; constexpr auto TEXTURE_HEIGHT = 256;
constexpr auto TEXTURE_WIDTH = 256; constexpr auto TEXTURE_WIDTH = 256;
constexpr auto TEXTURE_PAGE = (TEXTURE_HEIGHT * TEXTURE_WIDTH); constexpr auto TEXTURE_PAGE = (TEXTURE_HEIGHT * TEXTURE_WIDTH);
#define SHADOW_MAP_SIZE 1024
#define TEXTURE_ATLAS_SIZE 4096 #define TEXTURE_ATLAS_SIZE 4096
#define TEXTURE_PAGE_SIZE 262144 #define TEXTURE_PAGE_SIZE 262144
#define NUM_TEXTURE_PAGES_PER_ROW 16 #define NUM_TEXTURE_PAGES_PER_ROW 16

View file

@ -0,0 +1,24 @@
#include "framework.h"
#include "RenderPipelineState.h"
#include "Utils.h"
namespace T5M::Renderer {
using namespace Utils;
RenderPipelineState::RenderPipelineState(ID3D11Device* device, const ShaderCompileOptions& vertexShader, const ShaderCompileOptions& pixelShader, const BlendStateOptions& blendingOptions)
{
ComPtr<ID3D10Blob> blob;
this->vertexShader = compileVertexShader(device, vertexShader.fileName.c_str(), vertexShader.functionName.c_str(), vertexShader.profile.c_str(),nullptr, blob);
this->pixelShader = compilePixelShader(device, pixelShader.fileName.c_str(), pixelShader.functionName.c_str(), pixelShader.profile.c_str(), nullptr, blob);
D3D11_BLEND_DESC blndDesc = {};
blndDesc.IndependentBlendEnable = blendingOptions.blendingEnabled;
blndDesc.AlphaToCoverageEnable = false;
blndDesc.RenderTarget[0].BlendEnable = blendingOptions.blendingEnabled;
blndDesc.RenderTarget[0].BlendOp = (D3D11_BLEND_OP)blendingOptions.blendFunction;
blndDesc.RenderTarget[0].SrcBlend = (D3D11_BLEND)blendingOptions.sourceColorFactor;
blndDesc.RenderTarget[0].SrcBlendAlpha = (D3D11_BLEND)blendingOptions.sourceAlphaFactor;
blndDesc.RenderTarget[0].DestBlend = (D3D11_BLEND)blendingOptions.destinationColorFactor;
blndDesc.RenderTarget[0].DestBlendAlpha = (D3D11_BLEND)blendingOptions.destinationAlphaFactor;
blndDesc.RenderTarget[0].RenderTargetWriteMask = 0xFF;
device->CreateBlendState(&blndDesc, this->blendState.GetAddressOf());
}
}

View file

@ -0,0 +1,55 @@
#pragma once
#include <wrl/client.h>
#include <d3d11.h>
namespace T5M::Renderer {
class RenderPipelineState;
struct ShaderCompileOptions {
std::wstring fileName;
std::string functionName;
std::string profile;
std::string source;
};
struct BlendStateOptions {
enum BlendFunction {
SRC_ADD_DST,
SRC_SUBTRACT_DST,
DST_SUBTRACT_SRC,
MIN,
MAX
};
enum BlendFactor {
ZERO,
ONE,
SRC_COLOR,
INV_SRC_COLOR,
SRC_ALPHA,
INV_SRC_ALPHA,
DST_ALPHA,
INV_DST_ALPHA,
DST_COLOR,
INV_DST_COLOR,
ALPHA_SAT,
BLEND_FACTOR,
INV_BLEND_FACTOR,
};
BlendFunction blendFunction;
BlendFactor sourceColorFactor;
BlendFactor sourceAlphaFactor;
BlendFactor destinationColorFactor;
BlendFactor destinationAlphaFactor;
bool blendingEnabled;
};
using Microsoft::WRL::ComPtr;
class RenderPipelineState
{
private:
ComPtr<ID3D11InputLayout> inputLayout;
ComPtr<ID3D11VertexShader> vertexShader;
ComPtr<ID3D11PixelShader> pixelShader;
ComPtr<ID3D11BlendState> blendState;
ComPtr<ID3D11DepthStencilState> depthState;
public:
RenderPipelineState(ID3D11Device* device, const ShaderCompileOptions& vertexShader, const ShaderCompileOptions& pixelShader, const BlendStateOptions& blendingOptions);
};
}

View file

@ -3,14 +3,14 @@
#include "Utils.h" #include "Utils.h"
namespace T5M::Renderer { namespace T5M::Renderer {
using T5M::Renderer::Utils::throwIfFailed; using T5M::Renderer::Utils::throwIfFailed;
RenderTarget2D::RenderTarget2D(ID3D11Device* device, int w, int h, DXGI_FORMAT format) { RenderTarget2D::RenderTarget2D(ID3D11Device* device, int w, int h, DXGI_FORMAT colorFormat, DXGI_FORMAT depthFormat) {
D3D11_TEXTURE2D_DESC desc = {}; D3D11_TEXTURE2D_DESC desc = {};
desc.Width = w; desc.Width = w;
desc.Height = h; desc.Height = h;
desc.MipLevels = 1; desc.MipLevels = 1;
desc.ArraySize = 1; desc.ArraySize = 1;
desc.Format = format; desc.Format = colorFormat;
desc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0; desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT; desc.Usage = D3D11_USAGE_DEFAULT;
@ -46,7 +46,7 @@ namespace T5M::Renderer {
depthTexDesc.ArraySize = 1; depthTexDesc.ArraySize = 1;
depthTexDesc.SampleDesc.Count = 1; depthTexDesc.SampleDesc.Count = 1;
depthTexDesc.SampleDesc.Quality = 0; depthTexDesc.SampleDesc.Quality = 0;
depthTexDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthTexDesc.Format = depthFormat;
depthTexDesc.Usage = D3D11_USAGE_DEFAULT; depthTexDesc.Usage = D3D11_USAGE_DEFAULT;
depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthTexDesc.CPUAccessFlags = 0; depthTexDesc.CPUAccessFlags = 0;

View file

@ -11,7 +11,7 @@ namespace T5M::Renderer {
ComPtr<ID3D11Texture2D> DepthStencilTexture; ComPtr<ID3D11Texture2D> DepthStencilTexture;
ComPtr<ID3D11ShaderResourceView> DepthShaderResourceView; ComPtr<ID3D11ShaderResourceView> DepthShaderResourceView;
RenderTarget2D() {}; RenderTarget2D() {};
RenderTarget2D(ID3D11Device* device, int w, int h, DXGI_FORMAT format); RenderTarget2D(ID3D11Device* device, int w, int h, DXGI_FORMAT colorFormat, DXGI_FORMAT depthFormat = DXGI_FORMAT_D32_FLOAT);
}; };
} }

View file

@ -2,14 +2,14 @@
#include "RenderTargetCube.h" #include "RenderTargetCube.h"
#include "Utils.h" #include "Utils.h"
using T5M::Renderer::Utils::throwIfFailed; using T5M::Renderer::Utils::throwIfFailed;
T5M::Renderer::RenderTargetCube::RenderTargetCube(ID3D11Device* device, int resolution, DXGI_FORMAT format) : resolution(resolution) { T5M::Renderer::RenderTargetCube::RenderTargetCube(ID3D11Device* device, int resolution, DXGI_FORMAT colorFormat, DXGI_FORMAT depthFormat) : resolution(resolution) {
D3D11_TEXTURE2D_DESC desc = {}; D3D11_TEXTURE2D_DESC desc = {};
desc.Width = resolution; desc.Width = resolution;
desc.Height = resolution; desc.Height = resolution;
desc.MipLevels = 1; desc.MipLevels = 1;
desc.ArraySize = 6; desc.ArraySize = 6;
desc.Format = format; desc.Format = colorFormat;
desc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0; desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT; desc.Usage = D3D11_USAGE_DEFAULT;
@ -17,7 +17,7 @@ T5M::Renderer::RenderTargetCube::RenderTargetCube(ID3D11Device* device, int reso
desc.CPUAccessFlags = 0; desc.CPUAccessFlags = 0;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
HRESULT res = device->CreateTexture2D(&desc, NULL, &Texture); HRESULT res = device->CreateTexture2D(&desc, NULL, Texture.GetAddressOf());
throwIfFailed(res); throwIfFailed(res);
D3D11_RENDER_TARGET_VIEW_DESC viewDesc = {}; D3D11_RENDER_TARGET_VIEW_DESC viewDesc = {};
@ -49,7 +49,7 @@ T5M::Renderer::RenderTargetCube::RenderTargetCube(ID3D11Device* device, int reso
depthTexDesc.ArraySize = 6; depthTexDesc.ArraySize = 6;
depthTexDesc.SampleDesc.Count = 1; depthTexDesc.SampleDesc.Count = 1;
depthTexDesc.SampleDesc.Quality = 0; depthTexDesc.SampleDesc.Quality = 0;
depthTexDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthTexDesc.Format = depthFormat;
depthTexDesc.Usage = D3D11_USAGE_DEFAULT; depthTexDesc.Usage = D3D11_USAGE_DEFAULT;
depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthTexDesc.CPUAccessFlags = 0; depthTexDesc.CPUAccessFlags = 0;

View file

@ -36,6 +36,6 @@ namespace T5M::Renderer {
int resolution; int resolution;
D3D11_VIEWPORT viewport; D3D11_VIEWPORT viewport;
RenderTargetCube() : resolution(0), viewport({}) {}; RenderTargetCube() : resolution(0), viewport({}) {};
RenderTargetCube(ID3D11Device* device, int resolution, DXGI_FORMAT format); RenderTargetCube(ID3D11Device* device, int resolution, DXGI_FORMAT format, DXGI_FORMAT depthFormat = DXGI_FORMAT_D32_FLOAT);
}; };
} }

View file

@ -0,0 +1,76 @@
#include "framework.h"
#include "RenderTargetCubeArray.h"
#include "Utils.h"
namespace T5M::Renderer {
RenderTargetCubeArray::RenderTargetCubeArray(ID3D11Device* device, size_t resolution, size_t numCubes, DXGI_FORMAT colorFormat,DXGI_FORMAT depthFormat) : numCubes(numCubes), resolution(resolution), viewport(CreateViewport(resolution)) {
D3D11_TEXTURE2D_DESC desc = {};
desc.ArraySize = numCubes*6;
desc.Height = resolution;
desc.Width = resolution;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0x0;
desc.SampleDesc.Count = 1;
desc.MipLevels = 1;
desc.Format = colorFormat;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
desc.SampleDesc.Quality = 0;
HRESULT res = device->CreateTexture2D(&desc, nullptr, Texture.GetAddressOf());
Utils::throwIfFailed(res);
D3D11_RENDER_TARGET_VIEW_DESC viewDesc = {};
viewDesc.Format = desc.Format;
viewDesc.Texture2DArray.ArraySize = 1;
viewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
RenderTargetView.resize(numCubes);
for(int i = 0; i < numCubes - 1; i++)
for(int j = 0; j < 6; j++){
viewDesc.Texture2DArray.FirstArraySlice = D3D11CalcSubresource(0, i*numCubes+j, 1);
res = device->CreateRenderTargetView(Texture.Get(), &viewDesc, RenderTargetView[i][j].GetAddressOf());
Utils::throwIfFailed(res);
}
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Format = colorFormat;
srvDesc.TextureCubeArray.NumCubes = numCubes;
srvDesc.TextureCubeArray.First2DArrayFace = 0;
srvDesc.TextureCubeArray.MipLevels = 1;
srvDesc.TextureCubeArray.MostDetailedMip = 0;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
res = device->CreateShaderResourceView(Texture.Get(), &srvDesc,ShaderResourceView.GetAddressOf());
Utils::throwIfFailed(res);
D3D11_TEXTURE2D_DESC depthTexDesc = {};
depthTexDesc.Width = resolution;
depthTexDesc.Height = resolution;
depthTexDesc.MipLevels = 1;
depthTexDesc.ArraySize = numCubes*6;
depthTexDesc.SampleDesc.Count = 1;
depthTexDesc.SampleDesc.Quality = 0;
depthTexDesc.Format = depthFormat;
depthTexDesc.Usage = D3D11_USAGE_DEFAULT;
depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthTexDesc.CPUAccessFlags = 0;
depthTexDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
res = device->CreateTexture2D(&depthTexDesc, NULL, DepthStencilTexture.GetAddressOf());
Utils::throwIfFailed(res);
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
dsvDesc.Format = depthTexDesc.Format;
dsvDesc.Flags = 0;
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
dsvDesc.Texture2DArray.ArraySize = 1;
DepthStencilView.resize(numCubes);
for(int i = 0; i < numCubes - 1; i++)
for(int j = 0; j < 6; j++){
dsvDesc.Texture2DArray.FirstArraySlice = D3D11CalcSubresource(0, i * numCubes + j, 1);
res = device->CreateDepthStencilView(DepthStencilTexture.Get(), &dsvDesc, DepthStencilView[i][j].GetAddressOf());
Utils::throwIfFailed(res);
}
}
RenderTargetCubeArray::RenderTargetCubeArray() : resolution(0), viewport(CreateViewport(resolution)),numCubes(0) {
}
}

View file

@ -0,0 +1,34 @@
#pragma once
#include <d3d11.h>
#include <array>
#include <wrl/client.h>
namespace T5M::Renderer {
using Microsoft::WRL::ComPtr;
using std::array;
using std::vector;
class RenderTargetCubeArray {
private:
static constexpr D3D11_VIEWPORT CreateViewport(size_t resolution) {
return {
0,
0,
static_cast<FLOAT>(resolution),
static_cast<FLOAT>(resolution),
0,
1
};
}
public:
size_t numCubes;
size_t resolution;
D3D11_VIEWPORT viewport;
vector<array<ComPtr<ID3D11RenderTargetView>, 6>> RenderTargetView;
ComPtr<ID3D11ShaderResourceView> ShaderResourceView;
ComPtr<ID3D11Texture2D> Texture;
vector<array<ComPtr<ID3D11DepthStencilView>, 6>> DepthStencilView;
ComPtr<ID3D11Texture2D> DepthStencilTexture;
RenderTargetCubeArray();
RenderTargetCubeArray(ID3D11Device* device, size_t resolution,size_t arraySize, DXGI_FORMAT format, DXGI_FORMAT depthFormat = DXGI_FORMAT_D32_FLOAT);
};
}

View file

@ -47,7 +47,8 @@ namespace T5M::Renderer {
WorldPosition = Vector3(cam->pos.x, cam->pos.y, cam->pos.z); WorldPosition = Vector3(cam->pos.x, cam->pos.y, cam->pos.z);
Vector3 target = Vector3(cam->target.x, cam->target.y, cam->target.z); Vector3 target = Vector3(cam->target.x, cam->target.y, cam->target.z);
WorldDirection = Vector3(cam->target.x, cam->target.y, cam->target.z) - WorldPosition; WorldDirection = Vector3(cam->target.x, cam->target.y, cam->target.z) - WorldPosition;
WorldDirection.Normalize(); if (WorldDirection == Vector3::Zero) [[unlikely]]
WorldDirection = Vector3::UnitZ;
Vector3 up = -Vector3::UnitY; Vector3 up = -Vector3::UnitY;
Matrix upRotation = Matrix::CreateFromYawPitchRoll(0.0f, 0.0f, roll); Matrix upRotation = Matrix::CreateFromYawPitchRoll(0.0f, 0.0f, roll);
up = Vector3::Transform(up, upRotation); up = Vector3::Transform(up, upRotation);

View file

@ -33,51 +33,11 @@ namespace T5M::Renderer {
} }
Renderer11::~Renderer11() { Renderer11::~Renderer11() {
FreeRendererData(); freeRendererData();
DX11_RELEASE(m_backBufferRTV);
DX11_RELEASE(m_backBufferTexture);
DX11_RELEASE(m_depthStencilState);
DX11_RELEASE(m_depthStencilTexture);
DX11_RELEASE(m_depthStencilView);
DX11_DELETE(m_primitiveBatch);
DX11_DELETE(m_spriteBatch);
DX11_DELETE(m_gameFont);
DX11_DELETE(m_states);
DX11_RELEASE(m_vsRooms);
DX11_RELEASE(m_psRooms);
DX11_RELEASE(m_vsItems);
DX11_RELEASE(m_psItems);
DX11_RELEASE(m_vsStatics);
DX11_RELEASE(m_psStatics);
DX11_RELEASE(m_vsHairs);
DX11_RELEASE(m_psHairs);
DX11_RELEASE(m_vsSky);
DX11_RELEASE(m_psSky);
DX11_RELEASE(m_vsSprites);
DX11_RELEASE(m_psSprites);
DX11_RELEASE(m_vsSolid);
DX11_RELEASE(m_psSolid);
DX11_RELEASE(m_vsInventory);
DX11_RELEASE(m_psInventory);
DX11_RELEASE(m_vsFullScreenQuad);
DX11_RELEASE(m_psFullScreenQuad);
DX11_RELEASE(m_cbCameraMatrices);
DX11_RELEASE(m_cbItem);
DX11_RELEASE(m_cbStatic);
DX11_RELEASE(m_cbLights);
DX11_RELEASE(m_cbMisc);
DX11_RELEASE(m_cbHUD);
DX11_RELEASE(m_cbHUDBar);
DX11_RELEASE(m_swapChain);
DX11_RELEASE(m_context);
DX11_RELEASE(m_device);
DX11_RELEASE(m_cbSprite);
} }
void Renderer11::FreeRendererData() { void Renderer11::freeRendererData()
{
m_meshPointersToMesh.clear(); m_meshPointersToMesh.clear();
m_moveableObjects.clear(); m_moveableObjects.clear();
m_staticObjects.clear(); m_staticObjects.clear();
@ -118,103 +78,16 @@ namespace T5M::Renderer {
return nf; return nf;
} }
ID3D11VertexShader* Renderer11::compileVertexShader(const wchar_t* fileName, const char* function, const char* model, ID3D10Blob** bytecode) { void Renderer11::updateProgress(float value) {
HRESULT res;
*bytecode = NULL;
ID3DBlob* errors = NULL;
printf("Compiling vertex shader: %s\n", fileName);
UINT flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR | D3DCOMPILE_SKIP_OPTIMIZATION;
res = D3DCompileFromFile(fileName, NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, function, model, flags, 0, bytecode, &errors);
throwIfFailed(res);
ID3D11VertexShader* shader = NULL;
res = m_device->CreateVertexShader((*bytecode)->GetBufferPointer(), (*bytecode)->GetBufferSize(), NULL, &shader);
throwIfFailed(res);
return shader;
}
ID3D11PixelShader* Renderer11::compilePixelShader(const wchar_t* fileName, const char* function, const char* model, ID3D10Blob** bytecode) {
HRESULT res;
*bytecode = NULL;
ID3DBlob* errors = NULL;
printf("Compiling pixel shader: %s\n", fileName);
UINT flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR | D3DCOMPILE_SKIP_OPTIMIZATION;
throwIfFailed(D3DCompileFromFile(fileName, NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, function, model, flags, 0, bytecode, &errors));
ID3D11PixelShader* shader = NULL;
throwIfFailed(m_device->CreatePixelShader((*bytecode)->GetBufferPointer(), (*bytecode)->GetBufferSize(), NULL, &shader));
return shader;
}
ID3D11GeometryShader* Renderer11::compileGeometryShader(const wchar_t* fileName) {
HRESULT res;
ID3DBlob* bytecode = NULL;
ID3DBlob* errors = NULL;
res = D3DCompileFromFile(fileName, NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, NULL, "gs_4_0", D3D10_SHADER_OPTIMIZATION_LEVEL3, 0, &bytecode, &errors);
if (FAILED(res))
return NULL;
ID3D11GeometryShader* shader = NULL;
res = m_device->CreateGeometryShader(bytecode->GetBufferPointer(), bytecode->GetBufferSize(), NULL, &shader);
if (FAILED(res))
return NULL;
return shader;
}
ID3D11ComputeShader* Renderer11::compileComputeShader(const wchar_t* fileName) {
HRESULT res;
ID3DBlob* bytecode = NULL;
ID3DBlob* errors = NULL;
res = D3DCompileFromFile(fileName, NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, NULL, "gs_4_0", D3D10_SHADER_OPTIMIZATION_LEVEL3, 0, &bytecode, &errors);
if (FAILED(res))
return NULL;
ID3D11ComputeShader* shader = NULL;
res = m_device->CreateComputeShader(bytecode->GetBufferPointer(), bytecode->GetBufferSize(), NULL, &shader);
if (FAILED(res))
return NULL;
return shader;
}
void Renderer11::UpdateProgress(float value) {
m_progress = value; m_progress = value;
} }
ID3D11Buffer* Renderer11::createConstantBuffer(size_t size) {
ID3D11Buffer* buffer;
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.ByteWidth = size; // Constant buffer must have a size multiple of 16 bytes
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
HRESULT res = m_device->CreateBuffer(&desc, NULL, &buffer);
if (FAILED(res))
return NULL;
return buffer;
}
void Renderer11::renderToCubemap(const RenderTargetCube& dest,const Vector3& pos,int roomNumer) { void Renderer11::renderToCubemap(const RenderTargetCube& dest,const Vector3& pos,int roomNumer) {
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
RenderView renderView = RenderView(pos,RenderTargetCube::forwardVectors[i],RenderTargetCube::upVectors[i],dest.resolution,dest.resolution,Camera.pos.roomNumber,10,20480, 90* RADIAN); RenderView renderView = RenderView(pos,RenderTargetCube::forwardVectors[i],RenderTargetCube::upVectors[i],dest.resolution,dest.resolution,Camera.pos.roomNumber,10,20480, 90* RADIAN);
drawSimpleScene(dest.RenderTargetView[i].Get(), dest.DepthStencilView[i].Get(), renderView); renderSimpleScene(dest.RenderTargetView[i].Get(), dest.DepthStencilView[i].Get(), renderView);
m_context->ClearState(); m_context->ClearState();
} }
} }

View file

@ -20,17 +20,16 @@
#include "ConstantBuffers\SpriteBuffer.h" #include "ConstantBuffers\SpriteBuffer.h"
#include "RenderTargetCube\RenderTargetCube.h" #include "RenderTargetCube\RenderTargetCube.h"
#include "RenderView/RenderView.h" #include "RenderView/RenderView.h"
struct CAMERA_INFO;
#include <level.h> #include <level.h>
#include "ConstantBuffer/ConstantBuffer.h"
#include "RenderTargetCubeArray/RenderTargetCubeArray.h"
struct CAMERA_INFO;
#include <wrl/client.h>
namespace T5M::Renderer namespace T5M::Renderer
{ {
constexpr size_t MAX_DYNAMIC_SHADOWS = 1;
using TexturePair = std::tuple<Texture2D, Texture2D>; using TexturePair = std::tuple<Texture2D, Texture2D>;
#define MESH_BITS(x) (1 << x)
#define DX11_RELEASE(x) if (x != NULL) x->Release()
#define DX11_DELETE(x) if (x != NULL) { delete x; x = NULL; }
constexpr auto NUM_ANIMATED_SETS = 1024; constexpr auto NUM_ANIMATED_SETS = 1024;
constexpr auto MAX_LIGHTS_DRAW = 16384; constexpr auto MAX_LIGHTS_DRAW = 16384;
constexpr auto MAX_DYNAMIC_LIGHTS = 16384; constexpr auto MAX_DYNAMIC_LIGHTS = 16384;
@ -140,10 +139,6 @@ namespace T5M::Renderer
float In; float In;
float Out; float Out;
float Range; float Range;
RendererLight()
{
}
}; };
struct RendererAnimatedTexture struct RendererAnimatedTexture
@ -352,13 +347,12 @@ namespace T5M::Renderer
{ {
private: private:
// Core DX11 objects // Core DX11 objects
ID3D11Device* m_device = nullptr; Microsoft::WRL::ComPtr<ID3D11Device> m_device = nullptr;
ID3D11DeviceContext* m_context = nullptr; Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_context = nullptr;
IDXGISwapChain* m_swapChain = nullptr; Microsoft::WRL::ComPtr<IDXGISwapChain> m_swapChain = nullptr;
IDXGIDevice* m_dxgiDevice = nullptr; std::unique_ptr<CommonStates> m_states = nullptr;
CommonStates* m_states = nullptr; Microsoft::WRL::ComPtr<ID3D11BlendState> m_subtractiveBlendState = nullptr;
ID3D11BlendState* m_subtractiveBlendState = nullptr; Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout = nullptr;
ID3D11InputLayout* m_inputLayout = nullptr;
D3D11_VIEWPORT m_viewport; D3D11_VIEWPORT m_viewport;
D3D11_VIEWPORT m_shadowMapViewport; D3D11_VIEWPORT m_shadowMapViewport;
Viewport* m_viewportToolkit; Viewport* m_viewportToolkit;
@ -378,70 +372,68 @@ namespace T5M::Renderer
T5M::Renderer::RenderTarget2D m_shadowMap; T5M::Renderer::RenderTarget2D m_shadowMap;
T5M::Renderer::RenderTargetCube m_reflectionCubemap; T5M::Renderer::RenderTargetCube m_reflectionCubemap;
// Shaders // Shaders
ID3D11VertexShader* m_vsRooms; Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vsRooms;
ID3D11PixelShader* m_psRooms; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psRooms;
ID3D11VertexShader* m_vsItems; Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vsItems;
ID3D11PixelShader* m_psItems; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psItems;
ID3D11VertexShader* m_vsHairs; Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vsHairs;
ID3D11PixelShader* m_psHairs; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psHairs;
ID3D11VertexShader* m_vsStatics; Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vsStatics;
ID3D11PixelShader* m_psStatics; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psStatics;
ID3D11VertexShader* m_vsSky; Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vsSky;
ID3D11PixelShader* m_psSky; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psSky;
ID3D11VertexShader* m_vsSprites; Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vsSprites;
ID3D11PixelShader* m_psSprites; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psSprites;
ID3D11VertexShader* m_vsSolid; Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vsSolid;
ID3D11PixelShader* m_psSolid; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psSolid;
ID3D11VertexShader* m_vsInventory; Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vsInventory;
ID3D11PixelShader* m_psInventory; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psInventory;
ID3D11VertexShader* m_vsFullScreenQuad; Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vsFullScreenQuad;
ID3D11PixelShader* m_psFullScreenQuad; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psFullScreenQuad;
ID3D11VertexShader* m_vsShadowMap; Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vsShadowMap;
ID3D11PixelShader* m_psShadowMap; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psShadowMap;
ID3D11VertexShader* m_vsHUD; Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vsHUD;
ID3D11PixelShader* m_psHUDColor; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psHUDColor;
ID3D11PixelShader* m_psHUDTexture; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psHUDTexture;
ID3D11PixelShader* m_psHUDBarColor; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_psHUDBarColor;
Microsoft::WRL::ComPtr<ID3D11SamplerState> m_shadowSampler;
ID3D11ShaderResourceView* m_shadowMapRV;
ID3D11Texture2D* m_shadowMapTexture;
ID3D11DepthStencilView* m_shadowMapDSV;
// Constant buffers // Constant buffers
RenderView gameCamera; RenderView gameCamera;
ID3D11Buffer* m_cbCameraMatrices; ConstantBuffer<CCameraMatrixBuffer> m_cbCameraMatrices;
CItemBuffer m_stItem; CItemBuffer m_stItem;
ID3D11Buffer* m_cbItem; ConstantBuffer<CItemBuffer> m_cbItem;
CStaticBuffer m_stStatic; CStaticBuffer m_stStatic;
ID3D11Buffer* m_cbStatic; ConstantBuffer<CStaticBuffer> m_cbStatic;
CLightBuffer m_stLights; CLightBuffer m_stLights;
ID3D11Buffer* m_cbLights; ConstantBuffer<CLightBuffer> m_cbLights;
CMiscBuffer m_stMisc; CMiscBuffer m_stMisc;
ID3D11Buffer* m_cbMisc; ConstantBuffer<CMiscBuffer> m_cbMisc;
CRoomBuffer m_stRoom; CRoomBuffer m_stRoom;
ID3D11Buffer* m_cbRoom; ConstantBuffer<CRoomBuffer> m_cbRoom;
CShadowLightBuffer m_stShadowMap; CShadowLightBuffer m_stShadowMap;
ID3D11Buffer* m_cbShadowMap; ConstantBuffer<CShadowLightBuffer> m_cbShadowMap;
CHUDBuffer m_stHUD; CHUDBuffer m_stHUD;
ID3D11Buffer* m_cbHUD; ConstantBuffer<CHUDBuffer> m_cbHUD;
CHUDBarBuffer m_stHUDBar; CHUDBarBuffer m_stHUDBar;
ID3D11Buffer* m_cbHUDBar; ConstantBuffer<CHUDBarBuffer> m_cbHUDBar;
CSpriteBuffer m_stSprite; CSpriteBuffer m_stSprite;
ID3D11Buffer* m_cbSprite; ConstantBuffer<CSpriteBuffer> m_cbSprite;
// Text and sprites // Text and sprites
SpriteFont* m_gameFont; std::unique_ptr<SpriteFont> m_gameFont;
SpriteBatch* m_spriteBatch; std::unique_ptr<SpriteBatch> m_spriteBatch;
std::vector<RendererStringToDraw> m_strings; std::vector<RendererStringToDraw> m_strings;
int m_blinkColorValue; int m_blinkColorValue;
int m_blinkColorDirection; int m_blinkColorDirection;
PrimitiveBatch<RendererVertex>* m_primitiveBatch; std::unique_ptr<PrimitiveBatch<RendererVertex>> m_primitiveBatch;
// System resources // System resources
T5M::Renderer::Texture2D m_HUDBarBorderTexture; T5M::Renderer::Texture2D m_HUDBarBorderTexture;
T5M::Renderer::Texture2D m_caustics[NUM_CAUSTICS_TEXTURES]; T5M::Renderer::Texture2D m_caustics[NUM_CAUSTICS_TEXTURES];
T5M::Renderer::Texture2D m_binocularsTexture; T5M::Renderer::Texture2D m_binocularsTexture;
T5M::Renderer::Texture2D m_whiteTexture; T5M::Renderer::Texture2D m_whiteTexture;
T5M::Renderer::RenderTargetCubeArray m_shadowMaps;
// Level data // Level data
T5M::Renderer::Texture2D m_titleScreen; T5M::Renderer::Texture2D m_titleScreen;
@ -527,13 +519,7 @@ namespace T5M::Renderer
int m_pickupRotation; int m_pickupRotation;
// Private functions // Private functions
bool drawScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, CCameraMatrixBuffer& camera); void drawAllStrings();
bool drawAllStrings();
ID3D11VertexShader* compileVertexShader(const wchar_t * fileName, const char* function, const char* model, ID3D10Blob** bytecode);
ID3D11GeometryShader* compileGeometryShader(const wchar_t * fileName);
ID3D11PixelShader* compilePixelShader(const wchar_t * fileName, const char* function, const char* model, ID3D10Blob** bytecode);
ID3D11ComputeShader* compileComputeShader(const wchar_t * fileName);
ID3D11Buffer* createConstantBuffer(size_t size);
int getAnimatedTextureInfo(short textureId); int getAnimatedTextureInfo(short textureId);
void initialiseHairRemaps(); void initialiseHairRemaps();
RendererMesh* getRendererMeshFromTrMesh(RendererObject* obj, MESH* meshPtr, short boneIndex, int isJoints, int isHairs); RendererMesh* getRendererMeshFromTrMesh(RendererObject* obj, MESH* meshPtr, short boneIndex, int isJoints, int isHairs);
@ -558,18 +544,18 @@ namespace T5M::Renderer
int getFrame(short animation, short frame, ANIM_FRAME** framePtr, int* rate); int getFrame(short animation, short frame, ANIM_FRAME** framePtr, int* rate);
bool drawAmbientCubeMap(short roomNumber); bool drawAmbientCubeMap(short roomNumber);
bool sphereBoxIntersection(DirectX::SimpleMath::Vector3 boxMin, DirectX::SimpleMath::Vector3 boxMax, DirectX::SimpleMath::Vector3 sphereCentre, float sphereRadius); bool sphereBoxIntersection(DirectX::SimpleMath::Vector3 boxMin, DirectX::SimpleMath::Vector3 boxMax, DirectX::SimpleMath::Vector3 sphereCentre, float sphereRadius);
bool drawHorizonAndSky(ID3D11DepthStencilView* depthTarget); void drawHorizonAndSky(ID3D11DepthStencilView* depthTarget);
bool drawRooms(bool transparent, bool animated, RenderView& view); void drawRooms(bool transparent, bool animated, RenderView& view);
bool drawItems(bool transparent, bool animated,RenderView& view); void drawItems(bool transparent, bool animated,RenderView& view);
bool drawAnimatingItem(RendererItem* item, bool transparent, bool animated); void drawAnimatingItem(RendererItem* item, bool transparent, bool animated);
bool drawBaddieGunflashes(); void drawBaddieGunflashes();
bool drawScaledSpikes(RendererItem* item, bool transparent, bool animated); void drawScaledSpikes(RendererItem* item, bool transparent, bool animated);
bool drawStatics(bool transparent, RenderView& view); void drawStatics(bool transparent, RenderView& view);
bool drawWaterfalls(); void drawWaterfalls();
bool drawWraithExtra(RendererItem* item, bool transparent, bool animated); void renderShadowMap(RenderView& view);
bool drawShadowMap(); void drawWraithExtra(RendererItem* item, bool transparent, bool animated);
bool drawObjectOn2DPosition(short x, short y, short objectNum, short rotX, short rotY, short rotZ); void drawObjectOn2DPosition(short x, short y, short objectNum, short rotX, short rotY, short rotZ);
bool drawLara(bool transparent, bool shadowMap); void drawLara(bool transparent, bool shadowMap);
void printDebugMessage(LPCSTR message, ...); void printDebugMessage(LPCSTR message, ...);
void drawFires(); void drawFires();
void drawSparks(); void drawSparks();
@ -578,41 +564,40 @@ namespace T5M::Renderer
void drawBlood(); void drawBlood();
void drawDrips(); void drawDrips();
void drawBubbles(); void drawBubbles();
bool drawEffects(bool transparent); void drawEffects(bool transparent);
bool drawEffect(RendererEffect* effect, bool transparent); void drawEffect(RendererEffect* effect, bool transparent);
void drawSplahes(); void drawSplahes();
bool drawSprites(); void drawSprites();
bool drawLines3D(); void drawLines3D();
bool drawLines2D(); void drawLines2D();
bool drawOverlays(); void drawOverlays();
bool drawRopes(); void drawRopes();
bool drawBats(); void drawBats();
bool drawRats(); void drawRats();
bool drawLittleBeetles(); void drawLittleBeetles();
bool drawSpiders(); void drawSpiders();
bool drawGunFlashes(); bool drawGunFlashes();
bool drawGunShells(); void drawGunShells();
int drawInventoryScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, ID3D11ShaderResourceView* background); void renderInventoryScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, ID3D11ShaderResourceView* background);
bool drawDebris(bool transparent); void drawDebris(bool transparent);
int drawFinalPass(); void drawFullScreenImage(ID3D11ShaderResourceView* texture, float fade, ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget);
bool drawFullScreenImage(ID3D11ShaderResourceView* texture, float fade, ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget);
void updateAnimatedTextures(); void updateAnimatedTextures();
void createBillboardMatrix(DirectX::SimpleMath::Matrix* out, DirectX::SimpleMath::Vector3* particlePos, DirectX::SimpleMath::Vector3* cameraPos, float rotation); void createBillboardMatrix(DirectX::SimpleMath::Matrix* out, DirectX::SimpleMath::Vector3* particlePos, DirectX::SimpleMath::Vector3* cameraPos, float rotation);
void drawShockwaves(); void drawShockwaves();
void drawRipples(); void drawRipples();
void drawUnderwaterDust(); void drawUnderwaterDust();
bool doRain(); void doRain();
bool doSnow(); void doSnow();
bool drawFullScreenQuad(ID3D11ShaderResourceView* texture, DirectX::SimpleMath::Vector3 color, bool cinematicBars); void drawFullScreenQuad(ID3D11ShaderResourceView* texture, DirectX::SimpleMath::Vector3 color, bool cinematicBars);
bool isRoomUnderwater(short roomNumber); bool isRoomUnderwater(short roomNumber);
bool isInRoom(int x, int y, int z, short roomNumber); bool isInRoom(int x, int y, int z, short roomNumber);
bool drawColoredQuad(int x, int y, int w, int h, DirectX::SimpleMath::Vector4 color); void drawColoredQuad(int x, int y, int w, int h, DirectX::SimpleMath::Vector4 color);
bool initialiseScreen(int w, int h, int refreshRate, bool windowed, HWND handle, bool reset); void initialiseScreen(int w, int h, int refreshRate, bool windowed, HWND handle, bool reset);
bool initialiseBars(); void initialiseBars();
bool drawSmokeParticles(); void drawSmokeParticles();
bool drawSparkParticles(); void drawSparkParticles();
bool drawDripParticles(); void drawDripParticles();
bool drawExplosionParticles(); void drawExplosionParticles();
void renderToCubemap(const RenderTargetCube& dest,const Vector3& pos,int roomNumber); void renderToCubemap(const RenderTargetCube& dest,const Vector3& pos,int roomNumber);
void drawLaraHolsters(bool transparent); void drawLaraHolsters(bool transparent);
public: public:
@ -624,77 +609,62 @@ namespace T5M::Renderer
int ScreenHeight; int ScreenHeight;
bool Windowed; bool Windowed;
int NumTexturePages; int NumTexturePages;
Renderer11(); Renderer11();
~Renderer11(); ~Renderer11();
bool Create(); void Create();
bool EnumerateVideoModes(); void EnumerateVideoModes();
bool Initialise(int w, int h, int refreshRate, bool windowed, HWND handle); void Initialise(int w, int h, int refreshRate, bool windowed, HWND handle);
int Draw(); void Draw();
bool PrepareDataForTheRenderer(); bool PrepareDataForTheRenderer();
void UpdateCameraMatrices(CAMERA_INFO* cam, float roll, float fov); void UpdateCameraMatrices(CAMERA_INFO* cam, float roll, float fov);
bool drawSimpleScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, RenderView& view); void renderSimpleScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, RenderView& view);
int DumpGameScene(); void DumpGameScene();
int DrawInventory(); void renderInventory();
int DrawTitle(); void renderTitle();
bool drawScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, RenderView& view); void renderScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, RenderView& view);
int DrawPickup(short objectNum); void drawPickup(short objectNum);
int SyncRenderer(); int SyncRenderer();
bool PrintString(int x, int y, char* string, D3DCOLOR color, int flags); void drawString(int x, int y, const char* string, D3DCOLOR color, int flags);
void ClearDynamicLights(); void clearDynamicLights();
void AddDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b); void addDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b);
void FreeRendererData(); void freeRendererData();
void EnableCinematicBars(bool value); void enableCinematicBars(bool value);
void FadeIn(); void fadeIn();
void FadeOut(); void fadeOut();
void DrawLoadingScreen(std::wstring& fileName); void renderLoadingScreen(std::wstring& fileName);
void UpdateProgress(float value); void updateProgress(float value);
bool IsFading(); bool isFading();
void GetLaraBonePosition(DirectX::SimpleMath::Vector3* pos, int bone); void getLaraBonePosition(DirectX::SimpleMath::Vector3* pos, int bone);
bool ToggleFullScreen(); void toggleFullScreen();
bool IsFullsScreen(); bool isFullsScreen();
std::vector<RendererVideoAdapter>* GetAdapters(); std::vector<RendererVideoAdapter>* getAdapters();
bool DoTitleImage(); void renderTitleImage();
void AddLine2D(int x1, int y1, int x2, int y2, byte r, byte g, byte b, byte a); void addLine2D(int x1, int y1, int x2, int y2, byte r, byte g, byte b, byte a);
void AddSpriteBillboard(RendererSprite* sprite, DirectX::SimpleMath::Vector3 pos,DirectX::SimpleMath::Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode); void addSpriteBillboard(RendererSprite* sprite, DirectX::SimpleMath::Vector3 pos,DirectX::SimpleMath::Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode);
void AddSpriteBillboardConstrained(RendererSprite* sprite, DirectX::SimpleMath::Vector3 pos, DirectX::SimpleMath::Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode, DirectX::SimpleMath::Vector3 constrainAxis); void addSpriteBillboardConstrained(RendererSprite* sprite, DirectX::SimpleMath::Vector3 pos, DirectX::SimpleMath::Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode, DirectX::SimpleMath::Vector3 constrainAxis);
void AddSpriteBillboardConstrainedLookAt(RendererSprite* sprite, DirectX::SimpleMath::Vector3 pos, DirectX::SimpleMath::Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode, DirectX::SimpleMath::Vector3 lookAtAxis); void addSpriteBillboardConstrainedLookAt(RendererSprite* sprite, DirectX::SimpleMath::Vector3 pos, DirectX::SimpleMath::Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode, DirectX::SimpleMath::Vector3 lookAtAxis);
void AddSprite3D(RendererSprite* sprite, DirectX::SimpleMath::Vector3 vtx1, DirectX::SimpleMath::Vector3 vtx2, DirectX::SimpleMath::Vector3 vtx3, DirectX::SimpleMath::Vector3 vtx4, DirectX::SimpleMath::Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode); void addSprite3D(RendererSprite* sprite, DirectX::SimpleMath::Vector3 vtx1, DirectX::SimpleMath::Vector3 vtx2, DirectX::SimpleMath::Vector3 vtx3, DirectX::SimpleMath::Vector3 vtx4, DirectX::SimpleMath::Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode);
void AddLine3D(DirectX::SimpleMath::Vector3 start, DirectX::SimpleMath::Vector3 end, DirectX::SimpleMath::Vector4 color); void addLine3D(DirectX::SimpleMath::Vector3 start, DirectX::SimpleMath::Vector3 end, DirectX::SimpleMath::Vector4 color);
bool ChangeScreenResolution(int width, int height, int frequency, bool windowed); void changeScreenResolution(int width, int height, int frequency, bool windowed);
bool DrawBar(float percent, const RendererHUDBar* const bar); void drawBar(float percent, const RendererHUDBar* const bar);
void FlipRooms(short roomNumber1, short roomNumber2); void flipRooms(short roomNumber1, short roomNumber2);
void ResetAnimations(); void resetAnimations();
void UpdateLaraAnimations(bool force); void updateLaraAnimations(bool force);
void UpdateItemAnimations(int itemNumber, bool force); void updateItemAnimations(int itemNumber, bool force);
void GetLaraAbsBonePosition(DirectX::SimpleMath::Vector3* pos, int joint); void getLaraAbsBonePosition(DirectX::SimpleMath::Vector3* pos, int joint);
void GetItemAbsBonePosition(int itemNumber, DirectX::SimpleMath::Vector3* pos, int joint); void getItemAbsBonePosition(int itemNumber, DirectX::SimpleMath::Vector3* pos, int joint);
int GetSpheres(short itemNumber, BoundingSphere* ptr, char worldSpace, DirectX::SimpleMath::Matrix local); int getSpheres(short itemNumber, BoundingSphere* ptr, char worldSpace, DirectX::SimpleMath::Matrix local);
void GetBoneMatrix(short itemNumber, int joint, DirectX::SimpleMath::Matrix* outMatrix); void getBoneMatrix(short itemNumber, int joint, DirectX::SimpleMath::Matrix* outMatrix);
RendererMesh* getMesh(int meshIndex); RendererMesh* getMesh(int meshIndex);
private: private:
Texture2D CreateDefaultNormalTexture(); Texture2D createDefaultNormalTexture();
void drawFootprints(); void drawFootprints();
template<typename CBuff> template <typename C>
bool updateConstantBuffer(ID3D11Buffer* buffer, CBuff& data) { ConstantBuffer<C> createConstantBuffer() {
HRESULT res; return ConstantBuffer<C>(m_device.Get());
D3D11_MAPPED_SUBRESOURCE mappedResource;
// Lock the constant buffer so it can be written to.
res = m_context->Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(res))
return false;
// Get a pointer to the data in the constant buffer.
void* dataPtr = (mappedResource.pData);
memcpy(dataPtr, &data, sizeof(CBuff));
// Unlock the constant buffer.
m_context->Unmap(buffer, 0);
return true;
} }
}; };

View file

@ -17,7 +17,7 @@ namespace T5M::Renderer
m_moveableObjects.resize(ID_NUMBER_OBJECTS); m_moveableObjects.resize(ID_NUMBER_OBJECTS);
m_spriteSequences.resize(ID_NUMBER_OBJECTS); m_spriteSequences.resize(ID_NUMBER_OBJECTS);
m_staticObjects.resize(MAX_STATICS); m_staticObjects.resize(MAX_STATICS);
m_rooms = vector<RendererRoom>(NUM_ROOMS); m_rooms.resize(g_Level.Rooms.size());
m_meshes.clear(); m_meshes.clear();
@ -107,79 +107,85 @@ namespace T5M::Renderer
//free(buffer); //free(buffer);
// Upload textures to GPU memory // Upload textures to GPU memory
m_roomTextures.resize(g_Level.RoomTextures.size());
for (int i = 0; i < g_Level.RoomTextures.size(); i++) for (int i = 0; i < g_Level.RoomTextures.size(); i++)
{ {
TEXTURE *texture = &g_Level.RoomTextures[i]; TEXTURE *texture = &g_Level.RoomTextures[i];
Texture2D normal; Texture2D normal;
if (texture->normalMapData.size() < 1) { if (texture->normalMapData.size() < 1) {
normal = CreateDefaultNormalTexture(); normal = createDefaultNormalTexture();
} else { } else {
normal = Texture2D(m_device, texture->normalMapData.data(), texture->normalMapData.size()); normal = Texture2D(m_device.Get(), texture->normalMapData.data(), texture->normalMapData.size());
} }
TexturePair tex =std::make_tuple(Texture2D(m_device, texture->colorMapData.data(), texture->colorMapData.size()), normal); TexturePair tex =std::make_tuple(Texture2D(m_device.Get(), texture->colorMapData.data(), texture->colorMapData.size()), normal);
m_roomTextures.push_back(tex); m_roomTextures[i] = tex;
} }
m_moveablesTextures.resize(g_Level.MoveablesTextures.size());
for (int i = 0; i < g_Level.MoveablesTextures.size(); i++) for (int i = 0; i < g_Level.MoveablesTextures.size(); i++)
{ {
TEXTURE *texture = &g_Level.MoveablesTextures[i]; TEXTURE *texture = &g_Level.MoveablesTextures[i];
Texture2D normal; Texture2D normal;
if (texture->normalMapData.size() < 1) { if (texture->normalMapData.size() < 1) {
normal = CreateDefaultNormalTexture(); normal = createDefaultNormalTexture();
} else { } else {
normal = Texture2D(m_device, texture->normalMapData.data(), texture->normalMapData.size()); normal = Texture2D(m_device.Get(), texture->normalMapData.data(), texture->normalMapData.size());
} }
TexturePair tex = std::make_tuple(Texture2D(m_device, texture->colorMapData.data(), texture->colorMapData.size()), normal); TexturePair tex = std::make_tuple(Texture2D(m_device.Get(), texture->colorMapData.data(), texture->colorMapData.size()), normal);
m_moveablesTextures.push_back(tex); m_moveablesTextures[i] = tex;
} }
m_staticsTextures.resize(g_Level.RoomTextures.size());
for (int i = 0; i < g_Level.StaticsTextures.size(); i++) for (int i = 0; i < g_Level.StaticsTextures.size(); i++)
{ {
TEXTURE *texture = &g_Level.StaticsTextures[i]; TEXTURE *texture = &g_Level.StaticsTextures[i];
Texture2D normal; Texture2D normal;
if (texture->normalMapData.size() < 1) { if (texture->normalMapData.size() < 1) {
normal = CreateDefaultNormalTexture(); normal = createDefaultNormalTexture();
} else { } else {
normal = Texture2D(m_device, texture->normalMapData.data(), texture->normalMapData.size()); normal = Texture2D(m_device.Get(), texture->normalMapData.data(), texture->normalMapData.size());
} }
TexturePair tex = std::make_tuple(Texture2D(m_device, texture->colorMapData.data(), texture->colorMapData.size()), normal); TexturePair tex = std::make_tuple(Texture2D(m_device.Get(), texture->colorMapData.data(), texture->colorMapData.size()), normal);
m_staticsTextures.push_back(tex); m_staticsTextures[i] = tex;
} }
m_spritesTextures.resize(g_Level.SpritesTextures.size());
for (int i = 0; i < g_Level.SpritesTextures.size(); i++) for (int i = 0; i < g_Level.SpritesTextures.size(); i++)
{ {
TEXTURE *texture = &g_Level.SpritesTextures[i]; TEXTURE *texture = &g_Level.SpritesTextures[i];
m_spritesTextures.push_back(Texture2D(m_device, texture->colorMapData.data(), texture->colorMapData.size())); m_spritesTextures[i] = Texture2D(m_device.Get(), texture->colorMapData.data(), texture->colorMapData.size());
} }
m_skyTexture = Texture2D(m_device, g_Level.MiscTextures.colorMapData.data(), g_Level.MiscTextures.colorMapData.size()); m_skyTexture = Texture2D(m_device.Get(), g_Level.MiscTextures.colorMapData.data(), g_Level.MiscTextures.colorMapData.size());
// Step 2: prepare rooms // Step 2: prepare rooms
vector<RendererVertex> roomVertices; vector<RendererVertex> roomVertices;
vector<int> roomIndices; vector<int> roomIndices;
int baseRoomVertex = 0; int totalRoomsVertices = 0;
int baseRoomIndex = 0; int totalRoomsIndices = 0;
for (int i = 0; i < g_Level.Rooms.size(); i++) for (int i = 0; i < g_Level.Rooms.size(); i++)
{ {
ROOM_INFO *room = &g_Level.Rooms[i]; ROOM_INFO* room = &g_Level.Rooms[i];
m_rooms[i] = RendererRoom(); RendererRoom* r = &m_rooms[i];
RendererRoom &r = m_rooms[i]; r->RoomNumber = i;
r.RoomNumber = i; r->Room = room;
r.Room = room; r->AmbientLight = Vector4(room->ambient.x, room->ambient.y, room->ambient.z, 1.0f);
r.AmbientLight = Vector4(room->ambient.x, room->ambient.y, room->ambient.z, 1.0f);
//r.LightsToDraw = vector<RendererLight*>(MAX_LIGHTS); //r.LightsToDraw = vector<RendererLight*>(MAX_LIGHTS);
r.Statics.resize(room->mesh.size()); r->Statics.resize(room->mesh.size());
if (room->positions.size() == 0) if (room->positions.size() == 0)
continue; continue;
int baseRoomVertex = 0;
int baseRoomIndex = 0;
for (int n = 0; n < room->buckets.size(); n++) for (int n = 0; n < room->buckets.size(); n++)
{ {
BUCKET *levelBucket = &room->buckets[n]; BUCKET* levelBucket = &room->buckets[n];
RendererBucket *bucket; RendererBucket* bucket;
int bucketIndex; int bucketIndex;
if (levelBucket->blendMode != 0) if (levelBucket->blendMode != 0)
@ -187,125 +193,140 @@ namespace T5M::Renderer
else else
bucketIndex = RENDERER_BUCKET_SOLID; bucketIndex = RENDERER_BUCKET_SOLID;
bucket = &r.Buckets[bucketIndex]; bucket = &r->Buckets[bucketIndex];
bucket->Vertices.reserve(levelBucket->numQuads * 4 + levelBucket->numTriangles * 3); bucket->Vertices.resize(levelBucket->numQuads * 4 + levelBucket->numTriangles * 3);
bucket->Indices.reserve(levelBucket->numQuads * 6 + levelBucket->numTriangles * 3); bucket->Indices.resize(levelBucket->numQuads * 6 + levelBucket->numTriangles * 3);
int lastVertex = 0;
int lastIndex = 0;
for (int p = 0; p < levelBucket->polygons.size(); p++) for (int p = 0; p < levelBucket->polygons.size(); p++)
{ {
POLYGON* poly = &levelBucket->polygons[p]; POLYGON* poly = &levelBucket->polygons[p];
int baseVertices = bucket->Vertices.size(); int baseVertices = lastVertex;
for (int k = 0; k < poly->indices.size(); k++) for (int k = 0; k < poly->indices.size(); k++)
{ {
RendererVertex vertex; RendererVertex* vertex = &bucket->Vertices[lastVertex];
int v = poly->indices[k]; int v = poly->indices[k];
vertex.Position.x = room->x + room->positions[v].x; vertex->Position.x = room->x + room->positions[v].x;
vertex.Position.y = room->y + room->positions[v].y; vertex->Position.y = room->y + room->positions[v].y;
vertex.Position.z = room->z + room->positions[v].z; vertex->Position.z = room->z + room->positions[v].z;
vertex.Normal = poly->normals[k]; vertex->Normal = poly->normals[k];
vertex.UV = poly->textureCoordinates[k]; vertex->UV = poly->textureCoordinates[k];
vertex.Color = Vector4(room->colors[v].x, room->colors[v].y, room->colors[v].z,1.0f); vertex->Color = Vector4(room->colors[v].x, room->colors[v].y, room->colors[v].z, 1.0f);
vertex.Tangent = poly->tangents[k]; vertex->Tangent = poly->tangents[k];
vertex.BiTangent = poly->bitangents[k]; vertex->BiTangent = poly->bitangents[k];
vertex.Bone = 0; vertex->Bone = 0;
bucket->Vertices.push_back(vertex); lastVertex++;
totalRoomsVertices++;
} }
if (poly->shape == 0) if (poly->shape == 0)
{ {
bucket->Indices.push_back(baseVertices); bucket->Indices[lastIndex + 0] = baseVertices + 0; //.push_back(baseVertices);
bucket->Indices.push_back(baseVertices + 1); bucket->Indices[lastIndex + 1] = baseVertices + 1; //.push_back(baseVertices + 1);
bucket->Indices.push_back(baseVertices + 3); bucket->Indices[lastIndex + 2] = baseVertices + 3; //.push_back(baseVertices + 3);
bucket->Indices.push_back(baseVertices + 2); bucket->Indices[lastIndex + 3] = baseVertices + 2; //.push_back(baseVertices + 2);
bucket->Indices.push_back(baseVertices + 3); bucket->Indices[lastIndex + 4] = baseVertices + 3; //.push_back(baseVertices + 3);
bucket->Indices.push_back(baseVertices + 1); bucket->Indices[lastIndex + 5] = baseVertices + 1; //.push_back(baseVertices + 1);
lastIndex += 6;
totalRoomsIndices += 6;
} }
else else
{ {
bucket->Indices.push_back(baseVertices); bucket->Indices[lastIndex + 0] = baseVertices + 0; //.push_back(baseVertices);
bucket->Indices.push_back(baseVertices + 1); bucket->Indices[lastIndex + 1] = baseVertices + 1; //.push_back(baseVertices + 1);
bucket->Indices.push_back(baseVertices + 2); bucket->Indices[lastIndex + 2] = baseVertices + 2; //.push_back(baseVertices + 2);
lastIndex += 3;
totalRoomsIndices += 3;
} }
} }
} }
if (room->lights.size() != 0) if (room->lights.size() != 0)
{ {
r->Lights.resize(room->lights.size());
for (int l = 0; l < room->lights.size(); l++) for (int l = 0; l < room->lights.size(); l++)
{ {
RendererLight light; RendererLight* light = &r->Lights[l];
ROOM_LIGHT *oldLight = &room->lights[l]; ROOM_LIGHT* oldLight = &room->lights[l];
if (oldLight->type == LIGHT_TYPES::LIGHT_TYPE_SUN) if (oldLight->type == LIGHT_TYPES::LIGHT_TYPE_SUN)
{ {
light.Color = Vector3(oldLight->r, oldLight->g, oldLight->b); light->Color = Vector3(oldLight->r, oldLight->g, oldLight->b);
light.Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f); light->Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f);
light.Type = LIGHT_TYPES::LIGHT_TYPE_SUN; light->Type = LIGHT_TYPES::LIGHT_TYPE_SUN;
light.Intensity = 1.0f; light->Intensity = 1.0f;
r.Lights.push_back(light);
} }
else if (oldLight->type == LIGHT_TYPE_POINT) else if (oldLight->type == LIGHT_TYPE_POINT)
{ {
light.Position = Vector3(oldLight->x, oldLight->y, oldLight->z); light->Position = Vector3(oldLight->x, oldLight->y, oldLight->z);
light.Color = Vector3(oldLight->r, oldLight->g, oldLight->b); light->Color = Vector3(oldLight->r, oldLight->g, oldLight->b);
light.Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f); light->Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f);
light.Intensity = 1.0f; light->Intensity = 1.0f;
light.In = oldLight->in; light->In = oldLight->in;
light.Out = oldLight->out; light->Out = oldLight->out;
light.Type = LIGHT_TYPE_POINT; light->Type = LIGHT_TYPE_POINT;
r.Lights.push_back(light);
} }
else if (oldLight->type == LIGHT_TYPE_SHADOW) else if (oldLight->type == LIGHT_TYPE_SHADOW)
{ {
light.Position = Vector3(oldLight->x, oldLight->y, oldLight->z); light->Position = Vector3(oldLight->x, oldLight->y, oldLight->z);
light.Color = Vector3(oldLight->r, oldLight->g, oldLight->b); light->Color = Vector3(oldLight->r, oldLight->g, oldLight->b);
light.In = oldLight->in; light->In = oldLight->in;
light.Out = oldLight->out; light->Out = oldLight->out;
light.Type = LIGHT_TYPE_SHADOW; light->Type = LIGHT_TYPE_SHADOW;
light.Intensity = 1.0f; light->Intensity = 1.0f;
r.Lights.push_back(light);
} }
else if (oldLight->type == LIGHT_TYPE_SPOT) else if (oldLight->type == LIGHT_TYPE_SPOT)
{ {
light.Position = Vector3(oldLight->x, oldLight->y, oldLight->z); light->Position = Vector3(oldLight->x, oldLight->y, oldLight->z);
light.Color = Vector3(oldLight->r, oldLight->g, oldLight->b); light->Color = Vector3(oldLight->r, oldLight->g, oldLight->b);
light.Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f); light->Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f);
light.Intensity = 1.0f; light->Intensity = 1.0f;
light.In = oldLight->in; light->In = oldLight->in;
light.Out = oldLight->out; light->Out = oldLight->out;
light.Range = oldLight->length; light->Range = oldLight->length;
light.Type = LIGHT_TYPE_SPOT; light->Type = LIGHT_TYPE_SPOT;
r.Lights.push_back(light);
} }
oldLight++; oldLight++;
} }
} }
}
roomVertices.resize(totalRoomsVertices);
roomIndices.resize(totalRoomsIndices);
int baseRoomVertex = 0;
int baseRoomIndex = 0;
for (int i = 0; i < g_Level.Rooms.size(); i++)
{
ROOM_INFO* room = &g_Level.Rooms[i];
RendererRoom* r = &m_rooms[i];
// Merge vertices and indices in a single list // Merge vertices and indices in a single list
for (int j = 0; j < NUM_BUCKETS; j++) for (int j = 0; j < NUM_BUCKETS; j++)
{ {
RendererBucket *bucket = &r.Buckets[j]; RendererBucket *bucket = &r->Buckets[j];
bucket->StartVertex = baseRoomVertex; bucket->StartVertex = baseRoomVertex;
bucket->StartIndex = baseRoomIndex; bucket->StartIndex = baseRoomIndex;
for (int k = 0; k < bucket->Vertices.size(); k++) for (int k = 0; k < bucket->Vertices.size(); k++)
roomVertices.push_back(bucket->Vertices[k]); roomVertices[baseRoomVertex + k] = bucket->Vertices[k];
for (int k = 0; k < bucket->Indices.size(); k++) for (int k = 0; k < bucket->Indices.size(); k++)
roomIndices.push_back(baseRoomVertex + bucket->Indices[k]); roomIndices[baseRoomIndex + k] = baseRoomVertex + bucket->Indices[k];
baseRoomVertex += bucket->Vertices.size(); baseRoomVertex += bucket->Vertices.size();
baseRoomIndex += bucket->Indices.size(); baseRoomIndex += bucket->Indices.size();
@ -314,8 +335,8 @@ namespace T5M::Renderer
// Create a single vertex buffer and a single index buffer for all rooms // Create a single vertex buffer and a single index buffer for all rooms
// NOTICE: in theory, a 1,000,000 vertices scene should have a VB of 52 MB and an IB of 4 MB // NOTICE: in theory, a 1,000,000 vertices scene should have a VB of 52 MB and an IB of 4 MB
m_roomsVertexBuffer = VertexBuffer(m_device, roomVertices.size(), roomVertices.data()); m_roomsVertexBuffer = VertexBuffer(m_device.Get(), roomVertices.size(), roomVertices.data());
m_roomsIndexBuffer = IndexBuffer(m_device, roomIndices.size(), roomIndices.data()); m_roomsIndexBuffer = IndexBuffer(m_device.Get(), roomIndices.size(), roomIndices.data());
m_numHairVertices = 0; m_numHairVertices = 0;
m_numHairIndices = 0; m_numHairIndices = 0;
@ -339,24 +360,6 @@ namespace T5M::Renderer
m_moveableObjects[MoveablesIds[i]] = RendererObject(); m_moveableObjects[MoveablesIds[i]] = RendererObject();
RendererObject &moveable = *m_moveableObjects[MoveablesIds[i]]; RendererObject &moveable = *m_moveableObjects[MoveablesIds[i]];
moveable.Id = MoveablesIds[i]; moveable.Id = MoveablesIds[i];
// Assign the draw routine
/*if (objNum == ID_FLAME || objNum == ID_FLAME_EMITTER || objNum == ID_FLAME_EMITTER2 || objNum == ID_FLAME_EMITTER3 ||
objNum == ID_TRIGGER_TRIGGERER || objNum == ID_TIGHT_ROPE || objNum == ID_AI_AMBUSH ||
objNum == ID_AI_FOLLOW || objNum == ID_AI_GUARD || objNum == ID_AI_MODIFY ||
objNum == ID_AI_PATROL1 || objNum == ID_AI_PATROL2 || objNum == ID_AI_X1 ||
objNum == ID_AI_X2 || objNum == ID_DART_EMITTER || objNum == ID_HOMING_DART_EMITTER ||
objNum == ID_ROPE || objNum == ID_KILL_ALL_TRIGGERS || objNum == ID_EARTHQUAKE ||
objNum == ID_CAMERA_TARGET || objNum == ID_WATERFALLMIST || objNum == ID_SMOKE_EMITTER_BLACK ||
objNum == ID_SMOKE_EMITTER_WHITE)
{
moveable.DoNotDraw = true;
}
else
{
moveable.DoNotDraw = false;
}*/
moveable.DoNotDraw = (obj->drawRoutine == NULL); moveable.DoNotDraw = (obj->drawRoutine == NULL);
for (int j = 0; j < obj->nmeshes; j++) for (int j = 0; j < obj->nmeshes; j++)
@ -644,8 +647,8 @@ namespace T5M::Renderer
} }
// Create a single vertex buffer and a single index buffer for all moveables // Create a single vertex buffer and a single index buffer for all moveables
m_moveablesVertexBuffer = VertexBuffer(m_device, moveablesVertices.size(), moveablesVertices.data()); m_moveablesVertexBuffer = VertexBuffer(m_device.Get(), moveablesVertices.size(), moveablesVertices.data());
m_moveablesIndexBuffer = IndexBuffer(m_device, moveablesIndices.size(), moveablesIndices.data()); m_moveablesIndexBuffer = IndexBuffer(m_device.Get(), moveablesIndices.size(), moveablesIndices.data());
// Step 4: prepare static meshes // Step 4: prepare static meshes
vector<RendererVertex> staticsVertices; vector<RendererVertex> staticsVertices;
@ -688,8 +691,8 @@ namespace T5M::Renderer
} }
// Create a single vertex buffer and a single index buffer for all statics // Create a single vertex buffer and a single index buffer for all statics
m_staticsVertexBuffer = VertexBuffer(m_device, staticsVertices.size(), staticsVertices.data()); m_staticsVertexBuffer = VertexBuffer(m_device.Get(), staticsVertices.size(), staticsVertices.data());
m_staticsIndexBuffer = IndexBuffer(m_device, staticsIndices.size(), staticsIndices.data()); m_staticsIndexBuffer = IndexBuffer(m_device.Get(), staticsIndices.size(), staticsIndices.data());
// Step 5: prepare sprites // Step 5: prepare sprites
m_sprites.resize(g_Level.Sprites.size()); m_sprites.resize(g_Level.Sprites.size());

View file

@ -14,7 +14,7 @@ namespace T5M::Renderer {
_vsprintf_l(buffer, message, NULL, args); _vsprintf_l(buffer, message, NULL, args);
va_end(args); va_end(args);
PrintString(10, m_currentY, buffer, 0xFFFFFFFF, PRINTSTRING_OUTLINE); drawString(10, m_currentY, buffer, 0xFFFFFFFF, PRINTSTRING_OUTLINE);
m_currentY += 20; m_currentY += 20;
} }

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,8 @@ T5M::Renderer::RendererHUDBar* g_MusicVolumeBar;
T5M::Renderer::RendererHUDBar* g_SFXVolumeBar; T5M::Renderer::RendererHUDBar* g_SFXVolumeBar;
namespace T5M::Renderer { namespace T5M::Renderer {
bool Renderer11::initialiseBars() { void Renderer11::initialiseBars()
{
std::array<Vector4, 9> healthColors = { std::array<Vector4, 9> healthColors = {
//top //top
Vector4(82 / 255.0f,0,0,1), Vector4(82 / 255.0f,0,0,1),
@ -68,28 +69,27 @@ namespace T5M::Renderer {
Vector4(0.18f,0.3f,0.72f,1), Vector4(0.18f,0.3f,0.72f,1),
Vector4(0.18f,0.3f,0.72f,1), Vector4(0.18f,0.3f,0.72f,1),
}; };
g_HealthBar = new RendererHUDBar(m_device, 20, 32, 150, 8, 1, healthColors); g_HealthBar = new RendererHUDBar(m_device.Get(), 20, 32, 150, 8, 1, healthColors);
g_AirBar = new RendererHUDBar(m_device, 630, 32, 150, 8, 1, airColors); g_AirBar = new RendererHUDBar(m_device.Get(), 630, 32, 150, 8, 1, airColors);
g_DashBar = new RendererHUDBar(m_device, 630, 32 + 8 + 4, 150, 8, 1, dashColors); g_DashBar = new RendererHUDBar(m_device.Get(), 630, 32 + 8 + 4, 150, 8, 1, dashColors);
g_MusicVolumeBar = new RendererHUDBar(m_device, 400, 212, 150, 8, 1, soundSettingColors); g_MusicVolumeBar = new RendererHUDBar(m_device.Get(), 400, 212, 150, 8, 1, soundSettingColors);
g_SFXVolumeBar = new RendererHUDBar(m_device, 400, 230, 150, 8, 1, soundSettingColors); g_SFXVolumeBar = new RendererHUDBar(m_device.Get(), 400, 230, 150, 8, 1, soundSettingColors);
return true;
} }
bool Renderer11::DrawBar(float percent, const RendererHUDBar* const bar) { void Renderer11::drawBar(float percent, const RendererHUDBar* const bar) {
UINT strides = sizeof(RendererVertex); UINT strides = sizeof(RendererVertex);
UINT offset = 0; UINT offset = 0;
float color[] = { 0,0,0,1.0f }; float color[] = { 0,0,0,1.0f };
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0.0f, 0xFF); m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0.0f, 0xFF);
m_context->IASetInputLayout(m_inputLayout); m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetVertexBuffers(0, 1, bar->vertexBufferBorder.Buffer.GetAddressOf(), &strides, &offset); m_context->IASetVertexBuffers(0, 1, bar->vertexBufferBorder.Buffer.GetAddressOf(), &strides, &offset);
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetIndexBuffer(bar->indexBufferBorder.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); m_context->IASetIndexBuffer(bar->indexBufferBorder.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
m_context->VSSetConstantBuffers(0, 1, &m_cbHUD); m_context->VSSetConstantBuffers(0, 1, m_cbHUD.get());
m_context->VSSetShader(m_vsHUD, NULL, 0); m_context->VSSetShader(m_vsHUD.Get(), NULL, 0);
m_context->PSSetShaderResources(0, 1, m_HUDBarBorderTexture.ShaderResourceView.GetAddressOf()); m_context->PSSetShaderResources(0, 1, m_HUDBarBorderTexture.ShaderResourceView.GetAddressOf());
ID3D11SamplerState* sampler = m_states->LinearClamp(); ID3D11SamplerState* sampler = m_states->LinearClamp();
m_context->PSSetSamplers(0, 1, &sampler); m_context->PSSetSamplers(0, 1, &sampler);
m_context->PSSetShader(m_psHUDTexture, NULL, 0); m_context->PSSetShader(m_psHUDTexture.Get(), NULL, 0);
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF); m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
m_context->OMSetDepthStencilState(m_states->DepthNone(), NULL); m_context->OMSetDepthStencilState(m_states->DepthNone(), NULL);
m_context->RSSetState(m_states->CullNone()); m_context->RSSetState(m_states->CullNone());
@ -97,26 +97,23 @@ namespace T5M::Renderer {
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0.0f, 0xFF); m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0.0f, 0xFF);
m_context->IASetInputLayout(m_inputLayout); m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetVertexBuffers(0, 1, bar->vertexBuffer.Buffer.GetAddressOf(), &strides, &offset); m_context->IASetVertexBuffers(0, 1, bar->vertexBuffer.Buffer.GetAddressOf(), &strides, &offset);
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetIndexBuffer(bar->indexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); m_context->IASetIndexBuffer(bar->indexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
m_stHUDBar.Percent = percent; m_stHUDBar.Percent = percent;
updateConstantBuffer<CHUDBarBuffer>(m_cbHUDBar, m_stHUDBar); m_cbHUDBar.updateData(m_stHUDBar, m_context.Get());
m_context->VSSetConstantBuffers(0, 1, &m_cbHUD); m_context->VSSetConstantBuffers(0, 1, m_cbHUD.get());
m_context->PSSetConstantBuffers(0, 1, &m_cbHUDBar); m_context->PSSetConstantBuffers(0, 1, m_cbHUDBar.get());
m_context->VSSetShader(m_vsHUD, NULL, 0); m_context->VSSetShader(m_vsHUD.Get(), NULL, 0);
m_context->PSSetShader(m_psHUDBarColor, NULL, 0); m_context->PSSetShader(m_psHUDBarColor.Get(), NULL, 0);
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF); m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
m_context->OMSetDepthStencilState(m_states->DepthNone(), NULL); m_context->OMSetDepthStencilState(m_states->DepthNone(), NULL);
m_context->RSSetState(m_states->CullNone()); m_context->RSSetState(m_states->CullNone());
m_context->DrawIndexed(24, 0, 0); m_context->DrawIndexed(24, 0, 0);
return true;
} }
void Renderer11::AddLine2D(int x1, int y1, int x2, int y2, byte r, byte g, byte b, byte a) { void Renderer11::addLine2D(int x1, int y1, int x2, int y2, byte r, byte g, byte b, byte a) {
RendererLine2D* line = &m_lines2DBuffer[m_nextLine2D++]; RendererLine2D* line = &m_lines2DBuffer[m_nextLine2D++];
line->Vertices[0] = Vector2(x1, y1); line->Vertices[0] = Vector2(x1, y1);
@ -126,9 +123,10 @@ namespace T5M::Renderer {
m_lines2DToDraw.push_back(line); m_lines2DToDraw.push_back(line);
} }
bool Renderer11::drawOverlays() { void Renderer11::drawOverlays()
{
if (!BinocularRange && !SpotcamOverlay) if (!BinocularRange && !SpotcamOverlay)
return true; return;
m_context->OMSetBlendState(m_states->AlphaBlend(), NULL, 0xFFFFFFFF); m_context->OMSetBlendState(m_states->AlphaBlend(), NULL, 0xFFFFFFFF);
drawFullScreenQuad(m_binocularsTexture.ShaderResourceView.Get(), Vector3::One, false); drawFullScreenQuad(m_binocularsTexture.ShaderResourceView.Get(), Vector3::One, false);
@ -166,21 +164,19 @@ namespace T5M::Renderer {
vertices[3].UV.y = 1.0f; vertices[3].UV.y = 1.0f;
vertices[3].Color = Vector4(1.0f, 0.0f, 0.0f, 1.0f); vertices[3].Color = Vector4(1.0f, 0.0f, 0.0f, 1.0f);
m_context->VSSetShader(m_vsFullScreenQuad, NULL, 0); m_context->VSSetShader(m_vsFullScreenQuad.Get(), NULL, 0);
m_context->PSSetShader(m_psFullScreenQuad, NULL, 0); m_context->PSSetShader(m_psFullScreenQuad.Get(), NULL, 0);
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetInputLayout(m_inputLayout); m_context->IASetInputLayout(m_inputLayout.Get());
m_primitiveBatch->Begin(); m_primitiveBatch->Begin();
m_primitiveBatch->DrawQuad(vertices[0], vertices[1], vertices[2], vertices[3]); m_primitiveBatch->DrawQuad(vertices[0], vertices[1], vertices[2], vertices[3]);
m_primitiveBatch->End(); m_primitiveBatch->End();
} }
return true;
} }
bool Renderer11::drawColoredQuad(int x, int y, int w, int h, Vector4 color) { void Renderer11::drawColoredQuad(int x, int y, int w, int h, DirectX::SimpleMath::Vector4 color) {
float factorW = ScreenWidth / 800.0f; float factorW = ScreenWidth / 800.0f;
float factorH = ScreenHeight / 600.0f; float factorH = ScreenHeight / 600.0f;
@ -197,14 +193,13 @@ namespace T5M::Renderer {
int shiftW = 4 * factorW; int shiftW = 4 * factorW;
int shiftH = 4 * factorH; int shiftH = 4 * factorH;
AddLine2D(rect.left + shiftW, rect.top + shiftH, rect.right - shiftW, rect.top + shiftH, 128, 128, 128, 128); addLine2D(rect.left + shiftW, rect.top + shiftH, rect.right - shiftW, rect.top + shiftH, 128, 128, 128, 128);
AddLine2D(rect.right - shiftW, rect.top + shiftH, rect.right - shiftW, rect.bottom - shiftH, 128, 128, 128, 128); addLine2D(rect.right - shiftW, rect.top + shiftH, rect.right - shiftW, rect.bottom - shiftH, 128, 128, 128, 128);
AddLine2D(rect.left + shiftW, rect.bottom - shiftH, rect.right - shiftW, rect.bottom - shiftH, 128, 128, 128, 128); addLine2D(rect.left + shiftW, rect.bottom - shiftH, rect.right - shiftW, rect.bottom - shiftH, 128, 128, 128, 128);
AddLine2D(rect.left + shiftW, rect.top + shiftH, rect.left + shiftW, rect.bottom - shiftH, 128, 128, 128, 128); addLine2D(rect.left + shiftW, rect.top + shiftH, rect.left + shiftW, rect.bottom - shiftH, 128, 128, 128, 128);
m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0); m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0);
return true;
} }
} }

View file

@ -36,7 +36,7 @@ namespace T5M::Renderer {
void Renderer11::AddSprite3D(RendererSprite* sprite, Vector3 vtx1, Vector3 vtx2, Vector3 vtx3, Vector3 vtx4, Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode) { void Renderer11::addSprite3D(RendererSprite* sprite, Vector3 vtx1, Vector3 vtx2, Vector3 vtx3, Vector3 vtx4, Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode) {
if (m_nextSprite >= MAX_SPRITES) if (m_nextSprite >= MAX_SPRITES)
return; return;
@ -119,7 +119,7 @@ namespace T5M::Renderer {
Vector3 d = pos2 - pos1; Vector3 d = pos2 - pos1;
d.Normalize(); d.Normalize();
AddSpriteBillboardConstrained(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LIGHTHING], addSpriteBillboardConstrained(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LIGHTHING],
c, c,
Vector4(arc->r / 255.0f, arc->g / 255.0f, arc->b / 255.0f, alpha), Vector4(arc->r / 255.0f, arc->g / 255.0f, arc->b / 255.0f, alpha),
SPRITE_ROTATION_90_DEGREES, SPRITE_ROTATION_90_DEGREES,
@ -138,7 +138,7 @@ namespace T5M::Renderer {
SMOKE_SPARKS* spark = &SmokeSparks[i]; SMOKE_SPARKS* spark = &SmokeSparks[i];
if (spark->on) { if (spark->on) {
AddSpriteBillboard(&m_sprites[spark->def], addSpriteBillboard(&m_sprites[spark->def],
Vector3(spark->x, spark->y, spark->z), Vector3(spark->x, spark->y, spark->z),
Vector4(spark->shade / 255.0f, spark->shade / 255.0f, spark->shade / 255.0f, 1.0f), Vector4(spark->shade / 255.0f, spark->shade / 255.0f, spark->shade / 255.0f, 1.0f),
TO_RAD(spark->rotAng), spark->scalar, spark->size * 4.0f, spark->size * 4.0f, TO_RAD(spark->rotAng), spark->scalar, spark->size * 4.0f, spark->size * 4.0f,
@ -147,7 +147,7 @@ namespace T5M::Renderer {
} }
} }
void Renderer11::AddSpriteBillboard(RendererSprite* sprite, Vector3 pos, Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode) { void Renderer11::addSpriteBillboard(RendererSprite* sprite, Vector3 pos, Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode) {
if (m_nextSprite >= MAX_SPRITES) if (m_nextSprite >= MAX_SPRITES)
return; return;
@ -171,7 +171,7 @@ namespace T5M::Renderer {
m_spritesToDraw.push_back(spr); m_spritesToDraw.push_back(spr);
} }
void Renderer11::AddSpriteBillboardConstrained(RendererSprite* sprite, Vector3 pos, Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode, Vector3 constrainAxis) { void Renderer11::addSpriteBillboardConstrained(RendererSprite* sprite, Vector3 pos, Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode, Vector3 constrainAxis) {
if (m_nextSprite >= MAX_SPRITES) if (m_nextSprite >= MAX_SPRITES)
return; return;
@ -196,7 +196,7 @@ namespace T5M::Renderer {
m_spritesToDraw.push_back(spr); m_spritesToDraw.push_back(spr);
} }
void Renderer11::AddSpriteBillboardConstrainedLookAt(RendererSprite* sprite, DirectX::SimpleMath::Vector3 pos, DirectX::SimpleMath::Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode, DirectX::SimpleMath::Vector3 lookAtAxis) { void Renderer11::addSpriteBillboardConstrainedLookAt(RendererSprite* sprite, DirectX::SimpleMath::Vector3 pos, DirectX::SimpleMath::Vector4 color, float rotation, float scale, float width, float height, BLEND_MODES blendMode, DirectX::SimpleMath::Vector3 lookAtAxis) {
if (m_nextSprite >= MAX_SPRITES) if (m_nextSprite >= MAX_SPRITES)
return; return;
@ -227,7 +227,7 @@ namespace T5M::Renderer {
for (int i = 0; i < MAX_SPARKS_FIRE; i++) { for (int i = 0; i < MAX_SPARKS_FIRE; i++) {
FIRE_SPARKS* spark = &FireSparks[i]; FIRE_SPARKS* spark = &FireSparks[i];
if (spark->on) if (spark->on)
AddSpriteBillboard(&m_sprites[spark->def], Vector3(fire->x + spark->x, fire->y + spark->y, fire->z + spark->z), Vector4(spark->r / 255.0f, spark->g / 255.0f, spark->b / 255.0f, 1.0f), TO_RAD(spark->rotAng), spark->scalar, spark->size * 4.0f, spark->size * 4.0f, BLENDMODE_ALPHABLEND); addSpriteBillboard(&m_sprites[spark->def], Vector3(fire->x + spark->x, fire->y + spark->y, fire->z + spark->z), Vector4(spark->r / 255.0f, spark->g / 255.0f, spark->b / 255.0f, 1.0f), TO_RAD(spark->rotAng), spark->scalar, spark->size * 4.0f, spark->size * 4.0f, BLENDMODE_ALPHABLEND);
} }
} }
} }
@ -305,7 +305,7 @@ namespace T5M::Renderer {
} }
} }
AddSpriteBillboard(&m_sprites[spark->def], addSpriteBillboard(&m_sprites[spark->def],
pos, pos,
Vector4(spark->r / 255.0f, spark->g / 255.0f, spark->b / 255.0f, 1.0f), Vector4(spark->r / 255.0f, spark->g / 255.0f, spark->b / 255.0f, 1.0f),
TO_RAD(spark->rotAng), spark->scalar, spark->size, spark->size, TO_RAD(spark->rotAng), spark->scalar, spark->size, spark->size,
@ -316,7 +316,7 @@ namespace T5M::Renderer {
v.Normalize(); v.Normalize();
//AddSpriteBillboardConstrained(m_sprites[Objects[ID_SPARK_SPRITE].meshIndex], pos, Vector4(spark->r / 255.0f, spark->g / 255.0f, spark->b / 255.0f, 1.0f), TO_RAD(spark->rotAng), spark->scalar, spark., spark->size, BLENDMODE_ALPHABLEND, v); //AddSpriteBillboardConstrained(m_sprites[Objects[ID_SPARK_SPRITE].meshIndex], pos, Vector4(spark->r / 255.0f, spark->g / 255.0f, spark->b / 255.0f, 1.0f), TO_RAD(spark->rotAng), spark->scalar, spark., spark->size, BLENDMODE_ALPHABLEND, v);
AddLine3D(Vector3(spark->x, spark->y, spark->z), Vector3(spark->x + v.x * 24.0f, spark->y + v.y * 24.0f, spark->z + v.z * 24.0f), Vector4(spark->r / 255.0f, spark->g / 255.0f, spark->b / 255.0f, 1.0f)); addLine3D(Vector3(spark->x, spark->y, spark->z), Vector3(spark->x + v.x * 24.0f, spark->y + v.y * 24.0f, spark->z + v.z * 24.0f), Vector4(spark->r / 255.0f, spark->g / 255.0f, spark->b / 255.0f, 1.0f));
} }
} }
} }
@ -365,7 +365,7 @@ namespace T5M::Renderer {
x2Outer += splash.x; x2Outer += splash.x;
z2Outer = outerRadius * cos(alpha * j * PI / 180); z2Outer = outerRadius * cos(alpha * j * PI / 180);
z2Outer += splash.z; z2Outer += splash.z;
AddSprite3D(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + splash.spriteSequenceStart + (int)splash.animationPhase], Vector3(xOuter, yOuter, zOuter), Vector3(x2Outer, yOuter, z2Outer), Vector3(x2Inner, yInner, z2Inner), Vector3(xInner, yInner, zInner), Vector4(color / 255.0f, color / 255.0f, color / 255.0f, 1.0f), 0, 1, 0, 0, BLENDMODE_ALPHABLEND); addSprite3D(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + splash.spriteSequenceStart + (int)splash.animationPhase], Vector3(xOuter, yOuter, zOuter), Vector3(x2Outer, yOuter, z2Outer), Vector3(x2Inner, yInner, z2Inner), Vector3(xInner, yInner, zInner), Vector4(color / 255.0f, color / 255.0f, color / 255.0f, 1.0f), 0, 1, 0, 0, BLENDMODE_ALPHABLEND);
} }
} }
} }
@ -375,7 +375,7 @@ namespace T5M::Renderer {
for (int i = 0; i < MAX_BUBBLES; i++) { for (int i = 0; i < MAX_BUBBLES; i++) {
BUBBLE_STRUCT* bubble = &Bubbles[i]; BUBBLE_STRUCT* bubble = &Bubbles[i];
if (bubble->active) if (bubble->active)
AddSpriteBillboard(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + bubble->spriteNum], Vector3(bubble->worldPosition.x, bubble->worldPosition.y, bubble->worldPosition.z), bubble->color, bubble->rotation, 1.0f, bubble->size * 0.5f, bubble->size * 0.5f, BLENDMODE_ALPHABLEND); addSpriteBillboard(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + bubble->spriteNum], Vector3(bubble->worldPosition.x, bubble->worldPosition.y, bubble->worldPosition.z), bubble->color, bubble->rotation, 1.0f, bubble->size * 0.5f, bubble->size * 0.5f, BLENDMODE_ALPHABLEND);
} }
} }
@ -384,7 +384,7 @@ namespace T5M::Renderer {
DRIP_STRUCT* drip = &Drips[i]; DRIP_STRUCT* drip = &Drips[i];
if (drip->on) { if (drip->on) {
AddLine3D(Vector3(drip->x, drip->y, drip->z), Vector3(drip->x, drip->y + 24.0f, drip->z), Vector4(drip->r / 255.0f, drip->g / 255.0f, drip->b / 255.0f, 1.0f)); addLine3D(Vector3(drip->x, drip->y, drip->z), Vector3(drip->x, drip->y + 24.0f, drip->z), Vector4(drip->r / 255.0f, drip->g / 255.0f, drip->b / 255.0f, 1.0f));
} }
} }
} }
@ -396,9 +396,9 @@ namespace T5M::Renderer {
if (ripple->active) { if (ripple->active) {
float y = ripple->worldPos.y; float y = ripple->worldPos.y;
if (ripple->isBillboard) { if (ripple->isBillboard) {
AddSpriteBillboard(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + ripple->SpriteID], ripple->worldPos, ripple->currentColor, ripple->rotation, 1, ripple->size, ripple->size, BLENDMODE_ALPHABLEND); addSpriteBillboard(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + ripple->SpriteID], ripple->worldPos, ripple->currentColor, ripple->rotation, 1, ripple->size, ripple->size, BLENDMODE_ALPHABLEND);
} else { } else {
AddSpriteBillboardConstrainedLookAt(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + ripple->SpriteID], ripple->worldPos, ripple->currentColor, ripple->rotation, 1, ripple->size*2, ripple->size*2, BLENDMODE_ALPHABLEND, Vector3(0,-1,0)); addSpriteBillboardConstrainedLookAt(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + ripple->SpriteID], ripple->worldPos, ripple->currentColor, ripple->rotation, 1, ripple->size*2, ripple->size*2, BLENDMODE_ALPHABLEND, Vector3(0,-1,0));
//AddSprite3D(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + ripple->SpriteID], Vector3(x1, y, z2), Vector3(x2, y, z2), Vector3(x2, y, z1), Vector3(x1, y, z1), ripple->currentColor, 0.0f, 1.0f, ripple->size, ripple->size, BLENDMODE_ALPHABLEND); //AddSprite3D(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + ripple->SpriteID], Vector3(x1, y, z2), Vector3(x2, y, z2), Vector3(x2, y, z1), Vector3(x1, y, z1), ripple->currentColor, 0.0f, 1.0f, ripple->size, ripple->size, BLENDMODE_ALPHABLEND);
} }
} }
@ -447,15 +447,15 @@ namespace T5M::Renderer {
p2 = Vector3::Transform(p2, rotationMatrix); p2 = Vector3::Transform(p2, rotationMatrix);
p3 = Vector3::Transform(p3, rotationMatrix); p3 = Vector3::Transform(p3, rotationMatrix);
AddSprite3D(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_SPLASH], addSprite3D(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_SPLASH],
pos + p1, pos + p1,
pos + p2, pos + p2,
pos + p3, pos + p3,
pos + p4, pos + p4,
Vector4( Vector4(
shockwave->r * shockwave->life / 255.0f / 64.0f, shockwave->r * shockwave->life / 255.0f / 16.0f,
shockwave->g * shockwave->life / 255.0f / 64.0f, shockwave->g * shockwave->life / 255.0f / 16.0f,
shockwave->b * shockwave->life / 255.0f / 64.0f, shockwave->b * shockwave->life / 255.0f / 16.0f,
1.0f), 1.0f),
0, 1, 0, 0, BLENDMODE_ALPHABLEND); 0, 1, 0, 0, BLENDMODE_ALPHABLEND);
@ -471,7 +471,7 @@ namespace T5M::Renderer {
BLOOD_STRUCT* blood = &Blood[i]; BLOOD_STRUCT* blood = &Blood[i];
if (blood->on) { if (blood->on) {
AddSpriteBillboard(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_BLOOD], addSpriteBillboard(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_BLOOD],
Vector3(blood->x, blood->y, blood->z), Vector3(blood->x, blood->y, blood->z),
Vector4(blood->shade / 255.0f, blood->shade * 0, blood->shade * 0, 1.0f), Vector4(blood->shade / 255.0f, blood->shade * 0, blood->shade * 0, 1.0f),
TO_RAD(blood->rotAng), 1.0f, blood->size * 8.0f, blood->size * 8.0f, TO_RAD(blood->rotAng), 1.0f, blood->size * 8.0f, blood->size * 8.0f,
@ -501,12 +501,12 @@ namespace T5M::Renderer {
m_stLights.NumLights = item->Lights.size(); m_stLights.NumLights = item->Lights.size();
for (int j = 0; j < item->Lights.size(); j++) for (int j = 0; j < item->Lights.size(); j++)
memcpy(&m_stLights.Lights[j], item->Lights[j], sizeof(ShaderLight)); memcpy(&m_stLights.Lights[j], item->Lights[j], sizeof(ShaderLight));
updateConstantBuffer<CLightBuffer>(m_cbLights, m_stLights); m_cbLights.updateData(m_stLights, m_context.Get());
m_context->PSSetConstantBuffers(2, 1, &m_cbLights); m_context->PSSetConstantBuffers(2, 1, m_cbLights.get());
m_stMisc.AlphaTest = true; m_stMisc.AlphaTest = true;
updateConstantBuffer<CMiscBuffer>(m_cbMisc, m_stMisc); m_cbMisc.updateData(m_stMisc, m_context.Get());
m_context->PSSetConstantBuffers(3, 1, &m_cbMisc); m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
short length = 0; short length = 0;
short zOffset = 0; short zOffset = 0;
@ -556,8 +556,8 @@ namespace T5M::Renderer {
world = rotation2 * world; world = rotation2 * world;
m_stItem.World = world; m_stItem.World = world;
updateConstantBuffer<CItemBuffer>(m_cbItem, m_stItem); m_cbItem.updateData(m_stItem, m_context.Get());
m_context->VSSetConstantBuffers(1, 1, &m_cbItem); m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
m_context->DrawIndexed(flashBucket->Indices.size(), flashBucket->StartIndex, 0); m_context->DrawIndexed(flashBucket->Indices.size(), flashBucket->StartIndex, 0);
m_numDrawCalls++; m_numDrawCalls++;
@ -569,8 +569,8 @@ namespace T5M::Renderer {
world = rotation2 * world; world = rotation2 * world;
m_stItem.World = world; m_stItem.World = world;
updateConstantBuffer<CItemBuffer>(m_cbItem, m_stItem); m_cbItem.updateData(m_stItem, m_context.Get());
m_context->VSSetConstantBuffers(1, 1, &m_cbItem); m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
m_context->DrawIndexed(flashBucket->Indices.size(), flashBucket->StartIndex, 0); m_context->DrawIndexed(flashBucket->Indices.size(), flashBucket->StartIndex, 0);
m_numDrawCalls++; m_numDrawCalls++;
@ -585,7 +585,8 @@ namespace T5M::Renderer {
return true; return true;
} }
bool Renderer11::drawBaddieGunflashes() { void Renderer11::drawBaddieGunflashes()
{
rand(); rand();
rand(); rand();
rand(); rand();
@ -608,12 +609,12 @@ namespace T5M::Renderer {
m_stLights.NumLights = item->Lights.size(); m_stLights.NumLights = item->Lights.size();
for (int j = 0; j < item->Lights.size(); j++) for (int j = 0; j < item->Lights.size(); j++)
memcpy(&m_stLights.Lights[j], item->Lights[j], sizeof(ShaderLight)); memcpy(&m_stLights.Lights[j], item->Lights[j], sizeof(ShaderLight));
updateConstantBuffer<CLightBuffer>(m_cbLights, m_stLights); m_cbLights.updateData(m_stLights, m_context.Get());
m_context->PSSetConstantBuffers(2, 1, &m_cbLights); m_context->PSSetConstantBuffers(2, 1, m_cbLights.get());
m_stMisc.AlphaTest = true; m_stMisc.AlphaTest = true;
updateConstantBuffer<CMiscBuffer>(m_cbMisc, m_stMisc); m_cbMisc.updateData(m_stMisc, m_context.Get());
m_context->PSSetConstantBuffers(3, 1, &m_cbMisc); m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF); m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF);
m_context->OMSetDepthStencilState(m_states->DepthRead(), 0); m_context->OMSetDepthStencilState(m_states->DepthRead(), 0);
@ -644,8 +645,8 @@ namespace T5M::Renderer {
world = rotationZ * world; world = rotationZ * world;
m_stItem.World = world; m_stItem.World = world;
updateConstantBuffer<CItemBuffer>(m_cbItem, m_stItem); m_cbItem.updateData(m_stItem, m_context.Get());
m_context->VSSetConstantBuffers(1, 1, &m_cbItem); m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
m_context->DrawIndexed(flashBucket->Indices.size(), flashBucket->StartIndex, 0); m_context->DrawIndexed(flashBucket->Indices.size(), flashBucket->StartIndex, 0);
m_numDrawCalls++; m_numDrawCalls++;
@ -657,12 +658,11 @@ namespace T5M::Renderer {
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF); m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0); m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0);
return true;
} }
Texture2D Renderer11::CreateDefaultNormalTexture() { Texture2D Renderer11::createDefaultNormalTexture() {
vector<byte> data = {128,128,255,1}; vector<byte> data = {128,128,255,1};
return Texture2D(m_device,1,1,data.data()); return Texture2D(m_device.Get(),1,1,data.data());
} }
void Renderer11::drawFootprints() { void Renderer11::drawFootprints() {
@ -684,7 +684,7 @@ namespace T5M::Renderer {
p2 += Vector3(footprint.pos.xPos, footprint.pos.yPos, footprint.pos.zPos); p2 += Vector3(footprint.pos.xPos, footprint.pos.yPos, footprint.pos.zPos);
p3 += Vector3(footprint.pos.xPos, footprint.pos.yPos, footprint.pos.zPos); p3 += Vector3(footprint.pos.xPos, footprint.pos.yPos, footprint.pos.zPos);
p4 += Vector3(footprint.pos.xPos, footprint.pos.yPos, footprint.pos.zPos); p4 += Vector3(footprint.pos.xPos, footprint.pos.yPos, footprint.pos.zPos);
AddSprite3D(&m_sprites[spriteIndex], p1, p2, p3, p4, Vector4(footprint.opacity / 255.0f, footprint.opacity / 255.0f, footprint.opacity / 255.0f, footprint.opacity / 255.0f), 0, 1, 1, 1, BLENDMODE_SUBTRACTIVE); addSprite3D(&m_sprites[spriteIndex], p1, p2, p3, p4, Vector4(footprint.opacity / 255.0f, footprint.opacity / 255.0f, footprint.opacity / 255.0f, footprint.opacity / 255.0f), 0, 1, 1, 1, BLENDMODE_SUBTRACTIVE);
} }
} }
} }
@ -723,7 +723,7 @@ namespace T5M::Renderer {
dust->Life++; dust->Life++;
byte color = (dust->Life > 16 ? 32 - dust->Life : dust->Life) * 4; byte color = (dust->Life > 16 ? 32 - dust->Life : dust->Life) * 4;
AddSpriteBillboard(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST], Vector3(dust->X, dust->Y, dust->Z), Vector4(color / 255.0f, color / 255.0f, color / 255.0f, 1.0f), 0.0f, 1.0f, 12, 12, BLENDMODE_ALPHABLEND); addSpriteBillboard(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST], Vector3(dust->X, dust->Y, dust->Z), Vector4(color / 255.0f, color / 255.0f, color / 255.0f, 1.0f), 0.0f, 1.0f, 12, 12, BLENDMODE_ALPHABLEND);
if (dust->Life >= 32) if (dust->Life >= 32)
dust->Reset = true; dust->Reset = true;
@ -734,21 +734,22 @@ namespace T5M::Renderer {
return; return;
} }
bool Renderer11::drawSprites() { void Renderer11::drawSprites()
{
UINT stride = sizeof(RendererVertex); UINT stride = sizeof(RendererVertex);
UINT offset = 0; UINT offset = 0;
m_context->RSSetState(m_states->CullNone()); m_context->RSSetState(m_states->CullNone());
m_context->OMSetDepthStencilState(m_states->DepthRead(), 0); m_context->OMSetDepthStencilState(m_states->DepthRead(), 0);
m_context->VSSetShader(m_vsSprites, NULL, 0); m_context->VSSetShader(m_vsSprites.Get(), NULL, 0);
m_context->PSSetShader(m_psSprites, NULL, 0); m_context->PSSetShader(m_psSprites.Get(), NULL, 0);
m_stMisc.AlphaTest = true; m_stMisc.AlphaTest = true;
updateConstantBuffer<CMiscBuffer>(m_cbMisc, m_stMisc); m_cbMisc.updateData(m_stMisc, m_context.Get());
m_context->PSSetConstantBuffers(3, 1, &m_cbMisc); m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
m_context->IASetInputLayout(m_inputLayout); m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetVertexBuffers(0, 1, quadVertexBuffer.GetAddressOf(), &stride, &offset); m_context->IASetVertexBuffers(0, 1, quadVertexBuffer.GetAddressOf(), &stride, &offset);
for (int b = 0; b < 4; b++) { for (int b = 0; b < 4; b++) {
BLEND_MODES currentBlendMode = (BLEND_MODES)b; BLEND_MODES currentBlendMode = (BLEND_MODES)b;
@ -768,7 +769,7 @@ namespace T5M::Renderer {
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF); m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
break; break;
case BLENDMODE_SUBTRACTIVE: case BLENDMODE_SUBTRACTIVE:
m_context->OMSetBlendState(m_subtractiveBlendState, NULL, 0xFFFFFFFF); m_context->OMSetBlendState(m_subtractiveBlendState.Get(), NULL, 0xFFFFFFFF);
break; break;
} }
@ -792,8 +793,8 @@ namespace T5M::Renderer {
m_stSprite.billboardMatrix = billboardMatrix; m_stSprite.billboardMatrix = billboardMatrix;
m_stSprite.color = spr->color; m_stSprite.color = spr->color;
m_stSprite.isBillboard = true; m_stSprite.isBillboard = true;
updateConstantBuffer<CSpriteBuffer>(m_cbSprite, m_stSprite); m_cbSprite.updateData(m_stSprite, m_context.Get());
m_context->VSSetConstantBuffers(4, 1, &m_cbSprite); m_context->VSSetConstantBuffers(4, 1, m_cbSprite.get());
m_context->Draw(4, 0); m_context->Draw(4, 0);
} else if (spr->Type == RENDERER_SPRITE_TYPE::SPRITE_TYPE_BILLBOARD_CUSTOM) { } else if (spr->Type == RENDERER_SPRITE_TYPE::SPRITE_TYPE_BILLBOARD_CUSTOM) {
Matrix rotation = Matrix::CreateRotationZ(spr->Rotation); Matrix rotation = Matrix::CreateRotationZ(spr->Rotation);
@ -808,8 +809,8 @@ namespace T5M::Renderer {
m_stSprite.billboardMatrix = billboardMatrix; m_stSprite.billboardMatrix = billboardMatrix;
m_stSprite.color = spr->color; m_stSprite.color = spr->color;
m_stSprite.isBillboard = true; m_stSprite.isBillboard = true;
updateConstantBuffer<CSpriteBuffer>(m_cbSprite, m_stSprite); m_cbSprite.updateData(m_stSprite, m_context.Get());
m_context->VSSetConstantBuffers(4, 1, &m_cbSprite); m_context->VSSetConstantBuffers(4, 1, m_cbSprite.get());
m_context->Draw(4, 0); m_context->Draw(4, 0);
} else if (spr->Type == RENDERER_SPRITE_TYPE::SPRITE_TYPE_BILLBOARD_LOOKAT) { } else if (spr->Type == RENDERER_SPRITE_TYPE::SPRITE_TYPE_BILLBOARD_LOOKAT) {
Matrix translation = Matrix::CreateTranslation(spr->pos); Matrix translation = Matrix::CreateTranslation(spr->pos);
@ -819,8 +820,8 @@ namespace T5M::Renderer {
m_stSprite.billboardMatrix = billboardMatrix; m_stSprite.billboardMatrix = billboardMatrix;
m_stSprite.color = spr->color; m_stSprite.color = spr->color;
m_stSprite.isBillboard = true; m_stSprite.isBillboard = true;
updateConstantBuffer<CSpriteBuffer>(m_cbSprite, m_stSprite); m_cbSprite.updateData(m_stSprite, m_context.Get());
m_context->VSSetConstantBuffers(4, 1, &m_cbSprite); m_context->VSSetConstantBuffers(4, 1, m_cbSprite.get());
m_context->Draw(4, 0); m_context->Draw(4, 0);
}else if (spr->Type == RENDERER_SPRITE_TYPE::SPRITE_TYPE_3D) { }else if (spr->Type == RENDERER_SPRITE_TYPE::SPRITE_TYPE_3D) {
m_primitiveBatch->Begin(); m_primitiveBatch->Begin();
@ -862,8 +863,8 @@ namespace T5M::Renderer {
v3.Color = spr->color; v3.Color = spr->color;
m_stSprite.color = spr->color; m_stSprite.color = spr->color;
m_stSprite.isBillboard = false; m_stSprite.isBillboard = false;
updateConstantBuffer<CSpriteBuffer>(m_cbSprite, m_stSprite); m_cbSprite.updateData(m_stSprite, m_context.Get());
m_context->VSSetConstantBuffers(4, 1, &m_cbSprite); m_context->VSSetConstantBuffers(4, 1, m_cbSprite.get());
m_primitiveBatch->DrawQuad(v0, v1, v2, v3); m_primitiveBatch->DrawQuad(v0, v1, v2, v3);
m_primitiveBatch->End(); m_primitiveBatch->End();
} }
@ -875,10 +876,9 @@ namespace T5M::Renderer {
m_context->RSSetState(m_states->CullCounterClockwise()); m_context->RSSetState(m_states->CullCounterClockwise());
m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0); m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0);
return true;
} }
bool Renderer11::drawEffect(RendererEffect* effect, bool transparent) { void Renderer11::drawEffect(RendererEffect* effect, bool transparent) {
UINT stride = sizeof(RendererVertex); UINT stride = sizeof(RendererVertex);
UINT offset = 0; UINT offset = 0;
@ -893,18 +893,18 @@ namespace T5M::Renderer {
m_stItem.AmbientLight = room.AmbientLight; m_stItem.AmbientLight = room.AmbientLight;
Matrix matrices[1] = { Matrix::Identity }; Matrix matrices[1] = { Matrix::Identity };
memcpy(m_stItem.BonesMatrices, matrices, sizeof(Matrix)); memcpy(m_stItem.BonesMatrices, matrices, sizeof(Matrix));
updateConstantBuffer<CItemBuffer>(m_cbItem, m_stItem); m_cbItem.updateData(m_stItem, m_context.Get());
m_context->VSSetConstantBuffers(1, 1, &m_cbItem); m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
m_stLights.NumLights = effect->Lights.size(); m_stLights.NumLights = effect->Lights.size();
for (int j = 0; j < effect->Lights.size(); j++) for (int j = 0; j < effect->Lights.size(); j++)
memcpy(&m_stLights.Lights[j], effect->Lights[j], sizeof(ShaderLight)); memcpy(&m_stLights.Lights[j], effect->Lights[j], sizeof(ShaderLight));
updateConstantBuffer<CLightBuffer>(m_cbLights, m_stLights); m_cbLights.updateData(m_stLights, m_context.Get());
m_context->PSSetConstantBuffers(2, 1, &m_cbLights); m_context->PSSetConstantBuffers(2, 1, m_cbLights.get());
m_stMisc.AlphaTest = !transparent; m_stMisc.AlphaTest = !transparent;
updateConstantBuffer<CMiscBuffer>(m_cbMisc, m_stMisc); m_cbMisc.updateData(m_stMisc, m_context.Get());
m_context->PSSetConstantBuffers(3, 1, &m_cbMisc); m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
RendererMesh* mesh = effect->Mesh; RendererMesh* mesh = effect->Mesh;
@ -919,10 +919,9 @@ namespace T5M::Renderer {
m_numDrawCalls++; m_numDrawCalls++;
} }
return true;
} }
bool Renderer11::drawEffects(bool transparent) { void Renderer11::drawEffects(bool transparent) {
UINT stride = sizeof(RendererVertex); UINT stride = sizeof(RendererVertex);
UINT offset = 0; UINT offset = 0;
@ -931,7 +930,7 @@ namespace T5M::Renderer {
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetInputLayout(m_inputLayout); m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
for (int i = 0; i < m_effectsToDraw.size(); i++) { for (int i = 0; i < m_effectsToDraw.size(); i++) {
@ -943,10 +942,10 @@ namespace T5M::Renderer {
drawEffect(effect, transparent); drawEffect(effect, transparent);
} }
return true;
} }
bool Renderer11::drawWaterfalls() { void Renderer11::drawWaterfalls()
{
UINT stride = sizeof(RendererVertex); UINT stride = sizeof(RendererVertex);
UINT offset = 0; UINT offset = 0;
@ -967,18 +966,18 @@ namespace T5M::Renderer {
m_stItem.Position = Vector4(item->Item->pos.xPos, item->Item->pos.yPos, item->Item->pos.zPos, 1.0f); m_stItem.Position = Vector4(item->Item->pos.xPos, item->Item->pos.yPos, item->Item->pos.zPos, 1.0f);
m_stItem.AmbientLight = room.AmbientLight; //Vector4::One * 0.1f; // room->AmbientLight; m_stItem.AmbientLight = room.AmbientLight; //Vector4::One * 0.1f; // room->AmbientLight;
memcpy(m_stItem.BonesMatrices, item->AnimationTransforms, sizeof(Matrix) * 32); memcpy(m_stItem.BonesMatrices, item->AnimationTransforms, sizeof(Matrix) * 32);
updateConstantBuffer<CItemBuffer>(m_cbItem, m_stItem); m_cbItem.updateData(m_stItem, m_context.Get());
m_context->VSSetConstantBuffers(1, 1, &m_cbItem); m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
m_stLights.NumLights = item->Lights.size(); m_stLights.NumLights = item->Lights.size();
for (int j = 0; j < item->Lights.size(); j++) for (int j = 0; j < item->Lights.size(); j++)
memcpy(&m_stLights.Lights[j], item->Lights[j], sizeof(ShaderLight)); memcpy(&m_stLights.Lights[j], item->Lights[j], sizeof(ShaderLight));
updateConstantBuffer<CLightBuffer>(m_cbLights, m_stLights); m_cbLights.updateData(m_stLights, m_context.Get());
m_context->PSSetConstantBuffers(2, 1, &m_cbLights); m_context->PSSetConstantBuffers(2, 1, m_cbLights.get());
m_stMisc.AlphaTest = false; m_stMisc.AlphaTest = false;
updateConstantBuffer<CMiscBuffer>(m_cbMisc, m_stMisc); m_cbMisc.updateData(m_stMisc, m_context.Get());
m_context->PSSetConstantBuffers(3, 1, &m_cbMisc); m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
m_primitiveBatch->Begin(); m_primitiveBatch->Begin();
@ -1025,11 +1024,9 @@ namespace T5M::Renderer {
continue; continue;
} }
} }
return true;
} }
bool Renderer11::drawDebris(bool transparent) { void Renderer11::drawDebris(bool transparent) {
/*UINT cPasses = 1; /*UINT cPasses = 1;
// First collect debrises // First collect debrises
@ -1114,16 +1111,16 @@ namespace T5M::Renderer {
m_stCameraMatrices.View = View.Transpose(); m_stCameraMatrices.View = View.Transpose();
m_stCameraMatrices.Projection = Projection.Transpose(); m_stCameraMatrices.Projection = Projection.Transpose();
updateConstantBuffer(m_cbCameraMatrices, &m_stCameraMatrices, sizeof(CCameraMatrixBuffer)); updateConstantBuffer(m_cbCameraMatrices, &m_stCameraMatrices, sizeof(CCameraMatrixBuffer));
m_context->VSSetConstantBuffers(0, 1, &m_cbCameraMatrices); m_context->VSSetConstantBuffers(0, 1, m_cbCameraMatrices);
m_stMisc.AlphaTest = !transparent; m_stMisc.AlphaTest = !transparent;
updateConstantBuffer(m_cbMisc, &m_stMisc, sizeof(CMiscBuffer)); updateConstantBuffer(m_cbMisc, &m_stMisc, sizeof(CMiscBuffer));
m_context->PSSetConstantBuffers(3, 1, &m_cbMisc); m_context->PSSetConstantBuffers(3, 1, m_cbMisc);
m_stStatic.World = Matrix::Identity; m_stStatic.World = Matrix::Identity;
m_stStatic.Color = Vector4::One; m_stStatic.Color = Vector4::One;
updateConstantBuffer(m_cbStatic, &m_stStatic, sizeof(CStaticBuffer)); updateConstantBuffer(m_cbStatic, &m_stStatic, sizeof(CStaticBuffer));
m_context->VSSetConstantBuffers(1, 1, &m_cbStatic); m_context->VSSetConstantBuffers(1, 1, m_cbStatic);
// Draw vertices // Draw vertices
m_primitiveBatch->Draw(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST, vertices.data(), vertices.size()); m_primitiveBatch->Draw(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST, vertices.data(), vertices.size());
@ -1142,22 +1139,22 @@ namespace T5M::Renderer {
Matrix rotation = Matrix::CreateFromQuaternion(deb->rotation); Matrix rotation = Matrix::CreateFromQuaternion(deb->rotation);
Matrix world = rotation * translation; Matrix world = rotation * translation;
m_primitiveBatch->Begin(); m_primitiveBatch->Begin();
m_context->VSSetShader(m_vsStatics, NULL, 0); m_context->VSSetShader(m_vsStatics.Get(), NULL, 0);
m_context->PSSetShader(m_psStatics, NULL, 0); m_context->PSSetShader(m_psStatics.Get(), NULL, 0);
m_context->PSSetShaderResources(0, 1, (std::get<0>(m_staticsTextures[0])).ShaderResourceView.GetAddressOf()); m_context->PSSetShaderResources(0, 1, (std::get<0>(m_staticsTextures[0])).ShaderResourceView.GetAddressOf());
ID3D11SamplerState* sampler = m_states->AnisotropicClamp(); ID3D11SamplerState* sampler = m_states->AnisotropicClamp();
m_context->PSSetSamplers(0, 1, &sampler); m_context->PSSetSamplers(0, 1, &sampler);
//m_stCameraMatrices.View = View.Transpose(); //m_stCameraMatrices.View = View.Transpose();
//m_stCameraMatrices.Projection = Projection.Transpose(); //m_stCameraMatrices.Projection = Projection.Transpose();
//updateConstantBuffer(m_cbCameraMatrices, &m_stCameraMatrices, sizeof(CCameraMatrixBuffer)); //updateConstantBuffer(m_cbCameraMatrices, &m_stCameraMatrices, sizeof(CCameraMatrixBuffer));
//m_context->VSSetConstantBuffers(0, 1, &m_cbCameraMatrices); //m_context->VSSetConstantBuffers(0, 1, m_cbCameraMatrices);
m_stMisc.AlphaTest = !transparent; m_stMisc.AlphaTest = !transparent;
updateConstantBuffer<CMiscBuffer>(m_cbMisc, m_stMisc); m_cbMisc.updateData(m_stMisc, m_context.Get());
m_context->PSSetConstantBuffers(3, 1, &m_cbMisc); m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
m_stStatic.World = world; m_stStatic.World = world;
m_stStatic.Color = Vector4::One; m_stStatic.Color = Vector4::One;
updateConstantBuffer<CStaticBuffer>(m_cbStatic, m_stStatic); m_cbStatic.updateData(m_stStatic, m_context.Get());
m_context->VSSetConstantBuffers(1, 1, &m_cbStatic); m_context->VSSetConstantBuffers(1, 1, m_cbStatic.get());
RendererVertex vtx0 = deb->mesh.vertices[0]; RendererVertex vtx0 = deb->mesh.vertices[0];
RendererVertex vtx1 = deb->mesh.vertices[1]; RendererVertex vtx1 = deb->mesh.vertices[1];
RendererVertex vtx2 = deb->mesh.vertices[2]; RendererVertex vtx2 = deb->mesh.vertices[2];
@ -1170,21 +1167,21 @@ namespace T5M::Renderer {
m_primitiveBatch->End(); m_primitiveBatch->End();
} }
} }
return true;
} }
bool Renderer11::drawSmokeParticles() { void Renderer11::drawSmokeParticles()
{
using T5M::Effects::Smoke::SmokeParticles; using T5M::Effects::Smoke::SmokeParticles;
using T5M::Effects::Smoke::SmokeParticle; using T5M::Effects::Smoke::SmokeParticle;
for (int i = 0; i < SmokeParticles.size(); i++) { for (int i = 0; i < SmokeParticles.size(); i++) {
SmokeParticle& s = SmokeParticles[i]; SmokeParticle& s = SmokeParticles[i];
if (!s.active) continue; if (!s.active) continue;
AddSpriteBillboard(&m_sprites[Objects[ID_SMOKE_SPRITES].meshIndex + s.sprite], s.position, s.color, s.rotation, 1.0f, s.size, s.size, BLENDMODE_ALPHABLEND); addSpriteBillboard(&m_sprites[Objects[ID_SMOKE_SPRITES].meshIndex + s.sprite], s.position, s.color, s.rotation, 1.0f, s.size, s.size, BLENDMODE_ALPHABLEND);
} }
return true;
} }
bool Renderer11::drawSparkParticles() { void Renderer11::drawSparkParticles()
{
using T5M::Effects::Spark::SparkParticle; using T5M::Effects::Spark::SparkParticle;
using T5M::Effects::Spark::SparkParticles; using T5M::Effects::Spark::SparkParticles;
extern std::array<SparkParticle, 64> SparkParticles; extern std::array<SparkParticle, 64> SparkParticles;
@ -1193,12 +1190,12 @@ namespace T5M::Renderer {
if (!s.active) continue; if (!s.active) continue;
Vector3 v; Vector3 v;
s.velocity.Normalize(v); s.velocity.Normalize(v);
AddSpriteBillboardConstrained(&m_sprites[Objects[ID_SPARK_SPRITE].meshIndex], s.pos, s.color, 0, 1, s.width, s.height, BLENDMODE_ALPHABLEND, v); addSpriteBillboardConstrained(&m_sprites[Objects[ID_SPARK_SPRITE].meshIndex], s.pos, s.color, 0, 1, s.width, s.height, BLENDMODE_ALPHABLEND, v);
} }
return true;
} }
bool Renderer11::drawDripParticles() { void Renderer11::drawDripParticles()
{
using T5M::Effects::Drip::DripParticle; using T5M::Effects::Drip::DripParticle;
using T5M::Effects::Drip::dripParticles; using T5M::Effects::Drip::dripParticles;
using T5M::Effects::Drip::DRIP_WIDTH; using T5M::Effects::Drip::DRIP_WIDTH;
@ -1207,19 +1204,18 @@ namespace T5M::Renderer {
if (!d.active) continue; if (!d.active) continue;
Vector3 v; Vector3 v;
d.velocity.Normalize(v); d.velocity.Normalize(v);
AddSpriteBillboardConstrained(&m_sprites[Objects[ID_DRIP_SPRITE].meshIndex], d.pos, d.color, 0, 1, DRIP_WIDTH, d.height, BLENDMODE_ALPHABLEND, v); addSpriteBillboardConstrained(&m_sprites[Objects[ID_DRIP_SPRITE].meshIndex], d.pos, d.color, 0, 1, DRIP_WIDTH, d.height, BLENDMODE_ALPHABLEND, v);
} }
return true;
} }
bool Renderer11::drawExplosionParticles() { void Renderer11::drawExplosionParticles()
{
using T5M::Effects::Explosion::explosionParticles; using T5M::Effects::Explosion::explosionParticles;
using T5M::Effects::Explosion::ExplosionParticle; using T5M::Effects::Explosion::ExplosionParticle;
for (int i = 0; i < explosionParticles.size(); i++) { for (int i = 0; i < explosionParticles.size(); i++) {
ExplosionParticle& e = explosionParticles[i]; ExplosionParticle& e = explosionParticles[i];
if (!e.active) continue; if (!e.active) continue;
AddSpriteBillboard(&m_sprites[Objects[ID_EXPLOSION_SPRITES].meshIndex + e.sprite], e.pos, e.tint, e.rotation, 1.0f, e.size, e.size, BLENDMODE_ALPHABLEND); addSpriteBillboard(&m_sprites[Objects[ID_EXPLOSION_SPRITES].meshIndex + e.sprite], e.pos, e.tint, e.rotation, 1.0f, e.size, e.size, BLENDMODE_ALPHABLEND);
} }
return true;
} }
} }

View file

@ -465,7 +465,7 @@ namespace T5M::Renderer
} }
} }
void Renderer11::ResetAnimations() void Renderer11::resetAnimations()
{ {
for (int i = 0; i < NUM_ITEMS; i++) for (int i = 0; i < NUM_ITEMS; i++)
{ {

View file

@ -4,29 +4,29 @@
#include "winmain.h" #include "winmain.h"
#include "GameFlowScript.h" #include "GameFlowScript.h"
#include "Quad/RenderQuad.h" #include "Quad/RenderQuad.h"
#include <string>
#include <memory>
using namespace T5M::Renderer; using namespace T5M::Renderer;
using std::vector; using std::vector;
extern GameConfiguration g_Configuration; extern GameConfiguration g_Configuration;
extern GameFlow* g_GameFlow; extern GameFlow* g_GameFlow;
bool Renderer11::Initialise(int w, int h, int refreshRate, bool windowed, HWND handle) void T5M::Renderer::Renderer11::Initialise(int w, int h, int refreshRate, bool windowed, HWND handle)
{ {
HRESULT res; HRESULT res;
//DB_Log(2, "Renderer::Initialise - DLL"); //DB_Log(2, "Renderer::Initialise - DLL");
printf("Initialising DX11\n"); logD("Initializing DX11");
CoInitialize(NULL); CoInitialize(NULL);
ScreenWidth = w; ScreenWidth = w;
ScreenHeight = h; ScreenHeight = h;
Windowed = windowed; Windowed = windowed;
initialiseScreen(w, h, refreshRate, windowed, handle, false);
if (!initialiseScreen(w, h, refreshRate, windowed, handle, false))
return false;
// Initialise render states // Initialise render states
m_states = new CommonStates(m_device); m_states = std::make_unique<CommonStates>(m_device.Get());
// Load caustics // Load caustics
const char* causticsNames[NUM_CAUSTICS_TEXTURES] = { const char* causticsNames[NUM_CAUSTICS_TEXTURES] = {
@ -53,26 +53,27 @@ bool Renderer11::Initialise(int w, int h, int refreshRate, bool windowed, HWND h
wchar_t causticsFile[255]; wchar_t causticsFile[255];
std::mbstowcs(causticsFile, causticsNames[i], 255); std::mbstowcs(causticsFile, causticsNames[i], 255);
std::wstring causticsFilename = std::wstring(causticsFile); std::wstring causticsFilename = std::wstring(causticsFile);
m_caustics[i] = Texture2D(m_device, causticsFilename); m_caustics[i] = Texture2D(m_device.Get(), causticsFilename);
} }
m_HUDBarBorderTexture = Texture2D(m_device, L"bar_border.png"); m_HUDBarBorderTexture = Texture2D(m_device.Get(), L"bar_border.png");
wchar_t titleScreenFile[255]; wchar_t titleScreenFile[255];
std::wstring titleFile = std::wstring(titleScreenFile); std::wstring titleFile = std::wstring(titleScreenFile);
std::mbstowcs(titleScreenFile, g_GameFlow->GetLevel(0)->Background.c_str(),255); std::mbstowcs(titleScreenFile, g_GameFlow->GetLevel(0)->Background.c_str(),255);
m_titleScreen = Texture2D(m_device, titleScreenFile); m_titleScreen = Texture2D(m_device.Get(), titleScreenFile);
m_binocularsTexture = Texture2D(m_device, L"Binoculars.png"); m_binocularsTexture = Texture2D(m_device.Get(), L"Binoculars.png");
m_whiteTexture = Texture2D(m_device, L"WhiteSprite.png"); m_whiteTexture = Texture2D(m_device.Get(), L"WhiteSprite.png");
m_logo = Texture2D(m_device, L"Logo.png");
m_logo = Texture2D(m_device.Get(), L"Logo.png");
m_shadowMaps = RenderTargetCubeArray(m_device.Get(), g_Configuration.shadowMapSize, MAX_DYNAMIC_SHADOWS, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_D16_UNORM);
// Load shaders // Load shaders
ID3D10Blob * blob; ComPtr<ID3D10Blob> blob;
//char shadowMapStringBuff[4];
m_vsRooms = compileVertexShader(L"Shaders\\DX11_Rooms.fx", "VS", "vs_4_0", &blob); //_itoa(g_Configuration.shadowMapSize, shadowMapStringBuff,10);
if (m_vsRooms == NULL) std::string shadowSizeString = std::to_string(g_Configuration.shadowMapSize);
return false; const D3D_SHADER_MACRO roomDefines[] = {"SHADOW_MAP_SIZE",shadowSizeString.c_str(),nullptr,nullptr};
m_vsRooms = Utils::compileVertexShader(m_device.Get(),L"Shaders\\DX11_Rooms.fx", "VS", "vs_4_0", &roomDefines[0], blob);
// Initialise input layout using the first vertex shader // Initialise input layout using the first vertex shader
D3D11_INPUT_ELEMENT_DESC inputLayout[] = D3D11_INPUT_ELEMENT_DESC inputLayout[] =
@ -85,116 +86,48 @@ bool Renderer11::Initialise(int w, int h, int refreshRate, bool windowed, HWND h
{"BITANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 60, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"BITANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 60, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"BLENDINDICES", 0, DXGI_FORMAT_R32_FLOAT, 0, 72, D3D11_INPUT_PER_VERTEX_DATA, 0} {"BLENDINDICES", 0, DXGI_FORMAT_R32_FLOAT, 0, 72, D3D11_INPUT_PER_VERTEX_DATA, 0}
}; };
Utils::throwIfFailed(m_device->CreateInputLayout(inputLayout, 7, blob->GetBufferPointer(), blob->GetBufferSize(), &m_inputLayout));
m_inputLayout = NULL; m_psRooms = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Rooms.fx", "PS", "ps_4_0", &roomDefines[0], blob);
res = m_device->CreateInputLayout(inputLayout, 7, blob->GetBufferPointer(), blob->GetBufferSize(), &m_inputLayout); m_vsItems = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Items.fx", "VS", "vs_4_0", nullptr, blob);
if (FAILED(res)) m_psItems = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Items.fx", "PS", "ps_4_0", nullptr, blob);
return false; m_vsStatics = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Statics.fx", "VS", "vs_4_0", nullptr, blob);
m_psStatics = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Statics.fx", "PS", "ps_4_0", nullptr, blob);
m_psRooms = compilePixelShader(L"Shaders\\DX11_Rooms.fx", "PS", "ps_4_0", &blob); m_vsHairs = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Hairs.fx", "VS", "vs_4_0", nullptr, blob);
if (m_psRooms == NULL) m_psHairs = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Hairs.fx", "PS", "ps_4_0", nullptr, blob);
return false; m_vsSky = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Sky.fx", "VS", "vs_4_0", nullptr, blob);
m_psSky = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Sky.fx", "PS", "ps_4_0", nullptr, blob);
m_vsItems = compileVertexShader(L"Shaders\\DX11_Items.fx", "VS", "vs_4_0", &blob); m_vsSprites = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Sprites.fx", "VS", "vs_4_0", nullptr, blob);
if (m_vsItems == NULL) m_psSprites = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Sprites.fx", "PS", "ps_4_0", nullptr, blob);
return false; m_vsSolid = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Solid.fx", "VS", "vs_4_0", nullptr, blob);
m_psSolid = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Solid.fx", "PS", "ps_4_0", nullptr, blob);
m_psItems = compilePixelShader(L"Shaders\\DX11_Items.fx", "PS", "ps_4_0", &blob); m_vsInventory = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Inventory.fx", "VS", "vs_4_0",nullptr, blob);
if (m_psItems == NULL) m_psInventory = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Inventory.fx", "PS", "ps_4_0", nullptr, blob);
return false; m_vsFullScreenQuad = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_FullScreenQuad.fx", "VS", "vs_4_0",nullptr, blob);
m_psFullScreenQuad = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_FullScreenQuad.fx", "PS", "ps_4_0", nullptr, blob);
m_vsStatics = compileVertexShader(L"Shaders\\DX11_Statics.fx", "VS", "vs_4_0", &blob); m_vsShadowMap = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_ShadowMap.fx", "VS", "vs_4_0", nullptr, blob);
if (m_vsStatics == NULL) m_psShadowMap = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_ShadowMap.fx", "PS", "ps_4_0", nullptr, blob);
return false; m_vsHUD = Utils::compileVertexShader(m_device.Get(), L"Shaders\\HUD\\DX11_VS_HUD.hlsl", "VS", "vs_4_0", nullptr, blob);
m_psHUDColor = Utils::compilePixelShader(m_device.Get(), L"Shaders\\HUD\\DX11_PS_HUD.hlsl", "PSColored", "ps_4_0", nullptr, blob);
m_psStatics = compilePixelShader(L"Shaders\\DX11_Statics.fx", "PS", "ps_4_0", &blob); m_psHUDTexture = Utils::compilePixelShader(m_device.Get(),L"Shaders\\HUD\\DX11_PS_HUD.hlsl", "PSTextured", "ps_4_0", nullptr, blob);
if (m_psStatics == NULL) m_psHUDBarColor = Utils::compilePixelShader(m_device.Get(),L"Shaders\\HUD\\DX11_PS_HUDBar.hlsl", "PSColored", "ps_4_0", nullptr, blob);
return false; m_shadowMap = RenderTarget2D(m_device.Get(), g_Configuration.shadowMapSize, g_Configuration.shadowMapSize, DXGI_FORMAT_R32_FLOAT,DXGI_FORMAT_D16_UNORM);
m_vsHairs = compileVertexShader(L"Shaders\\DX11_Hairs.fx", "VS", "vs_4_0", &blob);
if (m_vsHairs == NULL)
return false;
m_psHairs = compilePixelShader(L"Shaders\\DX11_Hairs.fx", "PS", "ps_4_0", &blob);
if (m_psHairs == NULL)
return false;
m_vsSky = compileVertexShader(L"Shaders\\DX11_Sky.fx", "VS", "vs_4_0", &blob);
if (m_vsSky == NULL)
return false;
m_psSky = compilePixelShader(L"Shaders\\DX11_Sky.fx", "PS", "ps_4_0", &blob);
if (m_psSky == NULL)
return false;
m_vsSprites = compileVertexShader(L"Shaders\\DX11_Sprites.fx", "VS", "vs_4_0", &blob);
if (m_vsSprites == NULL)
return false;
m_psSprites = compilePixelShader(L"Shaders\\DX11_Sprites.fx", "PS", "ps_4_0", &blob);
if (m_psSprites == NULL)
return false;
m_vsSolid = compileVertexShader(L"Shaders\\DX11_Solid.fx", "VS", "vs_4_0", &blob);
if (m_vsSolid == NULL)
return false;
m_psSolid = compilePixelShader(L"Shaders\\DX11_Solid.fx", "PS", "ps_4_0", &blob);
if (m_psSolid == NULL)
return false;
m_vsInventory = compileVertexShader(L"Shaders\\DX11_Inventory.fx", "VS", "vs_4_0", &blob);
if (m_vsInventory == NULL)
return false;
m_psInventory = compilePixelShader(L"Shaders\\DX11_Inventory.fx", "PS", "ps_4_0", &blob);
if (m_psInventory == NULL)
return false;
m_vsFullScreenQuad = compileVertexShader(L"Shaders\\DX11_FullScreenQuad.fx", "VS", "vs_4_0", &blob);
if (m_vsFullScreenQuad == NULL)
return false;
m_psFullScreenQuad = compilePixelShader(L"Shaders\\DX11_FullScreenQuad.fx", "PS", "ps_4_0", &blob);
if (m_psFullScreenQuad == NULL)
return false;
m_vsShadowMap = compileVertexShader(L"Shaders\\DX11_ShadowMap.fx", "VS", "vs_4_0", &blob);
if (m_vsShadowMap == NULL)
return false;
m_psShadowMap = compilePixelShader(L"Shaders\\DX11_ShadowMap.fx", "PS", "ps_4_0", &blob);
if (m_psShadowMap == NULL)
return false;
m_vsHUD = compileVertexShader(L"Shaders\\HUD\\DX11_VS_HUD.hlsl", "VS", "vs_4_0", &blob);
if (m_vsHUD == NULL)
return false;
m_psHUDColor = compilePixelShader(L"Shaders\\HUD\\DX11_PS_HUD.hlsl", "PSColored", "ps_4_0", &blob);
if (m_psHUDColor == NULL)
return false;
m_psHUDTexture = compilePixelShader(L"Shaders\\HUD\\DX11_PS_HUD.hlsl", "PSTextured", "ps_4_0", &blob);
if (m_psHUDTexture == NULL)
return false;
m_psHUDBarColor = compilePixelShader(L"Shaders\\HUD\\DX11_PS_HUDBar.hlsl", "PSColored", "ps_4_0", &blob);
if (m_psHUDBarColor == NULL)
return false;
// Initialise constant buffers // Initialise constant buffers
m_cbCameraMatrices = createConstantBuffer(sizeof(CCameraMatrixBuffer)); m_cbCameraMatrices = createConstantBuffer<CCameraMatrixBuffer>();
m_cbItem = createConstantBuffer(sizeof(CItemBuffer)); m_cbItem = createConstantBuffer<CItemBuffer>();
m_cbStatic = createConstantBuffer(sizeof(CStaticBuffer)); m_cbStatic = createConstantBuffer<CStaticBuffer>();
m_cbLights = createConstantBuffer(sizeof(CLightBuffer)); m_cbLights = createConstantBuffer<CLightBuffer>();
m_cbMisc = createConstantBuffer(sizeof(CMiscBuffer)); m_cbMisc = createConstantBuffer<CMiscBuffer>();
m_cbShadowMap = createConstantBuffer(sizeof(CShadowLightBuffer)); m_cbShadowMap = createConstantBuffer<CShadowLightBuffer>();
m_cbRoom = createConstantBuffer(sizeof(CRoomBuffer)); m_cbRoom = createConstantBuffer<CRoomBuffer>();
//Prepare HUD Constant buffer //Prepare HUD Constant buffer
m_cbHUDBar = createConstantBuffer(sizeof(CHUDBarBuffer)); m_cbHUDBar = createConstantBuffer<CHUDBarBuffer>();
m_cbHUD = createConstantBuffer(sizeof(CHUDBuffer)); m_cbHUD = createConstantBuffer<CHUDBuffer>();
m_cbSprite = createConstantBuffer(sizeof(CSpriteBuffer)); m_cbSprite = createConstantBuffer<CSpriteBuffer>();
m_stHUD.View = Matrix::CreateLookAt(Vector3::Zero, Vector3(0, 0, 1), Vector3(0, -1, 0)); m_stHUD.View = Matrix::CreateLookAt(Vector3::Zero, Vector3(0, 0, 1), Vector3(0, -1, 0));
m_stHUD.Projection =Matrix::CreateOrthographicOffCenter(0, REFERENCE_RES_WIDTH, 0, REFERENCE_RES_HEIGHT, 0, 1.0f); m_stHUD.Projection =Matrix::CreateOrthographicOffCenter(0, REFERENCE_RES_WIDTH, 0, REFERENCE_RES_HEIGHT, 0, 1.0f);
updateConstantBuffer<CHUDBuffer>(m_cbHUD, m_stHUD); m_cbHUD.updateData(m_stHUD, m_context.Get());
m_currentCausticsFrame = 0; m_currentCausticsFrame = 0;
m_firstWeather = true; m_firstWeather = true;
@ -231,13 +164,20 @@ bool Renderer11::Initialise(int w, int h, int refreshRate, bool windowed, HWND h
blendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA; blendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA;
blendStateDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendStateDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; blendStateDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
m_device->CreateBlendState(&blendStateDesc, &m_subtractiveBlendState); Utils::throwIfFailed(m_device->CreateBlendState(&blendStateDesc, m_subtractiveBlendState.GetAddressOf()));
D3D11_SAMPLER_DESC shadowSamplerDesc = {};
shadowSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
shadowSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
shadowSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
shadowSamplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
shadowSamplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
Utils::throwIfFailed(m_device->CreateSamplerState(&shadowSamplerDesc,m_shadowSampler.GetAddressOf()));
m_shadowSampler->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("ShadowSampler") + 1, "ShadowSampler");
initialiseBars(); initialiseBars();
initQuad(m_device); initQuad(m_device.Get());
return true;
} }
bool Renderer11::initialiseScreen(int w, int h, int refreshRate, bool windowed, HWND handle, bool reset) void T5M::Renderer::Renderer11::initialiseScreen(int w, int h, int refreshRate, bool windowed, HWND handle, bool reset)
{ {
HRESULT res; HRESULT res;
@ -259,19 +199,13 @@ bool Renderer11::initialiseScreen(int w, int h, int refreshRate, bool windowed,
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
IDXGIDevice* dxgiDevice = NULL; IDXGIDevice* dxgiDevice = NULL;
res = m_device->QueryInterface(__uuidof(IDXGIDevice), (void**)& dxgiDevice); Utils::throwIfFailed(m_device->QueryInterface(__uuidof(IDXGIDevice), (void**)& dxgiDevice));
if (FAILED(res))
return false;
IDXGIAdapter* dxgiAdapter = NULL; IDXGIAdapter* dxgiAdapter = NULL;
res = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)& dxgiAdapter); Utils::throwIfFailed(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)& dxgiAdapter));
if (FAILED(res))
return false;
IDXGIFactory* dxgiFactory = NULL; IDXGIFactory* dxgiFactory = NULL;
res = dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)& dxgiFactory); Utils::throwIfFailed(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)& dxgiFactory));
if (FAILED(res))
return false;
if (reset) if (reset)
{ {
@ -280,10 +214,8 @@ bool Renderer11::initialiseScreen(int w, int h, int refreshRate, bool windowed,
m_swapChain->Release(); m_swapChain->Release();
} }
m_swapChain = NULL; Utils::throwIfFailed(dxgiFactory->CreateSwapChain(m_device.Get(), &sd, &m_swapChain));
res = dxgiFactory->CreateSwapChain(m_device, &sd, &m_swapChain);
if (FAILED(res))
return false;
dxgiFactory->MakeWindowAssociation(handle, 0); dxgiFactory->MakeWindowAssociation(handle, 0);
res = m_swapChain->SetFullscreenState(!windowed, NULL); res = m_swapChain->SetFullscreenState(!windowed, NULL);
@ -294,14 +226,12 @@ bool Renderer11::initialiseScreen(int w, int h, int refreshRate, bool windowed,
// Initialise the back buffer // Initialise the back buffer
m_backBufferTexture = NULL; m_backBufferTexture = NULL;
res = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast <void**>(&m_backBufferTexture)); Utils::throwIfFailed(m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast <void**>(&m_backBufferTexture)));
if (FAILED(res))
return false;
m_backBufferRTV = NULL; m_backBufferRTV = NULL;
res = m_device->CreateRenderTargetView(m_backBufferTexture, NULL, &m_backBufferRTV); Utils::throwIfFailed(m_device->CreateRenderTargetView(m_backBufferTexture, NULL, &m_backBufferRTV));
if (FAILED(res))
return false;
D3D11_TEXTURE2D_DESC depthStencilDesc; D3D11_TEXTURE2D_DESC depthStencilDesc;
depthStencilDesc.Width = w; depthStencilDesc.Width = w;
@ -317,28 +247,25 @@ bool Renderer11::initialiseScreen(int w, int h, int refreshRate, bool windowed,
depthStencilDesc.MiscFlags = 0; depthStencilDesc.MiscFlags = 0;
m_depthStencilTexture = NULL; m_depthStencilTexture = NULL;
res = m_device->CreateTexture2D(&depthStencilDesc, NULL, &m_depthStencilTexture); Utils::throwIfFailed(m_device->CreateTexture2D(&depthStencilDesc, NULL, &m_depthStencilTexture));
if (FAILED(res))
return false;
m_depthStencilView = NULL; m_depthStencilView = NULL;
res = m_device->CreateDepthStencilView(m_depthStencilTexture, NULL, &m_depthStencilView); Utils::throwIfFailed(m_device->CreateDepthStencilView(m_depthStencilTexture, NULL, &m_depthStencilView));
if (FAILED(res))
return false;
// Bind the back buffer and the depth stencil // Bind the back buffer and the depth stencil
m_context->OMSetRenderTargets(1, &m_backBufferRTV, m_depthStencilView); m_context->OMSetRenderTargets(1, &m_backBufferRTV, m_depthStencilView);
// Initialise sprites and font // Initialise sprites and font
m_spriteBatch = new SpriteBatch(m_context); m_spriteBatch = std::make_unique<SpriteBatch>(m_context.Get());
m_gameFont = new SpriteFont(m_device, L"Font.spritefont"); m_gameFont = std::make_unique<SpriteFont>(m_device.Get(), L"Font.spritefont");
m_primitiveBatch = new PrimitiveBatch<RendererVertex>(m_context); m_primitiveBatch = std::make_unique<PrimitiveBatch<RendererVertex>>(m_context.Get());
// Initialise buffers // Initialise buffers
m_renderTarget = RenderTarget2D(m_device, w, h, DXGI_FORMAT_R8G8B8A8_UNORM); m_renderTarget = RenderTarget2D(m_device.Get(), w, h, DXGI_FORMAT_R8G8B8A8_UNORM);
m_dumpScreenRenderTarget = RenderTarget2D(m_device, w, h, DXGI_FORMAT_R8G8B8A8_UNORM); m_dumpScreenRenderTarget = RenderTarget2D(m_device.Get(), w, h, DXGI_FORMAT_R8G8B8A8_UNORM);
m_shadowMap = RenderTarget2D(m_device, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE, DXGI_FORMAT_R32_FLOAT); m_reflectionCubemap = RenderTargetCube(m_device.Get(), 128, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
m_reflectionCubemap = RenderTargetCube(m_device, 128, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
// Shadow map // Shadow map
/*D3D11_TEXTURE2D_DESC depthTexDesc; /*D3D11_TEXTURE2D_DESC depthTexDesc;
ZeroMemory(&depthTexDesc, sizeof(D3D11_TEXTURE2D_DESC)); ZeroMemory(&depthTexDesc, sizeof(D3D11_TEXTURE2D_DESC));
@ -389,8 +316,8 @@ bool Renderer11::initialiseScreen(int w, int h, int refreshRate, bool windowed,
m_shadowMapViewport.TopLeftX = 0; m_shadowMapViewport.TopLeftX = 0;
m_shadowMapViewport.TopLeftY = 0; m_shadowMapViewport.TopLeftY = 0;
m_shadowMapViewport.Width = SHADOW_MAP_SIZE; m_shadowMapViewport.Width = g_Configuration.shadowMapSize;
m_shadowMapViewport.Height = SHADOW_MAP_SIZE; m_shadowMapViewport.Height = g_Configuration.shadowMapSize;
m_shadowMapViewport.MinDepth = 0.0f; m_shadowMapViewport.MinDepth = 0.0f;
m_shadowMapViewport.MaxDepth = 1.0f; m_shadowMapViewport.MaxDepth = 1.0f;
@ -412,12 +339,12 @@ bool Renderer11::initialiseScreen(int w, int h, int refreshRate, bool windowed,
UpdateWindow(handle); UpdateWindow(handle);
return true;
} }
bool Renderer11::Create() void T5M::Renderer::Renderer11::Create()
{ {
D3D_FEATURE_LEVEL levels[1] = { D3D_FEATURE_LEVEL_10_0 };
D3D_FEATURE_LEVEL levels[] = {D3D_FEATURE_LEVEL_11_0,D3D_FEATURE_LEVEL_11_1};
D3D_FEATURE_LEVEL featureLevel; D3D_FEATURE_LEVEL featureLevel;
HRESULT res; HRESULT res;
@ -426,11 +353,8 @@ bool Renderer11::Create()
#else #else
res = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, levels, 1, D3D11_SDK_VERSION, &m_device, &featureLevel, &m_context); // D3D11_CREATE_DEVICE_DEBUG res = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, levels, 1, D3D11_SDK_VERSION, &m_device, &featureLevel, &m_context); // D3D11_CREATE_DEVICE_DEBUG
#endif #endif
Utils::throwIfFailed(res);
if (FAILED(res))
return false;
return true;
} }
void Renderer11::initialiseHairRemaps() void Renderer11::initialiseHairRemaps()

View file

@ -13,7 +13,7 @@
using namespace T5M::Renderer; using namespace T5M::Renderer;
extern GameFlow *g_GameFlow; extern GameFlow *g_GameFlow;
void Renderer11::UpdateLaraAnimations(bool force) void Renderer11::updateLaraAnimations(bool force)
{ {
Matrix translation; Matrix translation;
Matrix rotation; Matrix rotation;
@ -65,8 +65,8 @@ void Renderer11::UpdateLaraAnimations(bool force)
else else
{ {
// While handling weapon some extra rotation could be applied to arms // While handling weapon some extra rotation could be applied to arms
laraObj.LinearizedBones[LM_LINARM]->ExtraRotation += Vector3(TO_RAD(Lara.leftArm.xRot), TO_RAD(Lara.leftArm.zRot), TO_RAD(-Lara.leftArm.yRot)); laraObj.LinearizedBones[LM_LINARM]->ExtraRotation += Vector3(TO_RAD(Lara.leftArm.xRot), TO_RAD(-Lara.leftArm.yRot), TO_RAD(Lara.leftArm.zRot));
laraObj.LinearizedBones[LM_RINARM]->ExtraRotation += Vector3(TO_RAD(Lara.rightArm.xRot), TO_RAD(Lara.rightArm.zRot), TO_RAD(-Lara.rightArm.yRot)); laraObj.LinearizedBones[LM_RINARM]->ExtraRotation += Vector3(TO_RAD(Lara.rightArm.xRot), TO_RAD(-Lara.rightArm.yRot), TO_RAD(Lara.rightArm.zRot));
LARA_ARM *leftArm = &Lara.leftArm; LARA_ARM *leftArm = &Lara.leftArm;
LARA_ARM *rightArm = &Lara.rightArm; LARA_ARM *rightArm = &Lara.rightArm;
@ -78,7 +78,9 @@ void Renderer11::UpdateLaraAnimations(bool force)
case WEAPON_HK: case WEAPON_HK:
case WEAPON_CROSSBOW: case WEAPON_CROSSBOW:
case WEAPON_GRENADE_LAUNCHER: case WEAPON_GRENADE_LAUNCHER:
case WEAPON_ROCKET_LAUNCHER:
case WEAPON_HARPOON_GUN: case WEAPON_HARPOON_GUN:
case WEAPON_REVOLVER:
ANIM_FRAME* shotgunFramePtr; ANIM_FRAME* shotgunFramePtr;
// Left arm // Left arm
@ -94,7 +96,6 @@ void Renderer11::UpdateLaraAnimations(bool force)
case WEAPON_PISTOLS: case WEAPON_PISTOLS:
case WEAPON_UZI: case WEAPON_UZI:
case WEAPON_REVOLVER:
default: default:
{ {
ANIM_FRAME* pistolFramePtr; ANIM_FRAME* pistolFramePtr;
@ -138,11 +139,11 @@ void Renderer11::UpdateLaraAnimations(bool force)
m_items[Lara.itemNumber].DoneAnimations = true; m_items[Lara.itemNumber].DoneAnimations = true;
} }
bool Renderer11::drawLara(bool transparent, bool shadowMap) void T5M::Renderer::Renderer11::drawLara(bool transparent, bool shadowMap)
{ {
// Don't draw Lara if binoculars or sniper // Don't draw Lara if binoculars or sniper
if (BinocularRange || SpotcamOverlay || SpotcamDontDrawLara || CurrentLevel == 0) if (BinocularRange || SpotcamOverlay || SpotcamDontDrawLara || CurrentLevel == 0)
return true; return;
UINT stride = sizeof(RendererVertex); UINT stride = sizeof(RendererVertex);
UINT offset = 0; UINT offset = 0;
@ -152,7 +153,7 @@ bool Renderer11::drawLara(bool transparent, bool shadowMap)
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetInputLayout(m_inputLayout); m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
RendererItem *item = &m_items[Lara.itemNumber]; RendererItem *item = &m_items[Lara.itemNumber];
@ -160,13 +161,13 @@ bool Renderer11::drawLara(bool transparent, bool shadowMap)
// Set shaders // Set shaders
if (shadowMap) if (shadowMap)
{ {
m_context->VSSetShader(m_vsShadowMap, NULL, 0); m_context->VSSetShader(m_vsShadowMap.Get(), NULL, 0);
m_context->PSSetShader(m_psShadowMap, NULL, 0); m_context->PSSetShader(m_psShadowMap.Get(), NULL, 0);
} }
else else
{ {
m_context->VSSetShader(m_vsItems, NULL, 0); m_context->VSSetShader(m_vsItems.Get(), NULL, 0);
m_context->PSSetShader(m_psItems, NULL, 0); m_context->PSSetShader(m_psItems.Get(), NULL, 0);
} }
// Set texture // Set texture
@ -177,8 +178,8 @@ bool Renderer11::drawLara(bool transparent, bool shadowMap)
m_context->PSSetSamplers(0, 1, &sampler); m_context->PSSetSamplers(0, 1, &sampler);
m_stMisc.AlphaTest = !transparent; m_stMisc.AlphaTest = !transparent;
updateConstantBuffer<CMiscBuffer>(m_cbMisc, m_stMisc); m_cbMisc.updateData(m_stMisc, m_context.Get());
m_context->PSSetConstantBuffers(3, 1, &m_cbMisc); m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
RendererObject &laraObj = *m_moveableObjects[ID_LARA]; RendererObject &laraObj = *m_moveableObjects[ID_LARA];
RendererObject &laraSkin = *m_moveableObjects[ID_LARA_SKIN]; RendererObject &laraSkin = *m_moveableObjects[ID_LARA_SKIN];
@ -188,17 +189,17 @@ bool Renderer11::drawLara(bool transparent, bool shadowMap)
m_stItem.Position = Vector4(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos, 1.0f); m_stItem.Position = Vector4(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos, 1.0f);
m_stItem.AmbientLight = room.AmbientLight; m_stItem.AmbientLight = room.AmbientLight;
memcpy(m_stItem.BonesMatrices, laraObj.AnimationTransforms.data(), sizeof(Matrix) * 32); memcpy(m_stItem.BonesMatrices, laraObj.AnimationTransforms.data(), sizeof(Matrix) * 32);
updateConstantBuffer<CItemBuffer>(m_cbItem, m_stItem); m_cbItem.updateData(m_stItem, m_context.Get());
m_context->VSSetConstantBuffers(1, 1, &m_cbItem); m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
m_context->PSSetConstantBuffers(1, 1, &m_cbItem); m_context->PSSetConstantBuffers(1, 1, m_cbItem.get());
if (!shadowMap) if (!shadowMap)
{ {
m_stLights.NumLights = item->Lights.size(); m_stLights.NumLights = item->Lights.size();
for (int j = 0; j < item->Lights.size(); j++) for (int j = 0; j < item->Lights.size(); j++)
memcpy(&m_stLights.Lights[j], item->Lights[j], sizeof(ShaderLight)); memcpy(&m_stLights.Lights[j], item->Lights[j], sizeof(ShaderLight));
updateConstantBuffer<CLightBuffer>(m_cbLights, m_stLights); m_cbLights.updateData(m_stLights, m_context.Get());
m_context->PSSetConstantBuffers(2, 1, &m_cbLights); m_context->PSSetConstantBuffers(2, 1, m_cbLights.get());
} }
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++) for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
@ -256,9 +257,9 @@ bool Renderer11::drawLara(bool transparent, bool shadowMap)
matrices[i + 1] = world; matrices[i + 1] = world;
} }
memcpy(m_stItem.BonesMatrices, matrices, sizeof(Matrix) * 7); memcpy(m_stItem.BonesMatrices, matrices, sizeof(Matrix) * 7);
updateConstantBuffer<CItemBuffer>(m_cbItem, m_stItem); m_cbItem.updateData(m_stItem,m_context.Get());
m_context->VSSetConstantBuffers(1, 1, &m_cbItem); m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
m_context->PSSetConstantBuffers(1, 1, &m_cbItem); m_context->PSSetConstantBuffers(1, 1, m_cbItem.get());
for (int k = 0; k < hairsObj.ObjectMeshes.size(); k++) for (int k = 0; k < hairsObj.ObjectMeshes.size(); k++)
{ {
@ -277,8 +278,6 @@ bool Renderer11::drawLara(bool transparent, bool shadowMap)
} }
} }
} }
return true;
} }
void Renderer11::drawLaraHolsters(bool transparent) void Renderer11::drawLaraHolsters(bool transparent)

View file

@ -1,16 +1,17 @@
#include "framework.h" #include "framework.h"
#include "Renderer11.h" #include "Renderer11.h"
namespace T5M::Renderer { namespace T5M::Renderer {
void Renderer11::EnableCinematicBars(bool value) { void Renderer11::enableCinematicBars(bool value) {
m_enableCinematicBars = value; m_enableCinematicBars = value;
} }
void Renderer11::FadeIn() { void Renderer11::fadeIn()
{
m_fadeStatus = RENDERER_FADE_STATUS::FADE_IN; m_fadeStatus = RENDERER_FADE_STATUS::FADE_IN;
m_fadeFactor = 0.0f; m_fadeFactor = 0.0f;
} }
void Renderer11::FadeOut() { void Renderer11::fadeOut() {
m_fadeStatus = RENDERER_FADE_STATUS::FADE_OUT; m_fadeStatus = RENDERER_FADE_STATUS::FADE_OUT;
m_fadeFactor = 1.0f; m_fadeFactor = 1.0f;
} }

View file

@ -2,11 +2,12 @@
#include "Renderer11.h" #include "Renderer11.h"
#include "winmain.h" #include "winmain.h"
namespace T5M::Renderer { namespace T5M::Renderer {
bool Renderer11::ToggleFullScreen() { void Renderer11::toggleFullScreen()
return true; {
} }
bool Renderer11::ChangeScreenResolution(int width, int height, int frequency, bool windowed) { void Renderer11::changeScreenResolution(int width, int height, int frequency, bool windowed) {
HRESULT res; HRESULT res;
/*if (windowed && !Windowed) /*if (windowed && !Windowed)
@ -133,10 +134,6 @@ namespace T5M::Renderer {
ID3D11RenderTargetView* nullViews[] = { nullptr }; ID3D11RenderTargetView* nullViews[] = { nullptr };
m_context->OMSetRenderTargets(0, nullViews, NULL); m_context->OMSetRenderTargets(0, nullViews, NULL);
DX11_DELETE(m_gameFont);
DX11_DELETE(m_spriteBatch);
DX11_DELETE(m_primitiveBatch);
m_backBufferTexture->Release(); m_backBufferTexture->Release();
m_backBufferRTV->Release(); m_backBufferRTV->Release();
m_depthStencilView->Release(); m_depthStencilView->Release();
@ -150,20 +147,14 @@ namespace T5M::Renderer {
return false;*/ return false;*/
IDXGIOutput* output; IDXGIOutput* output;
res = m_swapChain->GetContainingOutput(&output); Utils::throwIfFailed(m_swapChain->GetContainingOutput(&output));
if (FAILED(res))
return false;
DXGI_SWAP_CHAIN_DESC scd; DXGI_SWAP_CHAIN_DESC scd;
res = m_swapChain->GetDesc(&scd); Utils::throwIfFailed(m_swapChain->GetDesc(&scd));
if (FAILED(res))
return false;
UINT numModes = 1024; UINT numModes = 1024;
DXGI_MODE_DESC modes[1024]; DXGI_MODE_DESC modes[1024];
res = output->GetDisplayModeList(scd.BufferDesc.Format, 0, &numModes, modes); Utils::throwIfFailed(output->GetDisplayModeList(scd.BufferDesc.Format, 0, &numModes, modes));
if (FAILED(res))
return false;
DXGI_MODE_DESC* mode = &modes[0]; DXGI_MODE_DESC* mode = &modes[0];
for (int i = 0; i < numModes; i++) { for (int i = 0; i < numModes; i++) {
@ -172,17 +163,12 @@ namespace T5M::Renderer {
break; break;
} }
res = m_swapChain->ResizeTarget(mode); Utils::throwIfFailed( m_swapChain->ResizeTarget(mode));
if (FAILED(res))
return false;
if (!initialiseScreen(width, height, frequency, windowed, WindowsHandle, true)) initialiseScreen(width, height, frequency, windowed, WindowsHandle, true);
return false;
ScreenWidth = width; ScreenWidth = width;
ScreenHeight = height; ScreenHeight = height;
Windowed = windowed; Windowed = windowed;
return true;
} }
} }

View file

@ -1,7 +1,7 @@
#include "framework.h" #include "framework.h"
#include "Renderer11.h" #include "Renderer11.h"
namespace T5M::Renderer { namespace T5M::Renderer {
bool Renderer11::PrintString(int x, int y, char* string, D3DCOLOR color, int flags) { void Renderer11::drawString(int x, int y, const char* string, D3DCOLOR color, int flags) {
int realX = x; int realX = x;
int realY = y; int realY = y;
float factorX = ScreenWidth / 800.0f; float factorX = ScreenWidth / 800.0f;
@ -59,10 +59,10 @@ namespace T5M::Renderer {
m_strings.push_back(str); m_strings.push_back(str);
return true;
} }
bool Renderer11::drawAllStrings() { void Renderer11::drawAllStrings()
{
m_spriteBatch->Begin(); m_spriteBatch->Begin();
for (int i = 0; i < m_strings.size(); i++) { for (int i = 0; i < m_strings.size(); i++) {
@ -70,17 +70,16 @@ namespace T5M::Renderer {
// Draw shadow if needed // Draw shadow if needed
if (str->Flags & PRINTSTRING_OUTLINE) if (str->Flags & PRINTSTRING_OUTLINE)
m_gameFont->DrawString(m_spriteBatch, str->String.c_str(), Vector2(str->X + 1, str->Y + 1), m_gameFont->DrawString(m_spriteBatch.get(), str->String.c_str(), Vector2(str->X + 1, str->Y + 1),
Vector4(0.0f, 0.0f, 0.0f, 1.0f)); Vector4(0.0f, 0.0f, 0.0f, 1.0f));
// Draw string // Draw string
m_gameFont->DrawString(m_spriteBatch, str->String.c_str(), Vector2(str->X, str->Y), m_gameFont->DrawString(m_spriteBatch.get(), str->String.c_str(), Vector2(str->X, str->Y),
Vector4(str->Color.x / 255.0f, str->Color.y / 255.0f, str->Color.z / 255.0f, 1.0f)); Vector4(str->Color.x / 255.0f, str->Color.y / 255.0f, str->Color.z / 255.0f, 1.0f));
} }
m_spriteBatch->End(); m_spriteBatch->End();
return true;
} }
} }

View file

@ -1,9 +1,59 @@
#include "framework.h" #include "framework.h"
#include "Utils.h" #include "Utils.h"
#include <winerror.h> #include <winerror.h>
#include <iostream>
#include <wrl/client.h>
namespace T5M::Renderer::Utils {
using std::wstring;
using std::string;
using Microsoft::WRL::ComPtr;
using std::vector;
void Utils::throwIfFailed(const HRESULT& res) noexcept {
if(FAILED(res)){
std::string message = std::system_category().message(res);
std::cout << message << std::endl;
throw std::runtime_error("An error occured!");
}
void T5M::Renderer::Utils::throwIfFailed(const HRESULT& res) }
{
if (FAILED(res)) ComPtr<ID3D11VertexShader> compileVertexShader(ID3D11Device* device, const std::wstring& fileName, const std::string& function, const std::string& model, const D3D_SHADER_MACRO * defines, ComPtr<ID3D10Blob>& bytecode) {
throw std::exception("An error occured!"); ComPtr<ID3D10Blob> errors;
logD("Compiling vertex shader");
throwIfFailed(D3DCompileFromFile(fileName.c_str(), defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, function.c_str(), model.c_str(), GetShaderFlags(), 0, bytecode.GetAddressOf(),errors.GetAddressOf()));
ComPtr<ID3D11VertexShader> shader;
throwIfFailed(device->CreateVertexShader(bytecode->GetBufferPointer(), bytecode->GetBufferSize(), nullptr, shader.GetAddressOf()));
if constexpr(DebugBuild){
char buffer[100];
size_t sz = std::wcstombs(buffer, fileName.c_str(), 100);
shader->SetPrivateData(WKPDID_D3DDebugObjectName, sz, buffer);
}
return shader;
}
ComPtr<ID3D11PixelShader> compilePixelShader(ID3D11Device* device, const wstring& fileName, const string& function, const string& model, const D3D_SHADER_MACRO* defines, ComPtr<ID3D10Blob>& bytecode) {
ComPtr<ID3D10Blob> errors;
logD("Compiling pixel shader");
UINT flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR | D3DCOMPILE_SKIP_OPTIMIZATION;
throwIfFailed(D3DCompileFromFile(fileName.c_str(), defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, function.c_str(), model.c_str(), GetShaderFlags(), 0, bytecode.GetAddressOf(), errors.GetAddressOf()));
ComPtr<ID3D11PixelShader> shader;
throwIfFailed(device->CreatePixelShader(bytecode->GetBufferPointer(), bytecode->GetBufferSize(), nullptr, shader.GetAddressOf()));
if constexpr(DebugBuild){
char buffer[100];
size_t sz = std::wcstombs(buffer, fileName.c_str(), 100);
shader->SetPrivateData(WKPDID_D3DDebugObjectName, sz, buffer);
}
return shader;
}
constexpr UINT Utils::GetShaderFlags()
{
UINT flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
if constexpr(DebugBuild){
flags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
} else{
flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3 | D3DCOMPILE_IEEE_STRICTNESS;
}
return flags;
}
} }

View file

@ -1,11 +1,15 @@
#pragma once #pragma once
#include <winerror.h> #include <winerror.h>
#include <string>
#include <wrl/client.h>
namespace T5M { namespace T5M {
namespace Renderer { namespace Renderer {
namespace Utils { namespace Utils {
//throws a std::exception when the result contains a FAILED result void throwIfFailed(const HRESULT& res) noexcept;
//In most cases we cannot run the game if some Direct3D operation failed [[nodiscard]] Microsoft::WRL::ComPtr<ID3D11VertexShader> compileVertexShader(ID3D11Device* device, const std::wstring& fileName, const std::string& function, const std::string& model, const D3D_SHADER_MACRO* defines, Microsoft::WRL::ComPtr<ID3D10Blob>& bytecode);
void throwIfFailed(const HRESULT& res); constexpr [[nodiscard]] UINT GetShaderFlags();
[[nodiscard]] Microsoft::WRL::ComPtr<ID3D11PixelShader> compilePixelShader(ID3D11Device* device, const std::wstring& fileName, const std::string& function, const std::string& model, const D3D_SHADER_MACRO* defines, Microsoft::WRL::ComPtr<ID3D10Blob>& bytecode);
} }
} }
} }

View file

@ -8,23 +8,23 @@
#include "draw.h" #include "draw.h"
using std::string; using std::string;
using std::vector; using std::vector;
ChunkId* ChunkGameFlowFlags = ChunkId::FromString("Tr5MainFlags"); std::unique_ptr<ChunkId> ChunkGameFlowFlags = ChunkId::FromString("Tr5MainFlags");
ChunkId* ChunkGameFlowLevel = ChunkId::FromString("Tr5MainLevel"); std::unique_ptr<ChunkId> ChunkGameFlowLevel = ChunkId::FromString("Tr5MainLevel");
ChunkId* ChunkGameFlowLevelFlags = ChunkId::FromString("Tr5MainLevelFlags"); std::unique_ptr<ChunkId> ChunkGameFlowLevelFlags = ChunkId::FromString("Tr5MainLevelFlags");
ChunkId* ChunkGameFlowLevelInfo = ChunkId::FromString("Tr5MainLevelInfo"); std::unique_ptr<ChunkId> ChunkGameFlowLevelInfo = ChunkId::FromString("Tr5MainLevelInfo");
ChunkId* ChunkGameFlowLevelPuzzle = ChunkId::FromString("Tr5MainLevelPuzzle"); std::unique_ptr<ChunkId> ChunkGameFlowLevelPuzzle = ChunkId::FromString("Tr5MainLevelPuzzle");
ChunkId* ChunkGameFlowLevelKey = ChunkId::FromString("Tr5MainLevelKey"); std::unique_ptr<ChunkId> ChunkGameFlowLevelKey = ChunkId::FromString("Tr5MainLevelKey");
ChunkId* ChunkGameFlowLevelPuzzleCombo = ChunkId::FromString("Tr5MainLevelPuzzleCombo"); std::unique_ptr<ChunkId> ChunkGameFlowLevelPuzzleCombo = ChunkId::FromString("Tr5MainLevelPuzzleCombo");
ChunkId* ChunkGameFlowLevelKeyCombo = ChunkId::FromString("Tr5MainLevelKeyCombo"); std::unique_ptr<ChunkId> ChunkGameFlowLevelKeyCombo = ChunkId::FromString("Tr5MainLevelKeyCombo");
ChunkId* ChunkGameFlowLevelPickup = ChunkId::FromString("Tr5MainLevelPickup"); std::unique_ptr<ChunkId> ChunkGameFlowLevelPickup = ChunkId::FromString("Tr5MainLevelPickup");
ChunkId* ChunkGameFlowLevelPickupCombo = ChunkId::FromString("Tr5MainLevelPickupCombo"); std::unique_ptr<ChunkId> ChunkGameFlowLevelPickupCombo = ChunkId::FromString("Tr5MainLevelPickupCombo");
ChunkId* ChunkGameFlowLevelExamine = ChunkId::FromString("Tr5MainLevelExamine"); std::unique_ptr<ChunkId> ChunkGameFlowLevelExamine = ChunkId::FromString("Tr5MainLevelExamine");
ChunkId* ChunkGameFlowLevelLayer = ChunkId::FromString("Tr5MainLevelLayer"); std::unique_ptr<ChunkId> ChunkGameFlowLevelLayer = ChunkId::FromString("Tr5MainLevelLayer");
ChunkId* ChunkGameFlowLevelLuaEvent = ChunkId::FromString("Tr5MainLevelLuaEvent"); std::unique_ptr<ChunkId> ChunkGameFlowLevelLuaEvent = ChunkId::FromString("Tr5MainLevelLuaEvent");
ChunkId* ChunkGameFlowLevelLegend = ChunkId::FromString("Tr5MainLevelLegend"); std::unique_ptr<ChunkId> ChunkGameFlowLevelLegend = ChunkId::FromString("Tr5MainLevelLegend");
ChunkId* ChunkGameFlowStrings = ChunkId::FromString("Tr5MainStrings"); std::unique_ptr<ChunkId> ChunkGameFlowStrings = ChunkId::FromString("Tr5MainStrings");
ChunkId* ChunkGameFlowAudioTracks = ChunkId::FromString("Tr5MainAudioTracks"); std::unique_ptr<ChunkId> ChunkGameFlowAudioTracks = ChunkId::FromString("Tr5MainAudioTracks");
ChunkId* ChunkGameFlowTitleBackground = ChunkId::FromString("Tr5MainTitleBackground"); std::unique_ptr<ChunkId> ChunkGameFlowTitleBackground = ChunkId::FromString("Tr5MainTitleBackground");
ChunkReader* g_ScriptChunkIO; ChunkReader* g_ScriptChunkIO;
@ -163,7 +163,7 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, int maxSize, int arg)
{ {
GameScriptLevel* level = g_GameFlow->Levels[arg]; GameScriptLevel* level = g_GameFlow->Levels[arg];
if (chunkId->EqualsTo(ChunkGameFlowLevelInfo)) if (chunkId->EqualsTo(ChunkGameFlowLevelInfo.get()))
{ {
char* str; char* str;
@ -184,7 +184,7 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, int maxSize, int arg)
return true; return true;
} }
else if (chunkId->EqualsTo(ChunkGameFlowLevelFlags)) else if (chunkId->EqualsTo(ChunkGameFlowLevelFlags.get()))
{ {
level->Horizon = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); level->Horizon = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
level->Sky = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); level->Sky = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
@ -200,7 +200,7 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, int maxSize, int arg)
return true; return true;
} }
else if (chunkId->EqualsTo(ChunkGameFlowLevelPuzzle)) else if (chunkId->EqualsTo(ChunkGameFlowLevelPuzzle.get()))
{ {
int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
int itemStringIndex = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream()); int itemStringIndex = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream());
@ -209,7 +209,7 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, int maxSize, int arg)
return true; return true;
} }
else if (chunkId->EqualsTo(ChunkGameFlowLevelKey)) else if (chunkId->EqualsTo(ChunkGameFlowLevelKey.get()))
{ {
int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
int itemStringIndex = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream()); int itemStringIndex = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream());
@ -218,7 +218,7 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, int maxSize, int arg)
return true; return true;
} }
else if (chunkId->EqualsTo(ChunkGameFlowLevelPickup)) else if (chunkId->EqualsTo(ChunkGameFlowLevelPickup.get()))
{ {
int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
int itemStringIndex = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream()); int itemStringIndex = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream());
@ -227,7 +227,7 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, int maxSize, int arg)
return true; return true;
} }
else if (chunkId->EqualsTo(ChunkGameFlowLevelExamine)) else if (chunkId->EqualsTo(ChunkGameFlowLevelExamine.get()))
{ {
int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
int itemStringIndex = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream()); int itemStringIndex = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream());
@ -236,7 +236,7 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, int maxSize, int arg)
return true; return true;
} }
else if (chunkId->EqualsTo(ChunkGameFlowLevelPuzzleCombo)) else if (chunkId->EqualsTo(ChunkGameFlowLevelPuzzleCombo.get()))
{ {
int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
int piece = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); int piece = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
@ -246,7 +246,7 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, int maxSize, int arg)
return true; return true;
} }
else if (chunkId->EqualsTo(ChunkGameFlowLevelKeyCombo)) else if (chunkId->EqualsTo(ChunkGameFlowLevelKeyCombo.get()))
{ {
int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
int piece = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); int piece = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
@ -256,7 +256,7 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, int maxSize, int arg)
return true; return true;
} }
else if (chunkId->EqualsTo(ChunkGameFlowLevelPickupCombo)) else if (chunkId->EqualsTo(ChunkGameFlowLevelPickupCombo.get()))
{ {
int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); int itemIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
int piece = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); int piece = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
@ -266,7 +266,7 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, int maxSize, int arg)
return true; return true;
} }
else if (chunkId->EqualsTo(ChunkGameFlowLevelLayer)) else if (chunkId->EqualsTo(ChunkGameFlowLevelLayer.get()))
{ {
int layerIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); int layerIndex = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream());
@ -301,13 +301,13 @@ bool __cdecl readGameFlowLevel()
bool __cdecl readGameFlowChunks(ChunkId* chunkId, int maxSize, int arg) bool __cdecl readGameFlowChunks(ChunkId* chunkId, int maxSize, int arg)
{ {
if (chunkId->EqualsTo(ChunkGameFlowFlags)) if (chunkId->EqualsTo(ChunkGameFlowFlags.get()))
return readGameFlowFlags(); return readGameFlowFlags();
else if (chunkId->EqualsTo(ChunkGameFlowStrings)) else if (chunkId->EqualsTo(ChunkGameFlowStrings.get()))
return readGameFlowStrings(); return readGameFlowStrings();
else if (chunkId->EqualsTo(ChunkGameFlowAudioTracks)) else if (chunkId->EqualsTo(ChunkGameFlowAudioTracks.get()))
return readGameFlowTracks(); return readGameFlowTracks();
else if (chunkId->EqualsTo(ChunkGameFlowLevel)) else if (chunkId->EqualsTo(ChunkGameFlowLevel.get()))
return readGameFlowLevel(); return readGameFlowLevel();
return false; return false;
} }

View file

@ -83,7 +83,7 @@ float4 PS(PixelShaderInput input) : SV_TARGET
if (AlphaTest) if (AlphaTest)
clip(output.w - 0.5f); clip(output.w - 0.5f);
float3 lighting = AmbientLight.xyz * 2.0f; float3 lighting = AmbientLight.xyz;
float4 reflectionColor = Reflection.Sample(Sampler,input.ReflectionVector.xyz); float4 reflectionColor = Reflection.Sample(Sampler,input.ReflectionVector.xyz);
for (int i = 0; i < NumLights; i++) for (int i = 0; i < NumLights; i++)
{ {

View file

@ -54,7 +54,7 @@ SamplerState Sampler : register(s0);
Texture2D CausticsTexture : register(t1); Texture2D CausticsTexture : register(t1);
Texture2D ShadowMap : register(t2); Texture2D ShadowMap : register(t2);
SamplerState ShadowMapSampler : register(s1); SamplerComparisonState ShadowMapSampler : register(s1);
PixelShaderInput VS(VertexShaderInput input) PixelShaderInput VS(VertexShaderInput input)
{ {
PixelShaderInput output; PixelShaderInput output;
@ -79,17 +79,8 @@ PixelShaderInput VS(VertexShaderInput input)
return output; return output;
} }
float getShadowFactor(Texture2D shadowMap, SamplerState shadowMapSampler, float2 coords, float realDepth) { float2 texOffset(int u, int v) {
const float texelSize = 1.0f / 1024; return float2(u * 1.0f / SHADOW_MAP_SIZE, v * 1.0f / SHADOW_MAP_SIZE);
float shadowFactor = 0.0f;
//doing 9 samples
for (float x = -1; x <= 1.0f; x++) {
for (float y = -1; y <= 1.0f; y++) {
float shadowMapDepth = ShadowMap.SampleLevel(ShadowMapSampler, coords + (float2(x, y)*texelSize),0).r;
shadowFactor += shadowMapDepth < realDepth ? 1.0f : 0.0f;
}
}
return shadowFactor / 9.0f;
} }
float4 PS(PixelShaderInput input) : SV_TARGET float4 PS(PixelShaderInput input) : SV_TARGET
@ -117,16 +108,22 @@ float4 PS(PixelShaderInput input) : SV_TARGET
input.LightPosition.y >= -1.0f && input.LightPosition.y <= 1.0f && input.LightPosition.y >= -1.0f && input.LightPosition.y <= 1.0f &&
input.LightPosition.z >= 0.0f && input.LightPosition.z <= 1.0f) input.LightPosition.z >= 0.0f && input.LightPosition.z <= 1.0f)
{ {
float2 coords = float2(input.LightPosition.x / 2.0f + 0.5f, -input.LightPosition.y / 2.0f + 0.5f); input.LightPosition.x = input.LightPosition.x / 2 + 0.5;
input.LightPosition.y = input.LightPosition.y / -2 + 0.5;
// Sample shadow map - point sampler //PCF sampling for shadow map
float shadowMapDepth = ShadowMap.Sample(ShadowMapSampler, coords).r; float sum = 0;
float x, y;
float realDepth = input.LightPosition.z; //perform PCF filtering on a 4 x 4 texel neighborhood
for (y = -1.5; y <= 1.5; y += 1.0) {
for (x = -1.5; x <= 1.5; x += 1.0) {
sum += ShadowMap.SampleCmpLevelZero(ShadowMapSampler, input.LightPosition.xy + texOffset(x, y), input.LightPosition.z);
}
}
// If clip space z value greater than shadow map value then pixel is in shadow float shadowFactor = sum / 16.0;
float shadow = getShadowFactor(ShadowMap, ShadowMapSampler, coords, realDepth); lighting = lerp(lighting, min(AmbientColor,lighting), 1-saturate(shadowFactor));
lighting = lerp(lighting, min(AmbientColor*2,lighting), saturate(shadow));
} }
} }

View file

@ -17,19 +17,19 @@ ChunkId::~ChunkId() {
delete m_chunkBytes; delete m_chunkBytes;
} }
ChunkId* ChunkId::FromString(const char* str) { std::unique_ptr<ChunkId> ChunkId::FromString(const char* str) {
return new ChunkId((char*)str, strlen(str)); return std::make_unique<ChunkId>((char*)str, strlen(str));
} }
ChunkId* ChunkId::FromString(string* str) { std::unique_ptr<ChunkId> ChunkId::FromString(string* str) {
return new ChunkId((char*)str->c_str(), str->length()); return std::make_unique<ChunkId>( (char*)str->c_str(), str->length());
} }
ChunkId* ChunkId::FromStream(BaseStream* stream) { std::unique_ptr<ChunkId> ChunkId::FromStream(BaseStream* stream) {
int idLength = LEB128::ReadInt32(stream); int idLength = LEB128::ReadInt32(stream);
char* buffer = (char*)malloc(idLength); char* buffer = (char*)malloc(idLength);
stream->Read(buffer, idLength); stream->Read(buffer, idLength);
ChunkId* chunk = new ChunkId(buffer, idLength); std::unique_ptr<ChunkId> chunk = std::make_unique<ChunkId>(buffer, idLength);
free(buffer); free(buffer);
return chunk; return chunk;
} }

View file

@ -1,9 +1,9 @@
#pragma once #pragma once
#include "LEB128.h" #include "LEB128.h"
#include "Streams.h" #include "Streams.h"
#include <memory>
struct ChunkId
typedef struct ChunkId
{ {
private: private:
byte* m_chunkBytes; byte* m_chunkBytes;
@ -14,11 +14,11 @@ public:
~ChunkId(); ~ChunkId();
static ChunkId* FromString(const char* str); static std::unique_ptr<ChunkId> FromString(const char* str);
static ChunkId* FromString(std::string* str); static std::unique_ptr<ChunkId> FromString(std::string* str);
static ChunkId* FromStream(BaseStream* stream); static std::unique_ptr<ChunkId> FromStream(BaseStream* stream);
void ToStream(BaseStream* stream); void ToStream(BaseStream* stream);

View file

@ -42,7 +42,7 @@ bool ChunkReader::IsValid() {
bool ChunkReader::ReadChunks(bool(*func)(ChunkId* parentChunkId, int maxSize, int arg), int arg) { bool ChunkReader::ReadChunks(bool(*func)(ChunkId* parentChunkId, int maxSize, int arg), int arg) {
do { do {
ChunkId* chunkId = ChunkId::FromStream(m_stream); std::unique_ptr<ChunkId> chunkId = ChunkId::FromStream(m_stream);
if (chunkId->EqualsTo(m_emptyChunk)) // End reached if (chunkId->EqualsTo(m_emptyChunk)) // End reached
break; break;
@ -53,7 +53,7 @@ bool ChunkReader::ReadChunks(bool(*func)(ChunkId* parentChunkId, int maxSize, in
bool chunkRecognized = false; bool chunkRecognized = false;
int startPos = m_stream->GetCurrentPosition(); int startPos = m_stream->GetCurrentPosition();
chunkRecognized = func(chunkId, chunkSize, arg); chunkRecognized = func(chunkId.get(), chunkSize, arg);
int readDataCount = m_stream->GetCurrentPosition() - startPos; int readDataCount = m_stream->GetCurrentPosition() - startPos;
// Adjust _stream position if necessary // Adjust _stream position if necessary
@ -66,7 +66,7 @@ bool ChunkReader::ReadChunks(bool(*func)(ChunkId* parentChunkId, int maxSize, in
bool ChunkReader::ReadChunks(std::function<bool(ChunkId*, long, int)> func, int arg) { bool ChunkReader::ReadChunks(std::function<bool(ChunkId*, long, int)> func, int arg) {
do { do {
ChunkId* chunkId = ChunkId::FromStream(m_stream); std::unique_ptr<ChunkId> chunkId = ChunkId::FromStream(m_stream);
if (chunkId->EqualsTo(m_emptyChunk)) // End reached if (chunkId->EqualsTo(m_emptyChunk)) // End reached
break; break;
@ -77,7 +77,7 @@ bool ChunkReader::ReadChunks(std::function<bool(ChunkId*, long, int)> func, int
bool chunkRecognized = false; bool chunkRecognized = false;
int startPos = m_stream->GetCurrentPosition(); int startPos = m_stream->GetCurrentPosition();
chunkRecognized = func(chunkId, chunkSize, arg); chunkRecognized = func(chunkId.get(), chunkSize, arg);
int readDataCount = m_stream->GetCurrentPosition() - startPos; int readDataCount = m_stream->GetCurrentPosition() - startPos;
// Adjust _stream position if necessary // Adjust _stream position if necessary

View file

@ -18,7 +18,7 @@ void LoadResolutionsInCombobox(HWND handle, int index)
SendMessageA(cbHandle, CB_RESETCONTENT, 0, 0); SendMessageA(cbHandle, CB_RESETCONTENT, 0, 0);
vector<RendererVideoAdapter>* adapters = g_Renderer.GetAdapters(); vector<RendererVideoAdapter>* adapters = g_Renderer.getAdapters();
RendererVideoAdapter* adapter = &(*adapters)[index]; RendererVideoAdapter* adapter = &(*adapters)[index];
for (int i = 0; i < adapter->DisplayModes.size(); i++) for (int i = 0; i < adapter->DisplayModes.size(); i++)
@ -44,7 +44,7 @@ void LoadAdaptersInCombobox(HWND handle)
SendMessageA(cbHandle, CB_RESETCONTENT, 0, 0); SendMessageA(cbHandle, CB_RESETCONTENT, 0, 0);
vector<RendererVideoAdapter>* adapters = g_Renderer.GetAdapters(); vector<RendererVideoAdapter>* adapters = g_Renderer.getAdapters();
for (int i = 0; i < adapters->size(); i++) for (int i = 0; i < adapters->size(); i++)
{ {
RendererVideoAdapter* adapter = &(*adapters)[i]; RendererVideoAdapter* adapter = &(*adapters)[i];
@ -140,7 +140,7 @@ BOOL CALLBACK DialogProc(HWND handle, UINT msg, WPARAM wParam, LPARAM lParam)
g_Configuration.EnableSound = (SendDlgItemMessage(handle, IDC_ENABLE_SOUNDS, BM_GETCHECK, 0, 0)); g_Configuration.EnableSound = (SendDlgItemMessage(handle, IDC_ENABLE_SOUNDS, BM_GETCHECK, 0, 0));
g_Configuration.Adapter = (SendDlgItemMessage(handle, IDC_GFXADAPTER, CB_GETCURSEL, 0, 0)); g_Configuration.Adapter = (SendDlgItemMessage(handle, IDC_GFXADAPTER, CB_GETCURSEL, 0, 0));
selectedMode = (SendDlgItemMessage(handle, IDC_RESOLUTION, CB_GETCURSEL, 0, 0)); selectedMode = (SendDlgItemMessage(handle, IDC_RESOLUTION, CB_GETCURSEL, 0, 0));
adapter = &(*g_Renderer.GetAdapters())[g_Configuration.Adapter]; adapter = &(*g_Renderer.getAdapters())[g_Configuration.Adapter];
mode = &(adapter->DisplayModes[selectedMode]); mode = &(adapter->DisplayModes[selectedMode]);
g_Configuration.Width = mode->Width; g_Configuration.Width = mode->Width;
g_Configuration.Height = mode->Height; g_Configuration.Height = mode->Height;
@ -285,8 +285,12 @@ bool SaveConfiguration()
return false; return false;
} }
if (SetDWORDRegKey(rootKey, REGKEY_REFRESH_RATE, g_Configuration.RefreshRate) != ERROR_SUCCESS) if(SetDWORDRegKey(rootKey, REGKEY_REFRESH_RATE, g_Configuration.RefreshRate) != ERROR_SUCCESS){
{ RegCloseKey(rootKey);
return false;
}
if(SetDWORDRegKey(rootKey, REGKEY_SHADOW_MAP, g_Configuration.shadowMapSize) != ERROR_SUCCESS){
RegCloseKey(rootKey); RegCloseKey(rootKey);
return false; return false;
} }
@ -327,6 +331,7 @@ void InitDefaultConfiguration()
g_Configuration.SfxVolume = 100; g_Configuration.SfxVolume = 100;
g_Configuration.Width = 1366; g_Configuration.Width = 1366;
g_Configuration.Height = 768; g_Configuration.Height = 768;
g_Configuration.shadowMapSize = 512;
} }
bool LoadConfiguration() bool LoadConfiguration()
@ -462,7 +467,7 @@ bool LoadConfiguration()
g_Configuration.SfxVolume = sfxVolume; g_Configuration.SfxVolume = sfxVolume;
g_Configuration.RefreshRate = refreshRate; g_Configuration.RefreshRate = refreshRate;
g_Configuration.SoundDevice = soundDevice; g_Configuration.SoundDevice = soundDevice;
g_Configuration.shadowMapSize = 512;
// Set legacy variables // Set legacy variables
//OptionAutoTarget = autoTarget; //OptionAutoTarget = autoTarget;
GlobalMusicVolume = musicVolume; GlobalMusicVolume = musicVolume;

View file

@ -48,6 +48,7 @@
#define REGKEY_JWLK "JWlk" #define REGKEY_JWLK "JWlk"
#define REGKEY_REFRESH_RATE "RefreshRate" #define REGKEY_REFRESH_RATE "RefreshRate"
#define REGKEY_SOUND_DEVICE "SoundDevice" #define REGKEY_SOUND_DEVICE "SoundDevice"
#define REGKEY_SHADOW_MAP "ShadowMap"
typedef struct GameConfiguration { typedef struct GameConfiguration {
int Width; int Width;
@ -77,6 +78,7 @@ typedef struct GameConfiguration {
int JoyLook; int JoyLook;
int JoyRoll; int JoyRoll;
int JoyWalk; int JoyWalk;
int shadowMapSize = 1024;
}; };
void LoadResolutionsInCombobox(HWND handle, int index); void LoadResolutionsInCombobox(HWND handle, int index);

View file

@ -306,14 +306,14 @@ int S_UpdateInput()// (F)
Lara.requestGunType = WEAPON_REVOLVER; Lara.requestGunType = WEAPON_REVOLVER;
if (KeyMap[DIK_4] && Lara.Weapons[WEAPON_UZI].Present == true) if (KeyMap[DIK_4] && Lara.Weapons[WEAPON_UZI].Present == true)
Lara.requestGunType = WEAPON_UZI; Lara.requestGunType = WEAPON_UZI;
/* if (KeyMap[DIK_5] && Lara.Weapons[WEAPON_HARPOON_GUN].Present == true) if (KeyMap[DIK_5] && Lara.Weapons[WEAPON_HARPOON_GUN].Present == true)
Lara.requestGunType = WEAPON_HARPOON_GUN;*/ Lara.requestGunType = WEAPON_HARPOON_GUN;
if (KeyMap[DIK_6] && Lara.Weapons[WEAPON_HK].Present == true) if (KeyMap[DIK_6] && Lara.Weapons[WEAPON_HK].Present == true)
Lara.requestGunType = WEAPON_HK; Lara.requestGunType = WEAPON_HK;
/* if (KeyMap[DIK_7] && Lara.Weapons[WEAPON_ROCKET_LAUNCHER].Present == true) if (KeyMap[DIK_7] && Lara.Weapons[WEAPON_ROCKET_LAUNCHER].Present == true)
Lara.requestGunType = WEAPON_ROCKET_LAUNCHER; Lara.requestGunType = WEAPON_ROCKET_LAUNCHER;
if (KeyMap[DIK_8] && Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Present == true) if (KeyMap[DIK_8] && Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Present == true)
Lara.requestGunType = WEAPON_GRENADE_LAUNCHER*/ Lara.requestGunType = WEAPON_GRENADE_LAUNCHER;
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
if (KeyMap[DIK_0]) if (KeyMap[DIK_0])

View file

@ -342,6 +342,10 @@ void LoadObjects()
StaticObjects[meshID].collisionBox.Z2 = ReadInt16(); StaticObjects[meshID].collisionBox.Z2 = ReadInt16();
StaticObjects[meshID].flags = (short)ReadInt16(); StaticObjects[meshID].flags = (short)ReadInt16();
StaticObjects[meshID].shatterType = (short)ReadInt16();
StaticObjects[meshID].shatterDamage = (short)ReadInt16();
StaticObjects[meshID].shatterSound = (short)ReadInt16();
} }
// HACK: to remove after decompiling LoadSprites // HACK: to remove after decompiling LoadSprites
@ -631,6 +635,7 @@ void ReadRooms()
mesh.shade = ReadUInt16(); mesh.shade = ReadUInt16();
mesh.flags = ReadUInt16(); mesh.flags = ReadUInt16();
mesh.staticNumber = ReadUInt16(); mesh.staticNumber = ReadUInt16();
mesh.hitPoints = ReadInt16();
room.mesh.push_back(mesh); room.mesh.push_back(mesh);
} }
@ -695,7 +700,7 @@ void FreeLevel()
g_Level.Zones[j][i].clear(); g_Level.Zones[j][i].clear();
} }
} }
g_Renderer.FreeRendererData(); g_Renderer.freeRendererData();
g_GameScript->FreeLevelScripts(); g_GameScript->FreeLevelScripts();
} }
@ -807,7 +812,7 @@ unsigned CALLBACK LoadLevel(void* data)
LevelFilePtr = NULL; LevelFilePtr = NULL;
char* baseLevelDataPtr = NULL; char* baseLevelDataPtr = NULL;
g_Renderer.UpdateProgress(0); g_Renderer.updateProgress(0);
LevelFilePtr = FileOpen(filename); LevelFilePtr = FileOpen(filename);
if (LevelFilePtr) if (LevelFilePtr)
@ -835,21 +840,21 @@ unsigned CALLBACK LoadLevel(void* data)
LoadTextures(); LoadTextures();
g_Renderer.UpdateProgress(20); g_Renderer.updateProgress(20);
WeatherType = ReadInt8(); WeatherType = ReadInt8();
LaraDrawType = ReadInt8(); LaraDrawType = ReadInt8();
LoadRooms(); LoadRooms();
g_Renderer.UpdateProgress(40); g_Renderer.updateProgress(40);
LoadObjects(); LoadObjects();
g_Renderer.UpdateProgress(50); g_Renderer.updateProgress(50);
LoadSprites(); LoadSprites();
LoadCameras(); LoadCameras();
LoadSoundEffects(); LoadSoundEffects();
g_Renderer.UpdateProgress(60); g_Renderer.updateProgress(60);
LoadBoxes(); LoadBoxes();
@ -857,12 +862,12 @@ unsigned CALLBACK LoadLevel(void* data)
LoadAnimatedTextures(); LoadAnimatedTextures();
LoadTextureInfos(); LoadTextureInfos();
g_Renderer.UpdateProgress(70); g_Renderer.updateProgress(70);
LoadItems(); LoadItems();
LoadAIObjects(); LoadAIObjects();
LoadSamples(); LoadSamples();
g_Renderer.UpdateProgress(80); g_Renderer.updateProgress(80);
free(baseLevelDataPtr); free(baseLevelDataPtr);
LevelDataPtr = NULL; LevelDataPtr = NULL;
@ -873,7 +878,7 @@ unsigned CALLBACK LoadLevel(void* data)
return false; return false;
} }
g_Renderer.UpdateProgress(90); g_Renderer.updateProgress(90);
g_Renderer.PrepareDataForTheRenderer(); g_Renderer.PrepareDataForTheRenderer();
// Initialise the game // Initialise the game
@ -894,7 +899,7 @@ unsigned CALLBACK LoadLevel(void* data)
// Level loaded // Level loaded
IsLevelLoading = false; IsLevelLoading = false;
g_Renderer.UpdateProgress(100); g_Renderer.updateProgress(100);
_endthreadex(1); _endthreadex(1);
@ -1001,7 +1006,7 @@ int S_LoadLevelFile(int levelIndex)
wchar_t loadscreenFileName[80]; wchar_t loadscreenFileName[80];
std::mbstowcs(loadscreenFileName, level->LoadScreenFileName.c_str(),80); std::mbstowcs(loadscreenFileName, level->LoadScreenFileName.c_str(),80);
std::wstring loadScreenFile = std::wstring(loadscreenFileName); std::wstring loadScreenFile = std::wstring(loadscreenFileName);
g_Renderer.DrawLoadingScreen(loadScreenFile); g_Renderer.renderLoadingScreen(loadScreenFile);
while (IsLevelLoading); while (IsLevelLoading);

View file

@ -9,6 +9,7 @@ enum HitEffectEnum
HIT_BLOOD, HIT_BLOOD,
HIT_SMOKE, HIT_SMOKE,
HIT_FRAGMENT, HIT_FRAGMENT,
HIT_SPECIAL,
MAX_HIT_EFFECT MAX_HIT_EFFECT
}; };
@ -59,11 +60,19 @@ struct STATIC_INFO
int flags; int flags;
BOUNDING_BOX visibilityBox; BOUNDING_BOX visibilityBox;
BOUNDING_BOX collisionBox; BOUNDING_BOX collisionBox;
int shatterType;
int shatterDamage;
int shatterSound;
}; };
#define MAX_STATICS 1000 #define MAX_STATICS 1000
constexpr auto SF_NO_COLLISION = 0x01;
constexpr auto SF_SHATTERABLE = 0x02;
constexpr auto GRAVITY = 6; constexpr auto GRAVITY = 6;
constexpr auto SWAMP_GRAVITY = 2; constexpr auto SWAMP_GRAVITY = 2;
constexpr auto SHT_NONE = 0;
constexpr auto SHT_EXPLODE = 1;
constexpr auto SHT_FRAGMENT = 2;
extern OBJECT_INFO Objects[ID_NUMBER_OBJECTS]; extern OBJECT_INFO Objects[ID_NUMBER_OBJECTS];
extern STATIC_INFO StaticObjects[MAX_STATICS]; extern STATIC_INFO StaticObjects[MAX_STATICS];

View file

@ -41,6 +41,10 @@ bool newSkipFramesValue = false;
bool newSkipLoopValue = false; bool newSkipLoopValue = false;
bool newLockInputValue = false; bool newLockInputValue = false;
#if _DEBUG
string commit;
#endif
int lua_exception_handler(lua_State* L, sol::optional<const exception&> maybe_exception, sol::string_view description) int lua_exception_handler(lua_State* L, sol::optional<const exception&> maybe_exception, sol::string_view description)
{ {
return luaL_error(L, description.data()); return luaL_error(L, description.data());
@ -69,10 +73,10 @@ void CALLBACK HandleWmCommand(unsigned short wParam)
if (!IsLevelLoading) if (!IsLevelLoading)
{ {
SuspendThread((HANDLE)ThreadHandle); SuspendThread((HANDLE)ThreadHandle);
g_Renderer.ToggleFullScreen(); g_Renderer.toggleFullScreen();
ResumeThread((HANDLE)ThreadHandle); ResumeThread((HANDLE)ThreadHandle);
if (g_Renderer.IsFullsScreen()) if (g_Renderer.isFullsScreen())
{ {
SetCursor(0); SetCursor(0);
ShowCursor(false); ShowCursor(false);
@ -86,6 +90,59 @@ void CALLBACK HandleWmCommand(unsigned short wParam)
} }
} }
void getCurrentCommit() {
LPSTR cmdLine = {TEXT("git.exe log -1 --oneline")};
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
HANDLE hStdOutRd, hStdOutWr;
HANDLE hStdErrRd, hStdErrWr;
if(!CreatePipe(&hStdOutRd, &hStdOutWr, &sa, 0)){
// error handling...
}
if(!CreatePipe(&hStdErrRd, &hStdErrWr, &sa, 0)){
// error handling...
}
SetHandleInformation(hStdOutRd, HANDLE_FLAG_INHERIT, 0);
SetHandleInformation(hStdErrRd, HANDLE_FLAG_INHERIT, 0);
STARTUPINFO si = {};
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.hStdOutput = hStdOutWr;
si.hStdError = hStdErrWr;
PROCESS_INFORMATION pi = {};
if(!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)){
// error handling...
} else{
CHAR buf[256];
DWORD n;
BOOL success = ReadFile(hStdOutRd, buf, 256, &n, NULL);
if(!success || n == 0){
std::cout << "Failed to call ReadFile" << std::endl;
}
commit = std::string(buf, buf + n);
// read from hStdOutRd and hStdErrRd as needed until the process is terminated...
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
CloseHandle(hStdOutRd);
CloseHandle(hStdOutWr);
CloseHandle(hStdErrRd);
CloseHandle(hStdErrWr);
}
void HandleScriptMessage(WPARAM wParam) void HandleScriptMessage(WPARAM wParam)
{ {
string ErrorMessage; string ErrorMessage;
@ -191,6 +248,8 @@ LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{ {
if constexpr (DebugBuild)
getCurrentCommit();
int RetVal; int RetVal;
int n; int n;
@ -216,9 +275,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
// Clear Application Structure // Clear Application Structure
memset(&App, 0, sizeof(WINAPP)); memset(&App, 0, sizeof(WINAPP));
_CrtSetReportMode(0, 2);
_CrtSetDbgFlag(-1);
// Initialise the new scripting system // Initialise the new scripting system
sol::state luaState; sol::state luaState;
luaState.open_libraries(sol::lib::base); luaState.open_libraries(sol::lib::base);

View file

@ -22,6 +22,9 @@ extern unsigned int ThreadID;
extern uintptr_t ThreadHandle; extern uintptr_t ThreadHandle;
extern HACCEL hAccTable; extern HACCEL hAccTable;
extern HWND WindowsHandle; extern HWND WindowsHandle;
#if _DEBUG
extern std::string commit;
#endif
// return handle // return handle
#define BeginThread(function, threadid) _beginthreadex(0, 0, &function, 0, 0, &threadid) #define BeginThread(function, threadid) _beginthreadex(0, 0, &function, 0, 0, &threadid)
@ -33,3 +36,4 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
void WinClose(); void WinClose();
LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void CALLBACK HandleWmCommand(unsigned short wParam); void CALLBACK HandleWmCommand(unsigned short wParam);
void getCurrentCommit();

View file

@ -15,7 +15,7 @@
<ProjectGuid>{15AB0220-541C-4DA1-94EB-ED3C47E4582E}</ProjectGuid> <ProjectGuid>{15AB0220-541C-4DA1-94EB-ED3C47E4582E}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>TR5Main</RootNamespace> <RootNamespace>TR5Main</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -158,7 +158,9 @@ xcopy /Y "$(ProjectDir)Scripting\Scripts\*.lua" "$(TargetDir)\Scripts"</Command>
<ClInclude Include="Game\room.h" /> <ClInclude Include="Game\room.h" />
<ClInclude Include="Game\smoke.h" /> <ClInclude Include="Game\smoke.h" />
<ClInclude Include="Game\spark.h" /> <ClInclude Include="Game\spark.h" />
<ClInclude Include="Objects\TR4\Entity\tr4_enemy_jeep.h" />
<ClInclude Include="Renderer\ConstantBuffers\SpriteBuffer.h" /> <ClInclude Include="Renderer\ConstantBuffers\SpriteBuffer.h" />
<ClInclude Include="Renderer\ConstantBuffer\ConstantBuffer.h" />
<ClInclude Include="Renderer\Quad\RenderQuad.h" /> <ClInclude Include="Renderer\Quad\RenderQuad.h" />
<ClInclude Include="Libs\bass\bass.h" /> <ClInclude Include="Libs\bass\bass.h" />
<ClInclude Include="Libs\bass\bassmix.h" /> <ClInclude Include="Libs\bass\bassmix.h" />
@ -341,6 +343,8 @@ xcopy /Y "$(ProjectDir)Scripting\Scripts\*.lua" "$(TargetDir)\Scripts"</Command>
<ClInclude Include="Renderer\Utils.h" /> <ClInclude Include="Renderer\Utils.h" />
<ClInclude Include="Renderer\RenderTarget2D\RenderTarget2D.h" /> <ClInclude Include="Renderer\RenderTarget2D\RenderTarget2D.h" />
<ClInclude Include="Renderer\RenderTargetCube\RenderTargetCube.h" /> <ClInclude Include="Renderer\RenderTargetCube\RenderTargetCube.h" />
<ClInclude Include="Renderer\RenderTargetCubeArray\RenderTargetCubeArray.h" />
<ClInclude Include="Renderer\RenderPipelineState\RenderPipelineState.h" />
<ClInclude Include="Scripting\LanguageScript.h" /> <ClInclude Include="Scripting\LanguageScript.h" />
<ClInclude Include="Renderer\Renderer11.h" /> <ClInclude Include="Renderer\Renderer11.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
@ -440,6 +444,7 @@ xcopy /Y "$(ProjectDir)Scripting\Scripts\*.lua" "$(TargetDir)\Scripts"</Command>
<ClCompile Include="Game\trmath.cpp" /> <ClCompile Include="Game\trmath.cpp" />
<ClCompile Include="Game\smoke.cpp" /> <ClCompile Include="Game\smoke.cpp" />
<ClCompile Include="Game\spark.cpp" /> <ClCompile Include="Game\spark.cpp" />
<ClCompile Include="Objects\TR4\Entity\tr4_enemy_jeep.cpp" />
<ClCompile Include="Renderer\Quad\RenderQuad.cpp"> <ClCompile Include="Renderer\Quad\RenderQuad.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
</ClCompile> </ClCompile>
@ -595,6 +600,8 @@ xcopy /Y "$(ProjectDir)Scripting\Scripts\*.lua" "$(TargetDir)\Scripts"</Command>
<ClCompile Include="Renderer\Utils.cpp" /> <ClCompile Include="Renderer\Utils.cpp" />
<ClCompile Include="Renderer\RenderTarget2D\RenderTarget2D.cpp" /> <ClCompile Include="Renderer\RenderTarget2D\RenderTarget2D.cpp" />
<ClCompile Include="Renderer\RenderTargetCube\RenderTargetCube.cpp" /> <ClCompile Include="Renderer\RenderTargetCube\RenderTargetCube.cpp" />
<ClCompile Include="Renderer\RenderTargetCubeArray\RenderTargetCubeArray.cpp" />
<ClCompile Include="Renderer\RenderPipelineState\RenderPipelineState.cpp" />
<ClCompile Include="Scripting\LanguageScript.cpp" /> <ClCompile Include="Scripting\LanguageScript.cpp" />
<ClCompile Include="Objects\TR4\Entity\tr4_demigod.cpp" /> <ClCompile Include="Objects\TR4\Entity\tr4_demigod.cpp" />
<ClCompile Include="Objects\TR4\Entity\tr4_guide.cpp" /> <ClCompile Include="Objects\TR4\Entity\tr4_guide.cpp" />

View file

@ -879,6 +879,18 @@
<ClInclude Include="Game\Lara\lara_cheat.h"> <ClInclude Include="Game\Lara\lara_cheat.h">
<Filter>File di intestazione</Filter> <Filter>File di intestazione</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Objects\TR4\Entity\tr4_enemy_jeep.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="Renderer\ConstantBuffer\ConstantBuffer.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="Renderer\RenderTargetCubeArray\RenderTargetCubeArray.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="Renderer\RenderPipelineState\RenderPipelineState.h">
<Filter>File di intestazione</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Game\box.cpp"> <ClCompile Include="Game\box.cpp">
@ -1607,6 +1619,15 @@
<ClCompile Include="Game\Lara\lara_cheat.cpp"> <ClCompile Include="Game\Lara\lara_cheat.cpp">
<Filter>File di origine</Filter> <Filter>File di origine</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Objects\TR4\Entity\tr4_enemy_jeep.cpp">
<Filter>File di origine</Filter>
</ClCompile>
<ClCompile Include="Renderer\RenderTargetCubeArray\RenderTargetCubeArray.cpp">
<Filter>File di origine</Filter>
</ClCompile>
<ClCompile Include="Renderer\RenderPipelineState\RenderPipelineState.cpp">
<Filter>File di origine</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />

View file

@ -44,6 +44,7 @@
#include "bass_fx.h" #include "bass_fx.h"
#include "sol.hpp" #include "sol.hpp"
#include "memory/malloc.h" #include "memory/malloc.h"
#include "Game/debug/debug.h"
using namespace DirectX; using namespace DirectX;
using namespace DirectX::SimpleMath; using namespace DirectX::SimpleMath;