diff options
Diffstat (limited to 'src/frontend/Util_Video.cpp')
-rw-r--r-- | src/frontend/Util_Video.cpp | 297 |
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; } } |