Skip to content
This repository was archived by the owner on Jan 5, 2024. It is now read-only.

Commit 23a3f15

Browse files
committed
Review changes
1 parent 74bcde8 commit 23a3f15

File tree

4 files changed

+148
-117
lines changed

4 files changed

+148
-117
lines changed

Managers/FrameMan.cpp

Lines changed: 98 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,34 @@ namespace RTE {
725725
return 0;
726726
}
727727

728+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
729+
730+
void FrameMan::UpdateScreenOffsetForSplitScreen(char playerScreen, Vector &screenOffset) {
731+
switch (playerScreen) {
732+
case 1:
733+
// If both splits, or just VSplit, then in upper right quadrant
734+
if ((m_VSplit && !m_HSplit) || (m_VSplit && m_HSplit)) {
735+
screenOffset.SetIntXY(GetResX() / 2, 0);
736+
} else {
737+
// If only HSplit, then lower left quadrant
738+
screenOffset.SetIntXY(0, GetResY() / 2);
739+
}
740+
break;
741+
case 2:
742+
// Always lower left quadrant
743+
screenOffset.SetIntXY(0, GetResY() / 2);
744+
break;
745+
case 3:
746+
// Always lower right quadrant
747+
screenOffset.SetIntXY(GetResX() / 2, GetResY() / 2);
748+
break;
749+
default:
750+
// Always upper left corner
751+
screenOffset.SetIntXY(0, 0);
752+
break;
753+
}
754+
}
755+
728756
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
729757

