mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-29 17:15:40 +00:00
Update scroll fog logic. Should fix the credits in virtua fighter and daytona that have fogging applied to the background layer and shouldn't.
This commit is contained in:
parent
1d37358b8c
commit
aaa26f678c
|
@ -115,7 +115,7 @@ void CNew3D::UploadTextures(unsigned level, unsigned x, unsigned y, unsigned wid
|
||||||
|
|
||||||
void CNew3D::DrawScrollFog()
|
void CNew3D::DrawScrollFog()
|
||||||
{
|
{
|
||||||
// ths is my best guess at the logic based upon what games are doing
|
// this is my best guess at the logic based upon what games are doing
|
||||||
//
|
//
|
||||||
// ocean hunter - every viewport has scroll fog values set. Must start with lowest priority layers as the higher ones sometimes are garbage
|
// ocean hunter - every viewport has scroll fog values set. Must start with lowest priority layers as the higher ones sometimes are garbage
|
||||||
// scud race - first viewports in priority layer missing scroll values. The latter ones all contain valid scroll values.
|
// scud race - first viewports in priority layer missing scroll values. The latter ones all contain valid scroll values.
|
||||||
|
@ -124,33 +124,46 @@ void CNew3D::DrawScrollFog()
|
||||||
// sega bassfishing - first viewport in priority 1 sets scroll value. The rest all contain the wrong value + a higher select value ..
|
// sega bassfishing - first viewport in priority 1 sets scroll value. The rest all contain the wrong value + a higher select value ..
|
||||||
// spikeout final - 2nd viewport in the priority layer has scroll values set, none of the others do. It also uses the highest select value
|
// spikeout final - 2nd viewport in the priority layer has scroll values set, none of the others do. It also uses the highest select value
|
||||||
|
|
||||||
// known bug (vf3) - if you complete the game on a stage that has fogging, that fogging gets carried over into the credits. I did a binary diff on the viewport, it's never updated from the previous stage, neither is the data it's pointing at. Either a game or emulation bug.
|
float rgba[4];
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
|
|
||||||
Viewport *vp = nullptr;
|
|
||||||
|
|
||||||
for (auto &n : m_nodes) {
|
for (auto &n : m_nodes) {
|
||||||
|
|
||||||
if (n.viewport.priority == i) {
|
if (n.viewport.priority == i) {
|
||||||
if (!vp && n.viewport.scrollFog) {
|
if (n.viewport.scrollFog) {
|
||||||
vp = &n.viewport; // only start grabbing viewports if there is a scroll value
|
rgba[0] = n.viewport.fogParams[0];
|
||||||
|
rgba[1] = n.viewport.fogParams[1];
|
||||||
|
rgba[2] = n.viewport.fogParams[2];
|
||||||
|
rgba[3] = n.viewport.scrollFog;
|
||||||
|
goto CheckScroll;
|
||||||
}
|
}
|
||||||
else if(vp && n.viewport.select == vp->select) {
|
|
||||||
vp = &n.viewport; // grab the last viewport with the same select value ??
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vp && vp->scrollFog) {
|
return;
|
||||||
|
|
||||||
float rgba[4] = { vp->fogParams[0], vp->fogParams[1], vp->fogParams[2], vp->scrollFog };
|
CheckScroll:
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
for (auto &n : m_nodes) {
|
||||||
|
if (n.viewport.priority == i) {
|
||||||
|
|
||||||
|
//if we have a fog density value
|
||||||
|
if (n.viewport.fogParams[3]) {
|
||||||
|
|
||||||
|
if (rgba[0] == n.viewport.fogParams[0] &&
|
||||||
|
rgba[1] == n.viewport.fogParams[1] &&
|
||||||
|
rgba[2] == n.viewport.fogParams[2]) {
|
||||||
|
|
||||||
glViewport(0, 0, m_totalXRes, m_totalYRes); // fill the whole viewport
|
glViewport(0, 0, m_totalXRes, m_totalYRes); // fill the whole viewport
|
||||||
m_r3dScrollFog.DrawScrollFog(rgba, vp->scrollAtt, vp->fogParams[6], vp->spotFogColor, vp->spotEllipse);
|
m_r3dScrollFog.DrawScrollFog(rgba, n.viewport.scrollAtt, n.viewport.fogParams[6], n.viewport.spotFogColor, n.viewport.spotEllipse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNew3D::RenderScene(int priority, bool renderOverlay, Layer layer)
|
bool CNew3D::RenderScene(int priority, bool renderOverlay, Layer layer)
|
||||||
|
@ -781,6 +794,10 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
{ 1.0, 1.0, 1.0 } // white
|
{ 1.0, 1.0, 1.0 } // white
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if ((addr & 0x00FFFFFF) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Translate address and obtain pointer
|
// Translate address and obtain pointer
|
||||||
const uint32_t *vpnode = TranslateCullingAddress(addr);
|
const uint32_t *vpnode = TranslateCullingAddress(addr);
|
||||||
|
|
||||||
|
@ -788,10 +805,6 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vpnode[0x01] == 0) { // memory probably hasn't been set up yet, abort
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(vpnode[0] & 0x20)) { // only if viewport enabled
|
if (!(vpnode[0] & 0x20)) { // only if viewport enabled
|
||||||
|
|
||||||
// create node object
|
// create node object
|
||||||
|
@ -804,7 +817,6 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
vp->priority = (vpnode[0] >> 3) & 0x3;
|
vp->priority = (vpnode[0] >> 3) & 0x3;
|
||||||
vp->select = (vpnode[0] >> 8) & 0x3;
|
vp->select = (vpnode[0] >> 8) & 0x3;
|
||||||
vp->number = (vpnode[0] >> 10);
|
vp->number = (vpnode[0] >> 10);
|
||||||
|
|
||||||
m_currentPriority = vp->priority;
|
m_currentPriority = vp->priority;
|
||||||
|
|
||||||
// Fetch viewport parameters (TO-DO: would rounding make a difference?)
|
// Fetch viewport parameters (TO-DO: would rounding make a difference?)
|
||||||
|
|
Loading…
Reference in a new issue