screen
This commit is contained in:
@@ -9,6 +9,7 @@ target_sources(${DUSK_TARGET_NAME}
|
|||||||
display.c
|
display.c
|
||||||
camera.c
|
camera.c
|
||||||
tileset.c
|
tileset.c
|
||||||
|
screen.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Subdirectories
|
# Subdirectories
|
||||||
|
@@ -8,23 +8,265 @@
|
|||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
|
#include "display/mesh/quad.h"
|
||||||
|
|
||||||
|
screen_t SCREEN;
|
||||||
|
|
||||||
void screenInit() {
|
void screenInit() {
|
||||||
memoryZero(&SCREEN, sizeof(screen_t));
|
memoryZero(&SCREEN, sizeof(screen_t));
|
||||||
|
|
||||||
|
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||||
|
cameraInitOrthographic(&SCREEN.framebufferCamera);
|
||||||
|
SCREEN.framebufferCamera.viewType = CAMERA_VIEW_TYPE_2D;
|
||||||
|
SCREEN.framebufferCamera._2d.position[0] = 0;
|
||||||
|
SCREEN.framebufferCamera._2d.position[1] = 0;
|
||||||
|
SCREEN.framebufferCamera._2d.zoom = 1.0f;
|
||||||
|
|
||||||
|
quadBuffer(
|
||||||
|
SCREEN.frameBufferMeshVertices,
|
||||||
|
0.0f, 0.0f,
|
||||||
|
1.0f, 1.0f,
|
||||||
|
COLOR_WHITE,
|
||||||
|
0.0f, 0.0f,
|
||||||
|
1.0f, 1.0f
|
||||||
|
);
|
||||||
|
meshInit(
|
||||||
|
&SCREEN.frameBufferMesh,
|
||||||
|
QUAD_PRIMITIVE_TYPE,
|
||||||
|
QUAD_VERTEX_COUNT,
|
||||||
|
SCREEN.frameBufferMeshVertices
|
||||||
|
);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void screenBind() {
|
void screenBind() {
|
||||||
// Assume framebuffer is already unbound
|
// Assume backbuffer is currently bound.
|
||||||
|
switch(SCREEN.mode) {
|
||||||
|
case SCREEN_MODE_BACKBUFFER: {
|
||||||
|
// Screen mode backbuffer uses the full display size
|
||||||
|
SCREEN.width = frameBufferGetWidth(FRAMEBUFFER_BOUND);
|
||||||
|
SCREEN.height = frameBufferGetHeight(FRAMEBUFFER_BOUND);
|
||||||
|
|
||||||
|
// No needd for a framebuffer.
|
||||||
|
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||||
|
if(SCREEN.framebufferReady) {
|
||||||
|
frameBufferDispose(&SCREEN.framebuffer);
|
||||||
|
SCREEN.framebufferReady = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||||
|
case SCREEN_MODE_ASPECT_RATIO: {
|
||||||
|
// Aspect ratio mode, requires a framebuffer.
|
||||||
|
int32_t fbWidth, fbHeight;
|
||||||
|
fbWidth = frameBufferGetWidth(FRAMEBUFFER_BOUND);
|
||||||
|
fbHeight = frameBufferGetHeight(FRAMEBUFFER_BOUND);
|
||||||
|
|
||||||
|
float_t currentAspect = (float_t)fbWidth / (float_t)fbHeight;
|
||||||
|
if(currentAspect == SCREEN.aspectRatio.ratio) {
|
||||||
|
// No need to use framebuffer.
|
||||||
|
SCREEN.width = fbWidth;
|
||||||
|
SCREEN.height = fbHeight;
|
||||||
|
|
||||||
|
if(SCREEN.framebufferReady) {
|
||||||
|
frameBufferDispose(&SCREEN.framebuffer);
|
||||||
|
SCREEN.framebufferReady = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t newFbWidth, newFbHeight;
|
||||||
|
if(currentAspect > SCREEN.aspectRatio.ratio) {
|
||||||
|
// Wider than target aspect, limit by height
|
||||||
|
newFbWidth = (int32_t)floorf(fbHeight * SCREEN.aspectRatio.ratio);
|
||||||
|
newFbHeight = (int32_t)fbHeight;
|
||||||
|
} else {
|
||||||
|
// Taller than target aspect, limit by width
|
||||||
|
newFbHeight = (int32_t)floorf(fbWidth / SCREEN.aspectRatio.ratio);
|
||||||
|
newFbWidth = (int32_t)fbWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SCREEN.framebufferReady) {
|
||||||
|
// Is current framebuffer the correct size?
|
||||||
|
int32_t curFbWidth, curFbHeight;
|
||||||
|
curFbWidth = frameBufferGetWidth(&SCREEN.framebuffer);
|
||||||
|
curFbHeight = frameBufferGetHeight(&SCREEN.framebuffer);
|
||||||
|
if(curFbWidth == newFbWidth && curFbHeight == newFbHeight) {
|
||||||
|
// Correct size, nothing to do.
|
||||||
|
SCREEN.width = newFbWidth;
|
||||||
|
SCREEN.height = newFbHeight;
|
||||||
|
frameBufferBind(&SCREEN.framebuffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need a new framebuffer.
|
||||||
|
frameBufferDispose(&SCREEN.framebuffer);
|
||||||
|
SCREEN.framebufferReady = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new framebuffer
|
||||||
|
frameBufferInit(&SCREEN.framebuffer, newFbWidth, newFbHeight);
|
||||||
|
SCREEN.framebufferReady = true;
|
||||||
|
SCREEN.width = newFbWidth;
|
||||||
|
SCREEN.height = newFbHeight;
|
||||||
|
|
||||||
|
// Bind FB
|
||||||
|
frameBufferBind(&SCREEN.framebuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCREEN_MODE_FIXED_HEIGHT: {
|
||||||
|
float_t fbWidth = (float_t)frameBufferGetWidth(FRAMEBUFFER_BOUND);
|
||||||
|
float_t fbHeight = (float_t)frameBufferGetHeight(FRAMEBUFFER_BOUND);
|
||||||
|
float_t fbAspect = fbWidth / fbHeight;
|
||||||
|
|
||||||
|
int32_t newFbWidth, newFbHeight;
|
||||||
|
newFbHeight = SCREEN.fixedHeight.height;
|
||||||
|
newFbWidth = (int32_t)floorf(newFbHeight * fbAspect);
|
||||||
|
|
||||||
|
SCREEN.width = newFbWidth;
|
||||||
|
SCREEN.height = newFbHeight;
|
||||||
|
|
||||||
|
if(fbWidth == newFbWidth && fbHeight == newFbHeight) {
|
||||||
|
// No need to use framebuffer.
|
||||||
|
if(SCREEN.framebufferReady) {
|
||||||
|
frameBufferDispose(&SCREEN.framebuffer);
|
||||||
|
SCREEN.framebufferReady = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SCREEN.framebufferReady) {
|
||||||
|
// Is current framebuffer the correct size?
|
||||||
|
int32_t curFbWidth, curFbHeight;
|
||||||
|
curFbWidth = frameBufferGetWidth(&SCREEN.framebuffer);
|
||||||
|
curFbHeight = frameBufferGetHeight(&SCREEN.framebuffer);
|
||||||
|
if(curFbWidth == newFbWidth && curFbHeight == newFbHeight) {
|
||||||
|
frameBufferBind(&SCREEN.framebuffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need a new framebuffer.
|
||||||
|
frameBufferDispose(&SCREEN.framebuffer);
|
||||||
|
SCREEN.framebufferReady = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new framebuffer.
|
||||||
|
frameBufferInit(&SCREEN.framebuffer, newFbWidth, newFbHeight);
|
||||||
|
SCREEN.framebufferReady = true;
|
||||||
|
frameBufferBind(&SCREEN.framebuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default: {
|
||||||
|
assertUnreachable("Invalid screen mode.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void screenUnbind() {
|
void screenUnbind() {
|
||||||
|
switch(SCREEN.mode) {
|
||||||
|
case SCREEN_MODE_BACKBUFFER: {
|
||||||
|
// Nothing to do here.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||||
|
case SCREEN_MODE_ASPECT_RATIO:
|
||||||
|
case SCREEN_MODE_FIXED_HEIGHT:
|
||||||
|
if(SCREEN.framebufferReady) frameBufferBind(NULL);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default: {
|
||||||
|
assertUnreachable("Invalid screen mode.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void screenRender() {
|
void screenRender() {
|
||||||
|
if(SCREEN.mode == SCREEN_MODE_BACKBUFFER) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||||
|
if(
|
||||||
|
SCREEN.mode == SCREEN_MODE_ASPECT_RATIO ||
|
||||||
|
SCREEN.mode == SCREEN_MODE_FIXED_HEIGHT
|
||||||
|
) {
|
||||||
|
if(!SCREEN.framebufferReady) {
|
||||||
|
// Nothing to do here.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float_t bbWidth, bbHeight;
|
||||||
|
bbWidth = (float_t)frameBufferGetWidth(FRAMEBUFFER_BOUND);
|
||||||
|
bbHeight = (float_t)frameBufferGetHeight(FRAMEBUFFER_BOUND);
|
||||||
|
|
||||||
|
float_t backBufferAspect = bbWidth / bbHeight;
|
||||||
|
|
||||||
|
// Determine framebuffer centering
|
||||||
|
float_t fbWidth, fbHeight, fbAspect;
|
||||||
|
float_t fbX, fbY;
|
||||||
|
|
||||||
|
fbWidth = frameBufferGetWidth(&SCREEN.framebuffer);
|
||||||
|
fbHeight = frameBufferGetHeight(&SCREEN.framebuffer);
|
||||||
|
fbAspect = fbWidth / fbHeight;
|
||||||
|
|
||||||
|
if(backBufferAspect > fbAspect) {
|
||||||
|
fbHeight = bbHeight;
|
||||||
|
fbWidth = fbHeight * fbAspect;
|
||||||
|
fbX = (bbWidth - fbWidth) * 0.5f;
|
||||||
|
fbY = 0.0f;
|
||||||
|
} else {
|
||||||
|
fbWidth = bbWidth;
|
||||||
|
fbHeight = fbWidth / fbAspect;
|
||||||
|
fbX = 0.0f;
|
||||||
|
fbY = (bbHeight - fbHeight) * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float_t centerX = bbWidth * 0.5f;
|
||||||
|
float_t centerY = bbHeight * 0.5f;
|
||||||
|
|
||||||
|
SCREEN.framebufferCamera.orthographic.left = 0.0f;
|
||||||
|
SCREEN.framebufferCamera.orthographic.right = bbWidth;
|
||||||
|
SCREEN.framebufferCamera.orthographic.top = 0.0f;
|
||||||
|
SCREEN.framebufferCamera.orthographic.bottom = bbHeight;
|
||||||
|
quadBuffer(
|
||||||
|
SCREEN.frameBufferMeshVertices,
|
||||||
|
centerX - fbWidth * 0.5f, centerY + fbHeight * 0.5f, // top-left
|
||||||
|
centerX + fbWidth * 0.5f, centerY - fbHeight * 0.5f, // bottom-right
|
||||||
|
COLOR_WHITE,
|
||||||
|
0.0f, 0.0f,
|
||||||
|
1.0f, 1.0f
|
||||||
|
);
|
||||||
|
|
||||||
|
frameBufferClear(
|
||||||
|
FRAMEBUFFER_CLEAR_COLOR | FRAMEBUFFER_CLEAR_DEPTH,
|
||||||
|
COLOR_BLACK
|
||||||
|
);
|
||||||
|
cameraPushMatrix(&SCREEN.framebufferCamera);
|
||||||
|
textureBind(&SCREEN.framebuffer.texture);
|
||||||
|
meshDraw(&SCREEN.frameBufferMesh, 0, -1);
|
||||||
|
cameraPopMatrix();
|
||||||
|
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assertUnreachable("Invalid screen mode.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void screenDispose() {
|
void screenDispose() {
|
||||||
|
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||||
|
if(SCREEN.framebufferReady) {
|
||||||
|
frameBufferDispose(&SCREEN.framebuffer);
|
||||||
|
SCREEN.framebufferReady = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
@@ -7,31 +7,49 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "dusk.h"
|
#include "dusk.h"
|
||||||
|
#include "display/framebuffer/framebuffer.h"
|
||||||
|
#include "display/camera.h"
|
||||||
|
#include "display/mesh/quad.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SCREEN_MODE_BACKBUFFER,
|
SCREEN_MODE_BACKBUFFER,
|
||||||
|
|
||||||
#if DISPLAY_SIZE_DYNAMIC == 1
|
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||||
|
SCREEN_MODE_ASPECT_RATIO,// Maintains aspect at all cost
|
||||||
|
SCREEN_MODE_FIXED_HEIGHT, // Fixed height, width expands/contracts as needed
|
||||||
#endif
|
#endif
|
||||||
// SCREEN_MODE_FIXED_ASPECT,
|
|
||||||
// SCREEN_MODE_FIXED_ASPECT_INTEGER,
|
|
||||||
// SCREEN_MODE_FIXED_HEIGHT,
|
|
||||||
// SCREEN_MODE_FIXED_HEIGHT_INTEGER,
|
|
||||||
// SCREEN_MODE_FIXED_WIDTH,
|
|
||||||
// SCREEN_MODE_FIXED_WIDTH_INTEGER,
|
|
||||||
// SCREEN_MODE_SUPER_RESOLUTION_HEIGHT,
|
|
||||||
// SCREEN_MODE_SUPER_RESOLUTION_WIDTH
|
|
||||||
} screenmode_t;
|
} screenmode_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SCREEN_SCALE_MODE_FILL,
|
||||||
|
SCREEN_SCALE_MODE_INTEGER,
|
||||||
|
SCREEN_SCALE_MODE_INEGER_OVERFLOW
|
||||||
|
} screenscalemode_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
screenmode_t mode;
|
screenmode_t mode;
|
||||||
|
screenscalemode_t scaleMode;
|
||||||
|
|
||||||
// Calculated dimensions of the viewport, to be used by the camera
|
// Calculated dimensions of the viewport, to be used by the camera
|
||||||
int32_t width;
|
int32_t width;
|
||||||
int32_t height;
|
int32_t height;
|
||||||
|
|
||||||
|
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||||
|
framebuffer_t framebuffer;
|
||||||
|
bool_t framebufferReady;
|
||||||
|
camera_t framebufferCamera;
|
||||||
|
mesh_t frameBufferMesh;
|
||||||
|
meshvertex_t frameBufferMeshVertices[QUAD_VERTEX_COUNT];
|
||||||
|
#endif
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
struct {
|
||||||
|
float_t ratio;
|
||||||
|
} aspectRatio;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int32_t height;
|
||||||
|
} fixedHeight;
|
||||||
};
|
};
|
||||||
} screen_t;
|
} screen_t;
|
||||||
|
|
||||||
|
@@ -10,8 +10,15 @@
|
|||||||
#include "game/minesweeper/scene/scenesweep.h"
|
#include "game/minesweeper/scene/scenesweep.h"
|
||||||
#include "scene/scenemanager.h"
|
#include "scene/scenemanager.h"
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
|
#include "display/screen.h"
|
||||||
|
|
||||||
errorret_t gameInit(void) {
|
errorret_t gameInit(void) {
|
||||||
|
// Setup screen
|
||||||
|
// SCREEN.mode = SCREEN_MODE_FIXED_HEIGHT;
|
||||||
|
// SCREEN.fixedHeight.height = 270;
|
||||||
|
SCREEN.mode = SCREEN_MODE_ASPECT_RATIO;
|
||||||
|
SCREEN.aspectRatio.ratio = 16.0f / 9.0f;
|
||||||
|
|
||||||
errorChain(uiInit());
|
errorChain(uiInit());
|
||||||
|
|
||||||
sceneManagerRegisterScene(&SCENE_SWEEP);
|
sceneManagerRegisterScene(&SCENE_SWEEP);
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include "ui/uiframe.h"
|
#include "ui/uiframe.h"
|
||||||
#include "display/spritebatch/spritebatch.h"
|
#include "display/spritebatch/spritebatch.h"
|
||||||
#include "game/minesweeper/display/sweepboard.h"
|
#include "game/minesweeper/display/sweepboard.h"
|
||||||
|
#include "display/screen.h"
|
||||||
|
|
||||||
scene_t SCENE_SWEEP = {
|
scene_t SCENE_SWEEP = {
|
||||||
.name = "sweep",
|
.name = "sweep",
|
||||||
@@ -34,9 +35,8 @@ void sceneSweepUpdate(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sceneSweepRender(void) {
|
void sceneSweepRender(void) {
|
||||||
float_t w, h;
|
int32_t w = SCREEN.width;
|
||||||
w = 320;
|
int32_t h = SCREEN.height;
|
||||||
h = 240;
|
|
||||||
|
|
||||||
SCENE_SWEEP_DATA.camera.orthographic.left = 0;
|
SCENE_SWEEP_DATA.camera.orthographic.left = 0;
|
||||||
SCENE_SWEEP_DATA.camera.orthographic.right = w;
|
SCENE_SWEEP_DATA.camera.orthographic.right = w;
|
||||||
|
@@ -9,13 +9,12 @@
|
|||||||
#include "ui/uifps.h"
|
#include "ui/uifps.h"
|
||||||
#include "ui/uiconsole.h"
|
#include "ui/uiconsole.h"
|
||||||
#include "ui/uiframe.h"
|
#include "ui/uiframe.h"
|
||||||
#include "display/framebuffer/framebuffer.h"
|
#include "display/screen.h"
|
||||||
#include "display/spritebatch/spritebatch.h"
|
#include "display/spritebatch/spritebatch.h"
|
||||||
|
|
||||||
#include "display/tileset/tileset_minogram.h"
|
#include "display/tileset/tileset_minogram.h"
|
||||||
#include "display/tileset/tileset_ui.h"
|
#include "display/tileset/tileset_ui.h"
|
||||||
#include "display/tileset/tileset_ui_frame.h"
|
#include "display/tileset/tileset_ui_frame.h"
|
||||||
#include "display/tileset/tileset_frame_large.h"
|
|
||||||
#include "display/tileset/tileset_background.h"
|
#include "display/tileset/tileset_background.h"
|
||||||
|
|
||||||
ui_t UI;
|
ui_t UI;
|
||||||
@@ -55,12 +54,9 @@ errorret_t uiInit(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void uiRender(void) {
|
void uiRender(void) {
|
||||||
int32_t w = frameBufferGetWidth(FRAMEBUFFER_BOUND);
|
|
||||||
int32_t h = frameBufferGetHeight(FRAMEBUFFER_BOUND);
|
|
||||||
|
|
||||||
UI.camera.orthographic.left = 0;
|
UI.camera.orthographic.left = 0;
|
||||||
UI.camera.orthographic.right = w;
|
UI.camera.orthographic.right = SCREEN.width;
|
||||||
UI.camera.orthographic.bottom = h;
|
UI.camera.orthographic.bottom = SCREEN.height;
|
||||||
UI.camera.orthographic.top = 0;
|
UI.camera.orthographic.top = 0;
|
||||||
|
|
||||||
cameraPushMatrix(&UI.camera);
|
cameraPushMatrix(&UI.camera);
|
||||||
|
Reference in New Issue
Block a user