730758
void FrameMan::Draw() {
@@ -800,65 +828,21 @@ namespace RTE {
800828
// Enable clipping on the draw bitmap
801829
set_clip_state(pDrawScreen, 1);
802830

803-
DrawScreenText(whichScreen, pPlayerGUIBitmap);
804-
805-
// If we are dealing with split screens, then deal with the fact that we need to draw the player screens to different locations on the final buffer
806-
// The position of the current draw screen on the final screen
831+
DrawScreenText(playerScreen, playerGUIBitmap);
832+
833+
// The position of the current draw screen on the backbuffer
807834
Vector screenOffset;
808835

809-
if (screenCount > 1) {
810-
switch (whichScreen) {
811-
case 1:
812-
// If both splits, or just VSplit, then in upper right quadrant
813-
if ((m_VSplit && !m_HSplit) || (m_VSplit && m_HSplit)) {
814-
screenOffset.SetIntXY(GetResX() / 2, 0);
815-
} else {
816-
// If only HSplit, then lower left quadrant
817-
screenOffset.SetIntXY(0, GetResY() / 2);
818-
}
819-
break;
820-
case 2:
821-
// Always lower left quadrant
822-
screenOffset.SetIntXY(0, GetResY() / 2);
823-
break;
824-
case 3:
825-
// Always lower right quadrant
826-
screenOffset.SetIntXY(GetResX() / 2, GetResY() / 2);
827-
break;
828-
default:
829-
// Always upper left corner
830-
screenOffset.SetIntXY(0, 0);
831-
break;
832-
}
833-
}
834-
835-
DrawScreenFlash(whichScreen, pDrawScreenGUI);
836-
837-
// Draw the intermediate draw splitscreen to the appropriate spot on the back buffer
838-
if (!IsInMultiplayerMode()) { blit(pDrawScreen, m_BackBuffer8, 0, 0, screenOffset.GetFloorIntX(), screenOffset.GetFloorIntY(), pDrawScreen->w, pDrawScreen->h); }
839-
840-
// Add the player screen's effects to the total screen effects list so they can be drawn in post processing
841-
if (!IsInMultiplayerMode()) {
842-
int occX = g_SceneMan.GetScreenOcclusion(whichScreen).GetFloorIntX();
843-
int occY = g_SceneMan.GetScreenOcclusion(whichScreen).GetFloorIntY();
844-
845-
// Copy post effects received by client if in network mode
846-
if (m_DrawNetworkBackBuffer) { g_PostProcessMan.GetNetworkPostEffectsList(0, screenRelativeEffects); }
847-
848-
// Adjust for the player screen's position on the final buffer
849-
for (list<PostEffect>::iterator eItr = screenRelativeEffects.begin(); eItr != screenRelativeEffects.end(); ++eItr) {
850-
// Make sure we won't be adding any effects to a part of the screen that is occluded by menus and such
851-
if ((*eItr).m_Pos.m_X > occX && (*eItr).m_Pos.m_Y > occY && (*eItr).m_Pos.m_X < pDrawScreen->w + occX && (*eItr).m_Pos.m_Y < pDrawScreen->h + occY) {
852-
g_PostProcessMan.GetPostScreenEffectsList()->push_back(PostEffect((*eItr).m_Pos + screenOffset, (*eItr).m_Bitmap, (*eItr).m_BitmapHash, (*eItr).m_Strength, (*eItr).m_Angle));
853-
}
854-
}
836+
// If we are dealing with split screens, then deal with the fact that we need to draw the player screens to different locations on the final buffer
837+
if (screenCount > 1) { UpdateScreenOffsetForSplitScreen(playerScreen, screenOffset); }
855838

856-
// Adjust glow areas for the player screen's position on the final buffer
857-
for (list<Box>::iterator bItr = screenRelativeGlowBoxes.begin(); bItr != screenRelativeGlowBoxes.end(); ++bItr) {
858-
g_PostProcessMan.GetPostScreenGlowBoxesList()->push_back(*bItr);
859-
// Adjust each added glow area for the player screen's position on the final buffer
860-
g_PostProcessMan.GetPostScreenGlowBoxesList()->back().m_Corner += screenOffset;
861-
}
839+
DrawScreenFlash(playerScreen, drawScreenGUI);
840+
841+
if (!IsInMultiplayerMode()) {
842+
// Draw the intermediate draw splitscreen to the appropriate spot on the back buffer
843+
blit(drawScreen, m_BackBuffer8, 0, 0, screenOffset.GetFloorIntX(), screenOffset.GetFloorIntY(), drawScreen->w, drawScreen->h);
844+
845+
g_PostProcessMan.AdjustEffectsPosToPlayerScreen(playerScreen, drawScreen, screenOffset, screenRelativeEffects, screenRelativeGlowBoxes);
862846
}
863847
}
864848

@@ -867,7 +851,6 @@ namespace RTE {
867851

868852
if (!IsInMultiplayerMode()) {
869853
// Draw separating lines for split-screens
870-
acquire_bitmap(m_BackBuffer8);
871854
if (m_HSplit) {
872855
hline(m_BackBuffer8, 0, (m_BackBuffer8->h / 2) - 1, m_BackBuffer8->w - 1, m_AlmostBlackColor);
873856
hline(m_BackBuffer8, 0, (m_BackBuffer8->h / 2), m_BackBuffer8->w - 1, m_AlmostBlackColor);
@@ -889,62 +872,7 @@ namespace RTE {
889872
}
890873
}
891874

892-
if (IsInMultiplayerMode()) {
893-
// Blit all four internal player screens onto the backbuffer
894-
for (short i = 0; i < c_MaxScreenCount; i++) {
895-
int dx = 0;
896-
int dy = 0;
897-
int dw = m_BackBuffer8->w / 2;
898-
int dh = m_BackBuffer8->h / 2;
899-
900-
switch (i) {
901-
case 1:
902-
dx = dw;
903-
break;
904-
case 2:
905-
dy = dh;
906-
break;
907-
case 3:
908-
dx = dw;
909-
dy = dh;
910-
break;
911-
default:
912-
break;
913-
}
914-
915-
m_NetworkBitmapIsLocked[i] = true;
916-
blit(m_NetworkBackBufferIntermediate8[m_NetworkFrameCurrent][i], m_NetworkBackBufferFinal8[m_NetworkFrameCurrent][i], 0, 0, 0, 0, m_NetworkBackBufferFinal8[m_NetworkFrameCurrent][i]->w, m_NetworkBackBufferFinal8[m_NetworkFrameCurrent][i]->h);
917-
blit(m_NetworkBackBufferIntermediateGUI8[m_NetworkFrameCurrent][i], m_NetworkBackBufferFinalGUI8[m_NetworkFrameCurrent][i], 0, 0, 0, 0, m_NetworkBackBufferFinalGUI8[m_NetworkFrameCurrent][i]->w, m_NetworkBackBufferFinalGUI8[m_NetworkFrameCurrent][i]->h);
918-
m_NetworkBitmapIsLocked[i] = false;
919-
920-
#if defined DEBUG_BUILD || defined MIN_DEBUG_BUILD
921-
// Draw all player's screen into one
922-
if (g_UInputMan.KeyHeld(KEY_5)) {
923-
stretch_blit(m_NetworkBackBufferFinal8[m_NetworkFrameCurrent][i], m_BackBuffer8, 0, 0, m_NetworkBackBufferFinal8[m_NetworkFrameReady][i]->w, m_NetworkBackBufferFinal8[m_NetworkFrameReady][i]->h, dx, dy, dw, dh);
924-
}
925-
#endif
926-
}
927-
928-
#if defined DEBUG_BUILD || defined MIN_DEBUG_BUILD
929-
if (g_UInputMan.KeyHeld(KEY_1)) {
930-
stretch_blit(m_NetworkBackBufferFinal8[0][0], m_BackBuffer8, 0, 0, m_NetworkBackBufferFinal8[m_NetworkFrameReady][0]->w, m_NetworkBackBufferFinal8[m_NetworkFrameReady][0]->h, 0, 0, m_BackBuffer8->w, m_BackBuffer8->h);
931-
}
932-
if (g_UInputMan.KeyHeld(KEY_2)) {
933-
stretch_blit(m_NetworkBackBufferFinal8[1][0], m_BackBuffer8, 0, 0, m_NetworkBackBufferFinal8[m_NetworkFrameReady][1]->w, m_NetworkBackBufferFinal8[m_NetworkFrameReady][1]->h, 0, 0, m_BackBuffer8->w, m_BackBuffer8->h);
934-
}
935-
if (g_UInputMan.KeyHeld(KEY_3)) {
936-
stretch_blit(m_NetworkBackBufferFinal8[m_NetworkFrameReady][2], m_BackBuffer8, 0, 0, m_NetworkBackBufferFinal8[m_NetworkFrameReady][2]->w, m_NetworkBackBufferFinal8[m_NetworkFrameReady][2]->h, 0, 0, m_BackBuffer8->w, m_BackBuffer8->h);
937-
}
938-
if (g_UInputMan.KeyHeld(KEY_4)) {
939-
stretch_blit(m_NetworkBackBufferFinal8[m_NetworkFrameReady][3], m_BackBuffer8, 0, 0, m_NetworkBackBufferFinal8[m_NetworkFrameReady][3]->w, m_NetworkBackBufferFinal8[m_NetworkFrameReady][3]->h, 0, 0, m_BackBuffer8->w, m_BackBuffer8->h);
940-
}
941-
#endif
942-
943-
// Rendering complete, we can finally mark current frame as ready
944-
// This is needed to make rendering look totally atomic for the server pulling data in separate threads
945-
m_NetworkFrameReady = m_NetworkFrameCurrent;
946-
m_NetworkFrameCurrent = (m_NetworkFrameCurrent == 0) ? 1 : 0;
947-
}
875+
if (IsInMultiplayerMode()) { PrepareFrameForNetwork(); }
948876

949877
if (g_InActivity) { g_PostProcessMan.PostProcess(); }
950878

@@ -956,8 +884,6 @@ namespace RTE {
956884
vline(m_BackBuffer8, 0, 0, g_SceneMan.GetSceneHeight(), 5);
957885
#endif
958886

959-
release_bitmap(m_BackBuffer8);
960-
961887
// Reset the frame timer so we can measure how much it takes until next frame being drawn
962888
g_PerformanceMan.ResetFrameTimer();
963889
}
@@ -1094,4 +1020,61 @@ namespace RTE {
10941020
}
10951021
}
10961022
}
1023+
1024+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1025+
1026+
void FrameMan::PrepareFrameForNetwork() {
1027+
unsigned short dx = 0;
1028+
unsigned short dy = 0;
1029+
unsigned short dw = m_BackBuffer8->w / 2;
1030+
unsigned short dh = m_BackBuffer8->h / 2;
1031+
1032+
// Blit all four internal player screens onto the backbuffer
1033+
for (unsigned char i = 0; i < c_MaxScreenCount; i++) {
1034+
switch (i) {
1035+
case 1:
1036+
dx = dw;
1037+
break;
1038+
case 2:
1039+
dy = dh;
1040+
break;
1041+
case 3:
1042+
dx = dw;
1043+
dy = dh;
1044+
break;
1045+
default:
1046+
break;
1047+
}
1048+
1049+
m_NetworkBitmapIsLocked[i] = true;
1050+
blit(m_NetworkBackBufferIntermediate8[m_NetworkFrameCurrent][i], m_NetworkBackBufferFinal8[m_NetworkFrameCurrent][i], 0, 0, 0, 0, m_NetworkBackBufferFinal8[m_NetworkFrameCurrent][i]->w, m_NetworkBackBufferFinal8[m_NetworkFrameCurrent][i]->h);
1051+
blit(m_NetworkBackBufferIntermediateGUI8[m_NetworkFrameCurrent][i], m_NetworkBackBufferFinalGUI8[m_NetworkFrameCurrent][i], 0, 0, 0, 0, m_NetworkBackBufferFinalGUI8[m_NetworkFrameCurrent][i]->w, m_NetworkBackBufferFinalGUI8[m_NetworkFrameCurrent][i]->h);
1052+
m_NetworkBitmapIsLocked[i] = false;
1053+
1054+
#if defined DEBUG_BUILD || defined MIN_DEBUG_BUILD
1055+
// Draw all player's screen into one
1056+
if (g_UInputMan.KeyHeld(KEY_5)) {
1057+
stretch_blit(m_NetworkBackBufferFinal8[m_NetworkFrameCurrent][i], m_BackBuffer8, 0, 0, m_NetworkBackBufferFinal8[m_NetworkFrameReady][i]->w, m_NetworkBackBufferFinal8[m_NetworkFrameReady][i]->h, dx, dy, dw, dh);
1058+
}
1059+
#endif
1060+
}
1061+
1062+
#if defined DEBUG_BUILD || defined MIN_DEBUG_BUILD
1063+
if (g_UInputMan.KeyHeld(KEY_1)) {
1064+
stretch_blit(m_NetworkBackBufferFinal8[0][0], m_BackBuffer8, 0, 0, m_NetworkBackBufferFinal8[m_NetworkFrameReady][0]->w, m_NetworkBackBufferFinal8[m_NetworkFrameReady][0]->h, 0, 0, m_BackBuffer8->w, m_BackBuffer8->h);
1065+
}
1066+
if (g_UInputMan.KeyHeld(KEY_2)) {
1067+
stretch_blit(m_NetworkBackBufferFinal8[1][0], m_BackBuffer8, 0, 0, m_NetworkBackBufferFinal8[m_NetworkFrameReady][1]->w, m_NetworkBackBufferFinal8[m_NetworkFrameReady][1]->h, 0, 0, m_BackBuffer8->w, m_BackBuffer8->h);
1068+
}
1069+
if (g_UInputMan.KeyHeld(KEY_3)) {
1070+
stretch_blit(m_NetworkBackBufferFinal8[m_NetworkFrameReady][2], m_BackBuffer8, 0, 0, m_NetworkBackBufferFinal8[m_NetworkFrameReady][2]->w, m_NetworkBackBufferFinal8[m_NetworkFrameReady][2]->h, 0, 0, m_BackBuffer8->w, m_BackBuffer8->h);
1071+
}
1072+
if (g_UInputMan.KeyHeld(KEY_4)) {
1073+
stretch_blit(m_NetworkBackBufferFinal8[m_NetworkFrameReady][3], m_BackBuffer8, 0, 0, m_NetworkBackBufferFinal8[m_NetworkFrameReady][3]->w, m_NetworkBackBufferFinal8[m_NetworkFrameReady][3]->h, 0, 0, m_BackBuffer8->w, m_BackBuffer8->h);
1074+
}
1075+
#endif
1076+
// Rendering complete, we can finally mark current frame as ready. This is needed to make rendering look totally atomic for the server pulling data in separate threads.
1077+
m_NetworkFrameReady = m_NetworkFrameCurrent;
1078+
m_NetworkFrameCurrent = (m_NetworkFrameCurrent == 0) ? 1 : 0;
1079+
}
10971080
}

Managers/FrameMan.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,13 @@ namespace RTE {
654654
#pragma endregion
655655

656656
#pragma region Draw Breakdown
657+
/// <summary>
658+
/// Updates the drawing position of each player screen on the backbuffer when split screen is active. This is called during Draw().
659+
/// </summary>
660+
/// <param name="playerScreen">The player screen to update offset for.</param>
661+
/// <param name="screenOffset">Vector representing the screen offset.</param>
662+
void UpdateScreenOffsetForSplitScreen(char playerScreen, Vector &screenOffset);
663+
657664
/// <summary>
658665
/// Draws all the text messages to the specified player screen. This is called during Draw().
659666
/// </summary>
@@ -666,7 +673,12 @@ namespace RTE {
666673
/// </summary>
667674
/// <param name="playerScreenToFlash">The player screen the flash effect will be shown to.</param>
668675
/// <param name="guiBitmap">The bitmap the flash effect will be drawn on.</param>
669-
void DrawScreenFlash(short playerScreen, BITMAP *playerGUIBitmap);
676+
void DrawScreenFlash(char playerScreen, BITMAP *playerGUIBitmap);
677+
678+
/// <summary>
679+
/// Renders current frame and marks it ready for network transmission. This is called during Draw().
680+
/// </summary>
681+
void PrepareFrameForNetwork();
670682
#pragma endregion
671683

672684
#pragma region Screen Capture

Managers/PostProcessMan.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,33 @@ namespace RTE {
6464

6565
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6666

67-
void PostProcessMan::RegisterPostEffect(const Vector &effectPos, BITMAP *effect, size_t hash, int strength, float angle) {
67+
void PostProcessMan::AdjustEffectsPosToPlayerScreen(char playerScreen, BITMAP *targetBitmap, Vector targetBitmapOffset, std::list<PostEffect> &screenRelativeEffectsList, std::list<Box> &screenRelativeGlowBoxesList) {
68+
int screenOcclusionOffsetX = g_SceneMan.GetScreenOcclusion(playerScreen).GetFloorIntX();
69+
int screenOcclusionOffsetY = g_SceneMan.GetScreenOcclusion(playerScreen).GetFloorIntY();
70+
int occludedOffsetX = targetBitmap->w + screenOcclusionOffsetX;
71+
int occludedOffsetY = targetBitmap->h + screenOcclusionOffsetY;
72+
73+
// Copy post effects received by client if in network mode
74+
if (g_FrameMan.GetDrawNetworkBackBuffer()) { g_PostProcessMan.GetNetworkPostEffectsList(0, screenRelativeEffectsList); }
75+
76+
// Adjust for the player screen's position on the final buffer
77+
for (list<PostEffect>::iterator eItr = screenRelativeEffectsList.begin(); eItr != screenRelativeEffectsList.end(); ++eItr) {
78+
// Make sure we won't be adding any effects to a part of the screen that is occluded by menus and such
79+
if ((*eItr).m_Pos.m_X > screenOcclusionOffsetX && (*eItr).m_Pos.m_Y > screenOcclusionOffsetY && (*eItr).m_Pos.m_X < occludedOffsetX && (*eItr).m_Pos.m_Y < occludedOffsetY) {
80+
g_PostProcessMan.GetPostScreenEffectsList()->push_back(PostEffect((*eItr).m_Pos + targetBitmapOffset, (*eItr).m_Bitmap, (*eItr).m_BitmapHash, (*eItr).m_Strength, (*eItr).m_Angle));
81+
}
82+
}
83+
// Adjust glow areas for the player screen's position on the final buffer
84+
for (list<Box>::iterator bItr = screenRelativeGlowBoxesList.begin(); bItr != screenRelativeGlowBoxesList.end(); ++bItr) {
85+
g_PostProcessMan.GetPostScreenGlowBoxesList()->push_back(*bItr);
86+
// Adjust each added glow area for the player screen's position on the final buffer
87+
g_PostProcessMan.GetPostScreenGlowBoxesList()->back().m_Corner += targetBitmapOffset;
88+
}
89+
}
90+
91+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
92+
93+
void PostProcessMan::RegisterPostEffect(const Vector &effectPos, BITMAP *effect, size_t hash, unsigned char strength, float angle) {
6894
// These effects get applied when there's a drawn frame that followed one or more sim updates.
6995
// They are not only registered on drawn sim updates; flashes and stuff could be missed otherwise if they occur on undrawn sim updates.
7096
if (effect && g_TimerMan.SimUpdatesSinceDrawn() >= 0) { m_PostSceneEffects.push_back(PostEffect(effectPos, effect, hash, strength, angle)); }

Managers/PostProcessMan.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@ namespace RTE {
8484
/// Takes the current state of the 8bpp back-buffer, copies it, and adds post-processing effects on top like glows etc.
8585
/// </summary>
8686
void PostProcess();
87+
88+
/// <summary>
89+
/// Adjusts the offsets of all effects relative to the specified player screen and adds them to the total screen effects list so they can be drawn in PostProcess().
90+
/// </summary>
91+
/// <param name="playerScreen">Player screen to adjust effect offsets for.</param>
92+
/// <param name="targetBitmap">Bitmap representing the player screen.</param>
93+
/// <param name="targetBitmapOffset">The position of the specified player's draw screen on the backbuffer.</param>
94+
/// <param name="screenRelativeEffectsList">List of the specified player's accumulated post effects for this frame.</param>
95+
/// <param name="screenRelativeGlowBoxesList">List of the specified player's accumulated glow boxes for this frame.</param>
96+
void AdjustEffectsPosToPlayerScreen(char playerScreen, BITMAP *targetBitmap, Vector targetBitmapOffset, std::list<PostEffect> &screenRelativeEffectsList, std::list<Box> &screenRelativeGlowBoxesList);
8797
#pragma endregion
8898

8999
#pragma region Post Effect Handling

0 commit comments

Comments
 (0)