aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/Util_Video.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/Util_Video.cpp')
-rw-r--r--src/frontend/Util_Video.cpp297
1 files changed, 187 insertions, 110 deletions
diff --git a/src/frontend/Util_Video.cpp b/src/frontend/Util_Video.cpp
index f096311..4265631 100644
--- a/src/frontend/Util_Video.cpp
+++ b/src/frontend/Util_Video.cpp
@@ -31,7 +31,8 @@ namespace Frontend
float TopScreenMtx[6];
float BotScreenMtx[6];
float TouchMtx[6];
-
+bool TopEnable;
+bool BotEnable;
void M23_Identity(float* m)
{
@@ -47,6 +48,13 @@ void M23_Scale(float* m, float s)
m[4] *= s; m[5] *= s;
}
+void M23_Scale(float* m, float x, float y)
+{
+ m[0] *= x; m[1] *= y;
+ m[2] *= x; m[3] *= y;
+ m[4] *= x; m[5] *= y;
+}
+
void M23_RotateFast(float* m, int angle)
{
if (angle == 0) return;
@@ -109,7 +117,14 @@ void M23_Transform(float* m, float& x, float& y)
}
-void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int rotation, int sizing, int screenGap, bool integerScale, int swapScreens)
+void SetupScreenLayout(int screenWidth, int screenHeight,
+ int screenLayout,
+ int rotation,
+ int sizing,
+ int screenGap,
+ bool integerScale,
+ bool swapScreens,
+ float topAspect, float botAspect)
{
float refpoints[4][2] =
{
@@ -130,6 +145,9 @@ void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int
M23_Translate(TopScreenMtx, -256/2, -192/2);
M23_Translate(BotScreenMtx, -256/2, -192/2);
+ M23_Scale(TopScreenMtx, topAspect, 1);
+ M23_Scale(BotScreenMtx, botAspect, 1);
+
// rotation
{
float rotmtx[6];
@@ -145,136 +163,174 @@ void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int
M23_Transform(BotScreenMtx, refpoints[3][0], refpoints[3][1]);
}
- // move screens apart
- {
- int idx = layout == 0 ? 1 : 0;
- float offset =
- (((layout == 0 && (rotation % 2 == 0)) || (layout == 1 && (rotation % 2 == 1))
- ? 192.f : 256.f)
- + screenGap) / 2.f;
- if ((rotation == 1 || rotation == 2) ^ swapScreens)
- offset *= -1.f;
-
- M23_Translate(TopScreenMtx, (idx==0)?-offset:0, (idx==1)?-offset:0);
- M23_Translate(BotScreenMtx, (idx==0)?offset:0, (idx==1)?offset:0);
-
- refpoints[0][idx] -= offset;
- refpoints[1][idx] -= offset;
- refpoints[2][idx] += offset;
- refpoints[3][idx] += offset;
-
- botTrans[idx] = offset;
- }
+ int posRefPointOffset = 0;
+ int posRefPointCount = 4;
- // scale
+ if (sizing == 4 || sizing == 5)
{
- if (sizing == 0)
- {
- float minX = refpoints[0][0], maxX = minX;
- float minY = refpoints[0][1], maxY = minY;
+ float* mtx = sizing == 4 ? TopScreenMtx : BotScreenMtx;
+ int primOffset = sizing == 4 ? 0 : 2;
+ int secOffset = sizing == 5 ? 2 : 0;
- for (int i = 1; i < 4; i++)
- {
- minX = std::min(minX, refpoints[i][0]);
- minY = std::min(minY, refpoints[i][1]);
- maxX = std::max(maxX, refpoints[i][0]);
- maxY = std::max(maxY, refpoints[i][1]);
- }
+ float hSize = fabsf(refpoints[primOffset][0] - refpoints[primOffset+1][0]);
+ float vSize = fabsf(refpoints[primOffset][1] - refpoints[primOffset+1][1]);
+
+ float scale = std::min(screenWidth / hSize, screenHeight / vSize);
+ if (integerScale)
+ scale = floorf(scale);
- float hSize = maxX - minX;
- float vSize = maxY - minY;
+ TopEnable = sizing == 4;
+ BotEnable = sizing == 5;
+ botScale = scale;
- // scale evenly
- float scale = std::min(screenWidth / hSize, screenHeight / vSize);
+ M23_Scale(mtx, scale);
+ refpoints[primOffset][0] *= scale;
+ refpoints[primOffset][1] *= scale;
+ refpoints[primOffset+1][0] *= scale;
+ refpoints[primOffset+1][1] *= scale;
- if (integerScale)
- scale = floor(scale);
+ posRefPointOffset = primOffset;
+ posRefPointCount = 2;
+ }
+ else
+ {
+ TopEnable = BotEnable = true;
+ // move screens apart
+ {
+ int idx = layout == 0 ? 1 : 0;
- M23_Scale(TopScreenMtx, scale);
- M23_Scale(BotScreenMtx, scale);
+ bool moveV = rotation % 2 == layout;
- for (int i = 0; i < 4; i++)
+ float offsetTop = (moveV ? 192 : 256 * topAspect) / 2 + screenGap / 2;
+ float offsetBot = (moveV ? 192 : 256 * botAspect) / 2 + screenGap / 2;
+
+ if ((rotation == 1 || rotation == 2) ^ swapScreens)
{
- refpoints[i][0] *= scale;
- refpoints[i][1] *= scale;
+ offsetTop *= -1;
+ offsetBot *= -1;
}
- botScale = scale;
+ M23_Translate(TopScreenMtx, (idx==0)?-offsetTop:0, (idx==1)?-offsetTop:0);
+ M23_Translate(BotScreenMtx, (idx==0)?offsetBot:0, (idx==1)?offsetBot:0);
+
+ refpoints[0][idx] -= offsetTop;
+ refpoints[1][idx] -= offsetTop;
+ refpoints[2][idx] += offsetBot;
+ refpoints[3][idx] += offsetBot;
+
+ botTrans[idx] = offsetBot;
}
- else
+
+ // scale
{
- int primOffset = (sizing == 1) ? 0 : 2;
- int secOffset = (sizing == 1) ? 2 : 0;
- float* primMtx = (sizing == 1) ? TopScreenMtx : BotScreenMtx;
- float* secMtx = (sizing == 1) ? BotScreenMtx : TopScreenMtx;
+ if (sizing == 0)
+ {
+ float minX = refpoints[0][0], maxX = minX;
+ float minY = refpoints[0][1], maxY = minY;
- float primMinX = refpoints[primOffset][0], primMaxX = primMinX;
- float primMinY = refpoints[primOffset][1], primMaxY = primMinY;
- float secMinX = refpoints[secOffset][0], secMaxX = secMinX;
- float secMinY = refpoints[secOffset][1], secMaxY = secMinY;
+ for (int i = 1; i < 4; i++)
+ {
+ minX = std::min(minX, refpoints[i][0]);
+ minY = std::min(minY, refpoints[i][1]);
+ maxX = std::max(maxX, refpoints[i][0]);
+ maxY = std::max(maxY, refpoints[i][1]);
+ }
- primMinX = std::min(primMinX, refpoints[primOffset+1][0]);
- primMinY = std::min(primMinY, refpoints[primOffset+1][1]);
- primMaxX = std::max(primMaxX, refpoints[primOffset+1][0]);
- primMaxY = std::max(primMaxY, refpoints[primOffset+1][1]);
+ float hSize = maxX - minX;
+ float vSize = maxY - minY;
- secMinX = std::min(secMinX, refpoints[secOffset+1][0]);
- secMinY = std::min(secMinY, refpoints[secOffset+1][1]);
- secMaxX = std::max(secMaxX, refpoints[secOffset+1][0]);
- secMaxY = std::max(secMaxY, refpoints[secOffset+1][1]);
+ // scale evenly
+ float scale = std::min(screenWidth / hSize, screenHeight / vSize);
- float primHSize = layout == 1 ? std::max(primMaxX, -primMinX) : primMaxX - primMinX;
- float primVSize = layout == 0 ? std::max(primMaxY, -primMinY) : primMaxY - primMinY;
+ if (integerScale)
+ scale = floor(scale);
- float secHSize = layout == 1 ? std::max(secMaxX, -secMinX) : secMaxX - secMinX;
- float secVSize = layout == 0 ? std::max(secMaxY, -secMinY) : secMaxY - secMinY;
+ M23_Scale(TopScreenMtx, scale);
+ M23_Scale(BotScreenMtx, scale);
- float primScale = std::min(screenWidth / primHSize, screenHeight / primVSize);
- float secScale = 1.f;
+ for (int i = 0; i < 4; i++)
+ {
+ refpoints[i][0] *= scale;
+ refpoints[i][1] *= scale;
+ }
- if (layout == 0)
- {
- if (screenHeight - primVSize * primScale < secVSize)
- primScale = std::min(screenWidth / primHSize, (screenHeight - secVSize) / primVSize);
- else
- secScale = std::min((screenHeight - primVSize * primScale) / secVSize, screenWidth / secHSize);
+ botScale = scale;
}
else
{
- if (screenWidth - primHSize * primScale < secHSize)
- primScale = std::min((screenWidth - secHSize) / primHSize, screenHeight / primVSize);
+ int primOffset = (sizing == 1) ? 0 : 2;
+ int secOffset = (sizing == 1) ? 2 : 0;
+ float* primMtx = (sizing == 1) ? TopScreenMtx : BotScreenMtx;
+ float* secMtx = (sizing == 1) ? BotScreenMtx : TopScreenMtx;
+
+ float primMinX = refpoints[primOffset][0], primMaxX = primMinX;
+ float primMinY = refpoints[primOffset][1], primMaxY = primMinY;
+ float secMinX = refpoints[secOffset][0], secMaxX = secMinX;
+ float secMinY = refpoints[secOffset][1], secMaxY = secMinY;
+
+ primMinX = std::min(primMinX, refpoints[primOffset+1][0]);
+ primMinY = std::min(primMinY, refpoints[primOffset+1][1]);
+ primMaxX = std::max(primMaxX, refpoints[primOffset+1][0]);
+ primMaxY = std::max(primMaxY, refpoints[primOffset+1][1]);
+
+ secMinX = std::min(secMinX, refpoints[secOffset+1][0]);
+ secMinY = std::min(secMinY, refpoints[secOffset+1][1]);
+ secMaxX = std::max(secMaxX, refpoints[secOffset+1][0]);
+ secMaxY = std::max(secMaxY, refpoints[secOffset+1][1]);
+
+ float primHSize = layout == 1 ? std::max(primMaxX, -primMinX) : primMaxX - primMinX;
+ float primVSize = layout == 0 ? std::max(primMaxY, -primMinY) : primMaxY - primMinY;
+
+ float secHSize = layout == 1 ? std::max(secMaxX, -secMinX) : secMaxX - secMinX;
+ float secVSize = layout == 0 ? std::max(secMaxY, -secMinY) : secMaxY - secMinY;
+
+ float primScale = std::min(screenWidth / primHSize, screenHeight / primVSize);
+ float secScale = 1.f;
+
+ if (layout == 0)
+ {
+ if (screenHeight - primVSize * primScale < secVSize)
+ primScale = std::min(screenWidth / primHSize, (screenHeight - secVSize) / primVSize);
+ else
+ secScale = std::min((screenHeight - primVSize * primScale) / secVSize, screenWidth / secHSize);
+ }
else
- secScale = std::min((screenWidth - primHSize * primScale) / secHSize, screenHeight / secVSize);
+ {
+ if (screenWidth - primHSize * primScale < secHSize)
+ primScale = std::min((screenWidth - secHSize) / primHSize, screenHeight / primVSize);
+ else
+ secScale = std::min((screenWidth - primHSize * primScale) / secHSize, screenHeight / secVSize);
+ }
+
+ if (integerScale)
+ {
+ primScale = floor(primScale);
+ secScale = floor(secScale);
+ }
+
+ M23_Scale(primMtx, primScale);
+ M23_Scale(secMtx, secScale);
+
+ refpoints[primOffset+0][0] *= primScale;
+ refpoints[primOffset+0][1] *= primScale;
+ refpoints[primOffset+1][0] *= primScale;
+ refpoints[primOffset+1][1] *= primScale;
+ refpoints[secOffset+0][0] *= secScale;
+ refpoints[secOffset+0][1] *= secScale;
+ refpoints[secOffset+1][0] *= secScale;
+ refpoints[secOffset+1][1] *= secScale;
+
+ botScale = (sizing == 1) ? secScale : primScale;
}
-
- if (integerScale)
- {
- primScale = floor(primScale);
- secScale = floor(secScale);
- }
-
- M23_Scale(primMtx, primScale);
- M23_Scale(secMtx, secScale);
-
- refpoints[primOffset+0][0] *= primScale;
- refpoints[primOffset+0][1] *= primScale;
- refpoints[primOffset+1][0] *= primScale;
- refpoints[primOffset+1][1] *= primScale;
- refpoints[secOffset+0][0] *= secScale;
- refpoints[secOffset+0][1] *= secScale;
- refpoints[secOffset+1][0] *= secScale;
- refpoints[secOffset+1][1] *= secScale;
-
- botScale = (sizing == 1) ? secScale : primScale;
}
}
// position
{
- float minX = refpoints[0][0], maxX = minX;
- float minY = refpoints[0][1], maxY = minY;
+ float minX = refpoints[posRefPointOffset][0], maxX = minX;
+ float minY = refpoints[posRefPointOffset][1], maxY = minY;
- for (int i = 1; i < 4; i++)
+ for (int i = posRefPointOffset + 1; i < posRefPointOffset + posRefPointCount; i++)
{
minX = std::min(minX, refpoints[i][0]);
minY = std::min(minY, refpoints[i][1]);
@@ -297,6 +353,7 @@ void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int
// prepare a 'reverse' matrix for the touchscreen
// this matrix undoes the transforms applied to the bottom screen
// and can be used to calculate touchscreen coords from host screen coords
+ if (BotEnable)
{
M23_Identity(TouchMtx);
@@ -309,25 +366,45 @@ void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int
M23_RotateFast(rotmtx, (4-rotation) & 3);
M23_Multiply(TouchMtx, rotmtx, TouchMtx);
+ M23_Scale(TouchMtx, 1.f/botAspect, 1);
M23_Translate(TouchMtx, 256/2, 192/2);
}
}
-void GetScreenTransforms(float* top, float* bot)
+int GetScreenTransforms(float* out, int* kind)
{
- memcpy(top, TopScreenMtx, 6*sizeof(float));
- memcpy(bot, BotScreenMtx, 6*sizeof(float));
+ int num = 0;
+ if (TopEnable)
+ {
+ memcpy(out + 6*num, TopScreenMtx, sizeof(TopScreenMtx));
+ kind[num] = 0;
+ num++;
+ }
+ if (BotEnable)
+ {
+ memcpy(out + 6*num, BotScreenMtx, sizeof(BotScreenMtx));
+ kind[num] = 1;
+ num++;
+ }
+ return num;
}
-void GetTouchCoords(int& x, int& y)
+bool GetTouchCoords(int& x, int& y)
{
- float vx = x;
- float vy = y;
+ if (BotEnable)
+ {
+ float vx = x;
+ float vy = y;
- M23_Transform(TouchMtx, vx, vy);
+ M23_Transform(TouchMtx, vx, vy);
- x = (int)vx;
- y = (int)vy;
+ x = (int)vx;
+ y = (int)vy;
+
+ if (x >= 0 && x < 256 && y >= 0 && y < 192)
+ return true;
+ }
+ return false;
}
}