mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
170 lines
5.3 KiB
C++
170 lines
5.3 KiB
C++
#include "layout.h"
|
|
|
|
namespace Ion {
|
|
namespace Simulator {
|
|
namespace Layout {
|
|
|
|
static constexpr int backgroundWidth = 1160;
|
|
static constexpr int backgroundHeight = 2220;
|
|
|
|
static constexpr float X(int x) { return static_cast<float>(x)/static_cast<float>(backgroundWidth); }
|
|
static constexpr float Y(int y) { return static_cast<float>(y)/static_cast<float>(backgroundHeight); }
|
|
|
|
static constexpr SDL_FRect areaOfInterest = {X(110), Y(30), X(940), Y(2150)};
|
|
static constexpr SDL_FRect screenRect = {X(192), Y(191), X(779), Y(582)};
|
|
|
|
static SDL_Rect sFrame;
|
|
|
|
static void makeAbsolute(const SDL_FRect * f, SDL_Rect * r) {
|
|
r->x = f->x * sFrame.w + sFrame.x;
|
|
r->y = f->y * sFrame.h + sFrame.y;
|
|
r->w = f->w * sFrame.w;
|
|
r->h = f->h * sFrame.h;
|
|
}
|
|
|
|
static void makeAbsolute(const SDL_FPoint * f, SDL_Point * p) {
|
|
p->x = f->x * sFrame.w + sFrame.x;
|
|
p->y = f->y * sFrame.h + sFrame.y;
|
|
}
|
|
|
|
void recompute(int width, int height) {
|
|
float windowWidth = static_cast<float>(width);
|
|
float windowHeight = static_cast<float>(height);
|
|
|
|
float aoiRatio = (areaOfInterest.w / areaOfInterest.h) * (static_cast<float>(backgroundWidth)/static_cast<float>(backgroundHeight));
|
|
float windowRatio = windowWidth/windowHeight;
|
|
|
|
if (aoiRatio > windowRatio) {
|
|
// Area of interest is wider than the window (e.g. aoe 16:9, window 4:3)
|
|
// There will be "black bars" above and below
|
|
// We want the areaOfInterest's rect in pixels to be
|
|
// aoiInPixels.w = windowWidth
|
|
// aoiInPixels.x = 0
|
|
// aoiInPixels.h = windowWidth / (aoiRatio*deviceRatio)
|
|
// aoiInPixels.y = (windowHeight - aoiInPixels.h)/2;
|
|
// But we also know that
|
|
// aoiInPixels.x = sFrame.x + areaOfInterest.x*sFrame.w
|
|
// aoiInPixels.y = sFrame.y + areaOfInterest.y*sFrame.h
|
|
// aoiInPixels.w = sFrame.w * areaOfInterest.w
|
|
// aoiInPixels.h = sFrame.h * areaOfInterest*h
|
|
|
|
sFrame.w = windowWidth / areaOfInterest.w;
|
|
sFrame.h = (windowWidth / aoiRatio) / areaOfInterest.h;
|
|
sFrame.x = - areaOfInterest.x * sFrame.w;
|
|
sFrame.y = (windowHeight - windowWidth/aoiRatio)/2 - areaOfInterest.y * sFrame.h;
|
|
} else {
|
|
// Area of interest is taller than the window (e.g. window 16:9, aoe 4:3)
|
|
// There will be "black bars" on the sides
|
|
// We want the areaOfInterest's rect in pixels to be
|
|
// aoiInPixels.h = windowHeight
|
|
// aoiInPixels.y = 0
|
|
// aoiInPixels.x = windowHeight * aoiRatio
|
|
// aoiInPixels.w = (windowWidth - aoiInPixels.w)/2;
|
|
// But we also know that
|
|
// aoiInPixels.x = sFrame.x + areaOfInterest.x*sFrame.w
|
|
// aoiInPixels.y = sFrame.y + areaOfInterest.y*sFrame.h
|
|
// aoiInPixels.w = sFrame.w * areaOfInterest.w
|
|
// aoiInPixels.h = sFrame.h * areaOfInterest*h
|
|
|
|
sFrame.h = windowHeight / areaOfInterest.h;
|
|
sFrame.w = (windowHeight * aoiRatio) / areaOfInterest.w;
|
|
sFrame.y = - areaOfInterest.y * sFrame.h;
|
|
sFrame.x = (windowWidth - windowHeight*aoiRatio)/2.0f - areaOfInterest.x * sFrame.w;
|
|
}
|
|
}
|
|
|
|
void getScreenRect(SDL_Rect * rect) {
|
|
makeAbsolute(&screenRect, rect);
|
|
}
|
|
|
|
void getBackgroundRect(SDL_Rect * rect) {
|
|
rect->x = sFrame.x;
|
|
rect->y = sFrame.y;
|
|
rect->w = sFrame.w;
|
|
rect->h = sFrame.h;
|
|
}
|
|
|
|
static constexpr SDL_FPoint sKeyCenters[Keyboard::NumberOfValidKeys] = {
|
|
{X(185), Y(1029)}, // A1, Left
|
|
{X(273), Y(941)}, // A2, Up
|
|
{X(273), Y(1117)}, // A3, Down
|
|
{X(361), Y(1029)}, // A4, Right
|
|
{X(810), Y(1029)}, // A5, OK
|
|
{X(963), Y(1029)}, // A6, Back
|
|
|
|
{X(580), Y(958)}, // B1, Home
|
|
{X(580), Y(1094)}, // B2, Power
|
|
|
|
{X(198), Y(1252)}, // C1, Shift
|
|
{X(352), Y(1252)}, // C2, Alpha
|
|
{X(506), Y(1252)}, // C3, xnt
|
|
{X(656), Y(1252)}, // C4, var
|
|
{X(810), Y(1252)}, // C5, toolbox
|
|
{X(963), Y(1252)}, // C6, Delete
|
|
|
|
{X(198), Y(1375)}, // D1, exp
|
|
{X(352), Y(1375)}, // D2, ln
|
|
{X(506), Y(1375)}, // D3, log
|
|
{X(656), Y(1375)}, // D4, i
|
|
{X(810), Y(1375)}, // D5, comma
|
|
{X(963), Y(1375)}, // D6, power
|
|
|
|
{X(198), Y(1498)}, // E1, sin
|
|
{X(352), Y(1498)}, // E2, cos
|
|
{X(506), Y(1498)}, // E3, tan
|
|
{X(656), Y(1498)}, // E4, pi
|
|
{X(810), Y(1498)}, // E5, sqrt
|
|
{X(963), Y(1498)}, // E6, square
|
|
|
|
{X(210), Y(1629)}, // F1, 7
|
|
{X(395), Y(1629)}, // F2, 8
|
|
{X(580), Y(1629)}, // F3, 9
|
|
{X(765), Y(1629)}, // F4, (
|
|
{X(950), Y(1629)}, // F5, )
|
|
|
|
{X(210), Y(1766)}, // G1, 4
|
|
{X(395), Y(1766)}, // G2, 5
|
|
{X(580), Y(1766)}, // G3, 6
|
|
{X(765), Y(1766)}, // G4, *
|
|
{X(950), Y(1766)}, // G5, /
|
|
|
|
{X(210), Y(1902)}, // H1, 1
|
|
{X(395), Y(1902)}, // H2, 2
|
|
{X(580), Y(1902)}, // H3, 3
|
|
{X(765), Y(1902)}, // H4, +
|
|
{X(950), Y(1902)}, // H5, -
|
|
|
|
{X(210), Y(2040)}, // I1, 0
|
|
{X(395), Y(2040)}, // I2, .
|
|
{X(580), Y(2040)}, // I3, x10
|
|
{X(765), Y(2040)}, // I4, Ans
|
|
{X(950), Y(2040)}, // I5, EXE
|
|
};
|
|
|
|
static void getKeyCenter(int validKeyIndex, SDL_Point * point) {
|
|
assert(validKeyIndex >= 0);
|
|
assert(validKeyIndex < Keyboard::NumberOfValidKeys);
|
|
makeAbsolute(&sKeyCenters[validKeyIndex], point);
|
|
}
|
|
|
|
Keyboard::Key keyAt(SDL_Point * p) {
|
|
int minSquaredDistance = -1;
|
|
Keyboard::Key nearestKey = Keyboard::Key::None;
|
|
for (int i=0; i<Keyboard::NumberOfValidKeys; i++) {
|
|
SDL_Point keyCenter;
|
|
getKeyCenter(i, &keyCenter);
|
|
int dx = keyCenter.x - p->x;
|
|
int dy = keyCenter.y - p->y;
|
|
int squaredDistance = dx*dx + dy*dy;
|
|
if (squaredDistance < minSquaredDistance || minSquaredDistance < 0) {
|
|
minSquaredDistance = squaredDistance;
|
|
nearestKey = Keyboard::ValidKeys[i];
|
|
}
|
|
}
|
|
return nearestKey;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|