Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

softgpu: Remove offset from screenpos, adjust filtering coords #15410

Merged
merged 4 commits into from
Feb 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions GPU/Common/DrawEngineCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,13 @@ static Vec3f ClipToScreen(const Vec4f& coords) {
float z = coords.z * zScale / coords.w + zCenter;

// 16 = 0xFFFF / 4095.9375
return Vec3f(x * 16, y * 16, z);
return Vec3f(x * 16 - gstate.getOffsetX16(), y * 16 - gstate.getOffsetY16(), z);
}

static Vec3f ScreenToDrawing(const Vec3f& coords) {
Vec3f ret;
ret.x = (coords.x - gstate.getOffsetX16()) * (1.0f / 16.0f);
ret.y = (coords.y - gstate.getOffsetY16()) * (1.0f / 16.0f);
ret.x = coords.x * (1.0f / 16.0f);
ret.y = coords.y * (1.0f / 16.0f);
ret.z = coords.z;
return ret;
}
Expand Down
50 changes: 22 additions & 28 deletions GPU/Software/BinManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,8 @@ void BinManager::UpdateState() {

scissor_.x1 = screenScissorTL.x;
scissor_.y1 = screenScissorTL.y;
scissor_.x2 = screenScissorBR.x + 15;
scissor_.y2 = screenScissorBR.y + 15;

// Our bin sizes are based on offset, so if that changes we have to flush.
if (queueOffsetX_ != gstate.getOffsetX16() || queueOffsetY_ != gstate.getOffsetY16()) {
Flush("offset");
queueOffsetX_ = gstate.getOffsetX16();
queueOffsetY_ = gstate.getOffsetY16();
}
scissor_.x2 = screenScissorBR.x + SCREEN_SCALE_FACTOR - 1;
scissor_.y2 = screenScissorBR.y + SCREEN_SCALE_FACTOR - 1;

// If we're about to texture from something still pending (i.e. depth), flush.
if (HasTextureWrite(state))
Expand Down Expand Up @@ -294,6 +287,7 @@ void BinManager::AddTriangle(const VertexData &v0, const VertexData &v1, const V
Vec2<int> d12((int)v1.screenpos.x - (int)v2.screenpos.x, (int)v1.screenpos.y - (int)v2.screenpos.y);

// Drop primitives which are not in CCW order by checking the cross product.
static_assert(SCREEN_SCALE_FACTOR <= 16, "Fails if scale factor is too high");
if (d01.x * d02.y - d01.y * d02.x < 0)
return;
// If all points have identical coords, we'll have 0 weights and not skip properly, so skip here.
Expand Down Expand Up @@ -360,23 +354,23 @@ void BinManager::Drain() {

// If the waitable has fully drained, we can update our binning decisions.
if (!tasksSplit_ || waitable_->Empty()) {
int w2 = (queueRange_.x2 - queueRange_.x1 + 31) / 32;
int h2 = (queueRange_.y2 - queueRange_.y1 + 31) / 32;
int w2 = (queueRange_.x2 - queueRange_.x1 + (SCREEN_SCALE_FACTOR * 2 - 1)) / (SCREEN_SCALE_FACTOR * 2);
int h2 = (queueRange_.y2 - queueRange_.y1 + (SCREEN_SCALE_FACTOR * 2 - 1)) / (SCREEN_SCALE_FACTOR * 2);

// Always bin the entire possible range, but focus on the drawn area.
ScreenCoords tl(queueOffsetX_, queueOffsetY_, 0);
ScreenCoords br(queueOffsetX_ + 1024 * 16, queueOffsetY_ + 1024 * 16, 0);
ScreenCoords tl(0, 0, 0);
ScreenCoords br(1024 * SCREEN_SCALE_FACTOR, 1024 * SCREEN_SCALE_FACTOR, 0);

taskRanges_.clear();
if (h2 >= 18 && w2 >= h2 * 4) {
int bin_w = std::max(4, (w2 + maxTasks_ - 1) / maxTasks_) * 32;
int bin_w = std::max(4, (w2 + maxTasks_ - 1) / maxTasks_) * SCREEN_SCALE_FACTOR * 2;
taskRanges_.push_back(BinCoords{ tl.x, tl.y, queueRange_.x1 + bin_w - 1, br.y - 1 });
for (int x = queueRange_.x1 + bin_w; x <= queueRange_.x2; x += bin_w) {
int x2 = x + bin_w > queueRange_.x2 ? br.x : x + bin_w;
taskRanges_.push_back(BinCoords{ x, tl.y, x2 - 1, br.y - 1 });
}
} else if (h2 >= 18 && w2 >= 18) {
int bin_h = std::max(4, (h2 + maxTasks_ - 1) / maxTasks_) * 32;
int bin_h = std::max(4, (h2 + maxTasks_ - 1) / maxTasks_) * SCREEN_SCALE_FACTOR * 2;
taskRanges_.push_back(BinCoords{ tl.x, tl.y, br.x - 1, queueRange_.y1 + bin_h - 1 });
for (int y = queueRange_.y1 + bin_h; y <= queueRange_.y2; y += bin_h) {
int y2 = y + bin_h > queueRange_.y2 ? br.y : y + bin_h;
Expand Down Expand Up @@ -564,28 +558,28 @@ BinCoords BinManager::Scissor(BinCoords range) {

BinCoords BinManager::Range(const VertexData &v0, const VertexData &v1, const VertexData &v2) {
BinCoords range;
range.x1 = std::min(std::min(v0.screenpos.x, v1.screenpos.x), v2.screenpos.x) & ~0xF;
range.y1 = std::min(std::min(v0.screenpos.y, v1.screenpos.y), v2.screenpos.y) & ~0xF;
range.x2 = std::max(std::max(v0.screenpos.x, v1.screenpos.x), v2.screenpos.x) | 0xF;
range.y2 = std::max(std::max(v0.screenpos.y, v1.screenpos.y), v2.screenpos.y) | 0xF;
range.x1 = std::min(std::min(v0.screenpos.x, v1.screenpos.x), v2.screenpos.x) & ~(SCREEN_SCALE_FACTOR - 1);
range.y1 = std::min(std::min(v0.screenpos.y, v1.screenpos.y), v2.screenpos.y) & ~(SCREEN_SCALE_FACTOR - 1);
range.x2 = std::max(std::max(v0.screenpos.x, v1.screenpos.x), v2.screenpos.x) | (SCREEN_SCALE_FACTOR - 1);
range.y2 = std::max(std::max(v0.screenpos.y, v1.screenpos.y), v2.screenpos.y) | (SCREEN_SCALE_FACTOR - 1);
return Scissor(range);
}

BinCoords BinManager::Range(const VertexData &v0, const VertexData &v1) {
BinCoords range;
range.x1 = std::min(v0.screenpos.x, v1.screenpos.x) & ~0xF;
range.y1 = std::min(v0.screenpos.y, v1.screenpos.y) & ~0xF;
range.x2 = std::max(v0.screenpos.x, v1.screenpos.x) | 0xF;
range.y2 = std::max(v0.screenpos.y, v1.screenpos.y) | 0xF;
range.x1 = std::min(v0.screenpos.x, v1.screenpos.x) & ~(SCREEN_SCALE_FACTOR - 1);
range.y1 = std::min(v0.screenpos.y, v1.screenpos.y) & ~(SCREEN_SCALE_FACTOR - 1);
range.x2 = std::max(v0.screenpos.x, v1.screenpos.x) | (SCREEN_SCALE_FACTOR - 1);
range.y2 = std::max(v0.screenpos.y, v1.screenpos.y) | (SCREEN_SCALE_FACTOR - 1);
return Scissor(range);
}

BinCoords BinManager::Range(const VertexData &v0) {
BinCoords range;
range.x1 = v0.screenpos.x & ~0xF;
range.y1 = v0.screenpos.y & ~0xF;
range.x2 = v0.screenpos.x | 0xF;
range.y2 = v0.screenpos.y | 0xF;
range.x1 = v0.screenpos.x & ~(SCREEN_SCALE_FACTOR - 1);
range.y1 = v0.screenpos.y & ~(SCREEN_SCALE_FACTOR - 1);
range.x2 = v0.screenpos.x | (SCREEN_SCALE_FACTOR - 1);
range.y2 = v0.screenpos.y | (SCREEN_SCALE_FACTOR - 1);
return Scissor(range);
}

Expand All @@ -595,7 +589,7 @@ void BinManager::Expand(const BinCoords &range) {
queueRange_.x2 = std::max(queueRange_.x2, range.x2);
queueRange_.y2 = std::max(queueRange_.y2, range.y2);

if (maxTasks_ == 1 || (queueRange_.y2 - queueRange_.y1 >= 224 * 16 && enqueues_ < 36 * maxTasks_)) {
if (maxTasks_ == 1 || (queueRange_.y2 - queueRange_.y1 >= 224 * SCREEN_SCALE_FACTOR && enqueues_ < 36 * maxTasks_)) {
Drain();
}
}
2 changes: 0 additions & 2 deletions GPU/Software/BinManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,6 @@ class BinManager {
BinCoords scissor_;
BinItemQueue queue_;
BinCoords queueRange_;
int queueOffsetX_ = -1;
int queueOffsetY_ = -1;
SoftDirty dirty_ = SoftDirty::NONE;

int maxTasks_ = 1;
Expand Down
58 changes: 30 additions & 28 deletions GPU/Software/Rasterizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,16 +549,18 @@ static inline __m128i SOFTRAST_CALL TriangleEdgeStartSSE4(__m128i initX, __m128i
template <bool useSSE4>
Vec4<int> TriangleEdge<useSSE4>::Start(const ScreenCoords &v0, const ScreenCoords &v1, const ScreenCoords &origin) {
// Start at pixel centers.
Vec4<int> initX = Vec4<int>::AssignToAll(origin.x) + Vec4<int>(7, 23, 7, 23);
Vec4<int> initY = Vec4<int>::AssignToAll(origin.y) + Vec4<int>(7, 7, 23, 23);
static constexpr int centerOff = (SCREEN_SCALE_FACTOR / 2) - 1;
static constexpr int centerPlus1 = SCREEN_SCALE_FACTOR + centerOff;
Vec4<int> initX = Vec4<int>::AssignToAll(origin.x) + Vec4<int>(centerOff, centerPlus1, centerOff, centerPlus1);
Vec4<int> initY = Vec4<int>::AssignToAll(origin.y) + Vec4<int>(centerOff, centerOff, centerPlus1, centerPlus1);

// orient2d refactored.
int xf = v0.y - v1.y;
int yf = v1.x - v0.x;
int c = v1.y * v0.x - v1.x * v0.y;

stepX = Vec4<int>::AssignToAll(xf * 16 * 2);
stepY = Vec4<int>::AssignToAll(yf * 16 * 2);
stepX = Vec4<int>::AssignToAll(xf * SCREEN_SCALE_FACTOR * 2);
stepY = Vec4<int>::AssignToAll(yf * SCREEN_SCALE_FACTOR * 2);

#if defined(_M_SSE) && !PPSSPP_ARCH(X86)
if (useSSE4)
Expand Down Expand Up @@ -611,15 +613,15 @@ void TriangleEdge<useSSE4>::NarrowMinMaxX(const Vec4<int> &w, int64_t minX, int6
if (wmax < 0) {
if (stepX.x > 0) {
int steps = -wmax / stepX.x;
rowMinX = std::max(rowMinX, minX + steps * 16 * 2);
rowMinX = std::max(rowMinX, minX + steps * SCREEN_SCALE_FACTOR * 2);
} else if (stepX.x <= 0) {
rowMinX = rowMaxX + 1;
}
}

if (wmax >= 0 && stepX.x < 0) {
int steps = (-wmax / stepX.x) + 1;
rowMaxX = std::min(rowMaxX, minX + steps * 16 * 2);
rowMaxX = std::min(rowMaxX, minX + steps * SCREEN_SCALE_FACTOR * 2);
}
}

Expand Down Expand Up @@ -727,33 +729,33 @@ void DrawTriangleSlice(
std::string ztag = StringFromFormat("DisplayListTZ_%08x", state.listPC);
#endif

for (int64_t curY = minY; curY <= maxY; curY += 32,
for (int64_t curY = minY; curY <= maxY; curY += SCREEN_SCALE_FACTOR * 2,
w0_base = e0.StepY(w0_base),
w1_base = e1.StepY(w1_base),
w2_base = e2.StepY(w2_base)) {
Vec4<int> w0 = w0_base;
Vec4<int> w1 = w1_base;
Vec4<int> w2 = w2_base;

DrawingCoords p = TransformUnit::ScreenToDrawing(minX, curY, state.screenOffsetX, state.screenOffsetY);
DrawingCoords p = TransformUnit::ScreenToDrawing(minX, curY);

int64_t rowMinX = minX, rowMaxX = maxX;
e0.NarrowMinMaxX(w0, minX, rowMinX, rowMaxX);
e1.NarrowMinMaxX(w1, minX, rowMinX, rowMaxX);
e2.NarrowMinMaxX(w2, minX, rowMinX, rowMaxX);

int skipX = (rowMinX - minX) / 32;
int skipX = (rowMinX - minX) / (SCREEN_SCALE_FACTOR * 2);
w0 = e0.StepXTimes(w0, skipX);
w1 = e1.StepXTimes(w1, skipX);
w2 = e2.StepXTimes(w2, skipX);
p.x = (p.x + 2 * skipX) & 0x3FF;

// TODO: Maybe we can clip the edges instead?
int scissorYPlus1 = curY + 16 > maxY ? -1 : 0;
Vec4<int> scissor_mask = Vec4<int>(0, rowMaxX - rowMinX - 16, scissorYPlus1, (rowMaxX - rowMinX - 16) | scissorYPlus1);
Vec4<int> scissor_step = Vec4<int>(0, -32, 0, -32);
int scissorYPlus1 = curY + SCREEN_SCALE_FACTOR > maxY ? -1 : 0;
Vec4<int> scissor_mask = Vec4<int>(0, rowMaxX - rowMinX - SCREEN_SCALE_FACTOR, scissorYPlus1, (rowMaxX - rowMinX - SCREEN_SCALE_FACTOR) | scissorYPlus1);
Vec4<int> scissor_step = Vec4<int>(0, -(SCREEN_SCALE_FACTOR * 2), 0, -(SCREEN_SCALE_FACTOR * 2));

for (int64_t curX = rowMinX; curX <= rowMaxX; curX += 32,
for (int64_t curX = rowMinX; curX <= rowMaxX; curX += SCREEN_SCALE_FACTOR * 2,
w0 = e0.StepX(w0),
w1 = e1.StepX(w1),
w2 = e2.StepX(w2),
Expand Down Expand Up @@ -861,9 +863,9 @@ void DrawTriangleSlice(
}

#if !defined(SOFTGPU_MEMORY_TAGGING_DETAILED) && defined(SOFTGPU_MEMORY_TAGGING_BASIC)
for (int y = minY; y <= maxY; y += 16) {
DrawingCoords p = TransformUnit::ScreenToDrawing(minX, y, state.screenOffsetX, state.screenOffsetY);
DrawingCoords pend = TransformUnit::ScreenToDrawing(maxX, y, state.screenOffsetX, state.screenOffsetY);
for (int y = minY; y <= maxY; y += SCREEN_SCALE_FACTOR) {
DrawingCoords p = TransformUnit::ScreenToDrawing(minX, y);
DrawingCoords pend = TransformUnit::ScreenToDrawing(maxX, y);
uint32_t row = gstate.getFrameBufAddress() + p.y * pixelID.cached.framebufStride * bpp;
NotifyMemInfo(MemBlockFlags::WRITE, row + p.x * bpp, (pend.x - p.x) * bpp, tag.c_str(), tag.size());

Expand Down Expand Up @@ -916,7 +918,7 @@ void DrawPoint(const VertexData &v0, const BinCoords &range, const RasterizerSta
if (!pixelID.clearMode)
prim_color += Vec4<int>(sec_color, 0);

DrawingCoords p = TransformUnit::ScreenToDrawing(pos, state.screenOffsetX, state.screenOffsetY);
DrawingCoords p = TransformUnit::ScreenToDrawing(pos);
u16 z = pos.z;

u8 fog = 255;
Expand All @@ -943,13 +945,13 @@ void DrawPoint(const VertexData &v0, const BinCoords &range, const RasterizerSta
}

void ClearRectangle(const VertexData &v0, const VertexData &v1, const BinCoords &range, const RasterizerState &state) {
DrawingCoords pprime = TransformUnit::ScreenToDrawing(range.x1, range.y1, state.screenOffsetX, state.screenOffsetY);
DrawingCoords pend = TransformUnit::ScreenToDrawing(range.x2, range.y2, state.screenOffsetX, state.screenOffsetY);
DrawingCoords pprime = TransformUnit::ScreenToDrawing(range.x1, range.y1);
DrawingCoords pend = TransformUnit::ScreenToDrawing(range.x2, range.y2);
auto &pixelID = state.pixelID;
auto &samplerID = state.samplerID;

// Min and max are in PSP fixed point screen coordinates, 16 here is for the 4 subpixel bits.
const int w = (range.x2 - range.x1 + 1) / 16;
const int w = (range.x2 - range.x1 + 1) / SCREEN_SCALE_FACTOR;
if (w <= 0)
return;

Expand Down Expand Up @@ -1129,14 +1131,14 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const BinCoords &range

int steps;
if (abs(dx) < abs(dy))
steps = abs(dy) / 16;
steps = abs(dy) / SCREEN_SCALE_FACTOR;
else
steps = abs(dx) / 16;
steps = abs(dx) / SCREEN_SCALE_FACTOR;

// Avoid going too far since we typically don't start at the pixel center.
if (dx < 0 && dx >= -16)
if (dx < 0 && dx >= -SCREEN_SCALE_FACTOR)
dx++;
if (dy < 0 && dy >= -16)
if (dy < 0 && dy >= -SCREEN_SCALE_FACTOR)
dy++;

double xinc = (double)dx / steps;
Expand Down Expand Up @@ -1199,8 +1201,8 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const BinCoords &range
}

// If inc is 0, force the delta to zero.
float ds = xinc == 0.0 ? 0.0f : (s1 - s) * 16.0f * (1.0f / xinc);
float dt = yinc == 0.0 ? 0.0f : (t1 - t) * 16.0f * (1.0f / yinc);
float ds = xinc == 0.0 ? 0.0f : (s1 - s) * (float)SCREEN_SCALE_FACTOR * (1.0f / xinc);
float dt = yinc == 0.0 ? 0.0f : (t1 - t) * (float)SCREEN_SCALE_FACTOR * (1.0f / yinc);

int texLevel;
int texLevelFrac;
Expand All @@ -1209,7 +1211,7 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const BinCoords &range

if (state.antialiasLines) {
// TODO: This is a naive and wrong implementation.
DrawingCoords p0 = TransformUnit::ScreenToDrawing(x, y, state.screenOffsetX, state.screenOffsetY);
DrawingCoords p0 = TransformUnit::ScreenToDrawing(x, y);
s = ((float)p0.x + xinc / 32.0f) / 512.0f;
t = ((float)p0.y + yinc / 32.0f) / 512.0f;

Expand All @@ -1224,7 +1226,7 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const BinCoords &range
prim_color += Vec4<int>(sec_color, 0);

PROFILE_THIS_SCOPE("draw_px");
DrawingCoords p = TransformUnit::ScreenToDrawing(x, y, state.screenOffsetX, state.screenOffsetY);
DrawingCoords p = TransformUnit::ScreenToDrawing(x, y);
state.drawPixel(p.x, p.y, z, fog, ToVec4IntArg(prim_color), pixelID);

#if defined(SOFTGPU_MEMORY_TAGGING_DETAILED) || defined(SOFTGPU_MEMORY_TAGGING_BASIC)
Expand Down
26 changes: 13 additions & 13 deletions GPU/Software/RasterizerRectangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ void DrawSprite(const VertexData &v0, const VertexData &v1, const BinCoords &ran
auto &pixelID = state.pixelID;
auto &samplerID = state.samplerID;

DrawingCoords pos0 = TransformUnit::ScreenToDrawing(v0.screenpos, state.screenOffsetX, state.screenOffsetY);
DrawingCoords pos0 = TransformUnit::ScreenToDrawing(v0.screenpos);
// Include the ending pixel based on its center, not start.
DrawingCoords pos1 = TransformUnit::ScreenToDrawing(v1.screenpos + ScreenCoords(7, 7, 0), state.screenOffsetX, state.screenOffsetY);
DrawingCoords pos1 = TransformUnit::ScreenToDrawing(v1.screenpos + ScreenCoords(7, 7, 0));

DrawingCoords scissorTL = TransformUnit::ScreenToDrawing(range.x1, range.y1, state.screenOffsetX, state.screenOffsetY);
DrawingCoords scissorBR = TransformUnit::ScreenToDrawing(range.x2, range.y2, state.screenOffsetX, state.screenOffsetY);
DrawingCoords scissorTL = TransformUnit::ScreenToDrawing(range.x1, range.y1);
DrawingCoords scissorBR = TransformUnit::ScreenToDrawing(range.x2, range.y2);

int z = v1.screenpos.z;
int fog = 255;
Expand Down Expand Up @@ -249,10 +249,10 @@ void DrawSprite(const VertexData &v0, const VertexData &v1, const BinCoords &ran

bool g_needsClearAfterDialog = false;

static inline bool NoClampOrWrap(const Vec2f &tc) {
static inline bool NoClampOrWrap(const RasterizerState &state, const Vec2f &tc) {
if (tc.x < 0 || tc.y < 0)
return false;
return tc.x <= gstate.getTextureWidth(0) && tc.y <= gstate.getTextureHeight(0);
return tc.x <= state.samplerID.cached.sizes[0].w && tc.y <= state.samplerID.cached.sizes[0].h;
}

// Returns true if the normal path should be skipped.
Expand All @@ -263,15 +263,15 @@ bool RectangleFastPath(const VertexData &v0, const VertexData &v1, BinManager &b
// Check for 1:1 texture mapping. In that case we can call DrawSprite.
int xdiff = v1.screenpos.x - v0.screenpos.x;
int ydiff = v1.screenpos.y - v0.screenpos.y;
int udiff = (v1.texturecoords.x - v0.texturecoords.x) * 16.0f;
int vdiff = (v1.texturecoords.y - v0.texturecoords.y) * 16.0f;
int udiff = (v1.texturecoords.x - v0.texturecoords.x) * (float)SCREEN_SCALE_FACTOR;
int vdiff = (v1.texturecoords.y - v0.texturecoords.y) * (float)SCREEN_SCALE_FACTOR;
bool coord_check =
(xdiff == udiff || xdiff == -udiff) &&
(ydiff == vdiff || ydiff == -vdiff);
// Currently only works for TL/BR, which is the most common but not required.
bool orient_check = xdiff >= 0 && ydiff >= 0;
// We already have a fast path for clear in ClearRectangle.
bool state_check = !state.pixelID.clearMode && !state.samplerID.hasAnyMips && NoClampOrWrap(v0.texturecoords) && NoClampOrWrap(v1.texturecoords);
bool state_check = !state.pixelID.clearMode && !state.samplerID.hasAnyMips && NoClampOrWrap(state, v0.texturecoords) && NoClampOrWrap(state, v1.texturecoords);
if ((coord_check || !state.enableTextures) && orient_check && state_check) {
binner.AddSprite(v0, v1);
return true;
Expand All @@ -282,9 +282,9 @@ bool RectangleFastPath(const VertexData &v0, const VertexData &v1, BinManager &b
if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && v0.texturecoords.x == 64.0f && v0.texturecoords.y == 16.0f && v1.texturecoords.x == 448.0f && v1.texturecoords.y == 240.0f) {
// check for save/load dialog.
if (!currentDialogActive) {
if (v0.screenpos.x == 0x7100 && v0.screenpos.y == 0x7780 && v1.screenpos.x == 0x8f00 && v1.screenpos.y == 0x8880) {
if (v0.screenpos.x + state.screenOffsetX == 0x7100 && v0.screenpos.y + state.screenOffsetY == 0x7780 && v1.screenpos.x + state.screenOffsetX == 0x8f00 && v1.screenpos.y + state.screenOffsetY == 0x8880) {
g_DarkStalkerStretch = DSStretch::Wide;
} else if (v0.screenpos.x == 0x7400 && v0.screenpos.y == 0x7780 && v1.screenpos.x == 0x8C00 && v1.screenpos.y == 0x8880) {
} else if (v0.screenpos.x + state.screenOffsetX == 0x7400 && v0.screenpos.y + state.screenOffsetY == 0x7780 && v1.screenpos.x + state.screenOffsetX == 0x8C00 && v1.screenpos.y + state.screenOffsetY == 0x8880) {
g_DarkStalkerStretch = DSStretch::Normal;
} else {
return false;
Expand Down Expand Up @@ -456,8 +456,8 @@ bool DetectRectangleThroughModeSlices(const RasterizerState &state, const Vertex
return false;

// We might be able to compare ratios, but let's expect 1:1.
int texdiff1 = (texbr1.x - textl1.x) * 16.0f;
int texdiff2 = (texbr2.x - textl2.x) * 16.0f;
int texdiff1 = (texbr1.x - textl1.x) * (float)SCREEN_SCALE_FACTOR;
int texdiff2 = (texbr2.x - textl2.x) * (float)SCREEN_SCALE_FACTOR;
int posdiff1 = br1.x - tl1.x;
int posdiff2 = br2.x - tl2.x;
return texdiff1 == posdiff1 && texdiff2 == posdiff2;
Expand Down
Loading