camera: debug controls
This commit is contained in:
parent
b92cbcec5b
commit
8b1eb85c51
|
@ -4,6 +4,7 @@ project(Nooncraft LANGUAGES CXX)
|
|||
include(GenerateG3A)
|
||||
include(Fxconv)
|
||||
find_package(Gint 2.8 REQUIRED)
|
||||
find_package(LibProf 2.1 REQUIRED)
|
||||
|
||||
set(SOURCES
|
||||
src/block.cpp
|
||||
|
@ -20,7 +21,7 @@ fxconv_declare_converters(converters.py)
|
|||
|
||||
add_executable(addin ${SOURCES} ${ASSETS})
|
||||
target_compile_options(addin PRIVATE -Wall -Wextra -Wno-narrowing -Os -std=c++20)
|
||||
target_link_libraries(addin Gint::Gint -lsupc++)
|
||||
target_link_libraries(addin LibProf::LibProf Gint::Gint -lsupc++)
|
||||
|
||||
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
|
||||
message(FATAL_ERROR "This game is not supported on fx-9860G!")
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
#include "graphics.h"
|
||||
#include "render.h"
|
||||
#include <stdio.h>
|
||||
|
||||
WorldRect Camera::validCenters() const
|
||||
{
|
||||
WorldRect b = this->world->worldBorder;
|
||||
|
||||
/* Allow up to just next to the world border */
|
||||
return WorldRect(b.xmin + 1, b.xmax - 1, b.ymin + 1, b.ymax - 1);
|
||||
}
|
||||
|
||||
void Camera::moveBy(WorldCoord direction)
|
||||
{
|
||||
this->center = this->validCenters().clampPoint(this->center + direction);
|
||||
}
|
||||
|
||||
namespace Nooncraft {
|
||||
|
||||
|
@ -8,11 +22,25 @@ void renderCamera(int x, int y, Camera *camera)
|
|||
if(!camera)
|
||||
return;
|
||||
|
||||
WorldRect r = camera->region;
|
||||
WorldRect r = camera->visible;
|
||||
for(int dy = r.ymin; dy <= r.ymax; dy++)
|
||||
for(int dx = r.xmin; dx <= r.xmax; dx++) {
|
||||
GlyphCluster c('@', '#', '~', '&');
|
||||
renderCluster(x+2*dx, y+2*dy, c);
|
||||
int wx = camera->center.x + dx;
|
||||
int wy = camera->center.y + dy;
|
||||
|
||||
if(!camera->world->worldBorder.contains(WorldCoord(wx, wy))) {
|
||||
continue;
|
||||
}
|
||||
else if(camera->world->isPointOnWorldBorder(wx, wy)) {
|
||||
GlyphCluster c('{', '}', '{', '}');
|
||||
renderCluster(x+2*dx, y+2*dy, c);
|
||||
}
|
||||
else {
|
||||
char str[5];
|
||||
sprintf(str, "%02X%02X", wx & 0xff, wy & 0xff);
|
||||
GlyphCluster c(str[0], str[1], str[2], str[3]);
|
||||
renderCluster(x+2*dx, y+2*dy, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
struct Camera
|
||||
{
|
||||
Camera(World const *w): world {w}, center {0,0}, region {-1,1,-1,1} {}
|
||||
Camera(World const *w): world {w}, center {0,0}, visible {-1,1,-1,1} {}
|
||||
|
||||
/* Underlying world object */
|
||||
World const *world;
|
||||
|
@ -14,7 +14,13 @@ struct Camera
|
|||
WorldCoord center;
|
||||
/* Local rectangle around center at (0,0). This influences how much of the
|
||||
screen the camera will take up when rendered */
|
||||
WorldRect region;
|
||||
WorldRect visible;
|
||||
|
||||
/* Range of possible values for center */
|
||||
WorldRect validCenters() const;
|
||||
|
||||
/* Move the camera by a fixed vector */
|
||||
void moveBy(WorldCoord direction);
|
||||
};
|
||||
|
||||
namespace Nooncraft {
|
||||
|
|
72
src/main.cpp
72
src/main.cpp
|
@ -2,21 +2,13 @@
|
|||
#include "world.h"
|
||||
#include "graphics.h"
|
||||
#include <gint/keyboard.h>
|
||||
#include <gint/timer.h>
|
||||
#include <gint/cpu.h>
|
||||
#include <libprof.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(void)
|
||||
static void renderGame(Camera *camera, int frameDuration)
|
||||
{
|
||||
World *world = Nooncraft::mkWorld(128, 128);
|
||||
if(!world)
|
||||
return 0;
|
||||
|
||||
Nooncraft::genWorld(world);
|
||||
|
||||
Camera *camera = new Camera(world);
|
||||
camera->region = WorldRect(-13, 14, -6, 6);
|
||||
|
||||
// -
|
||||
|
||||
char separator[57];
|
||||
memset(separator, '-', 56);
|
||||
separator[56] = 0;
|
||||
|
@ -24,30 +16,72 @@ int main(void)
|
|||
renderClear();
|
||||
Nooncraft::renderCamera(26, 12, camera);
|
||||
|
||||
// HUD
|
||||
|
||||
GlyphCluster invLeft(' ', GLYPH_PARALLEL_TO, ' ', GLYPH_PARALLEL_TO);
|
||||
GlyphCluster invRight(GLYPH_PARALLEL_TO, ' ', GLYPH_PARALLEL_TO, ' ');
|
||||
int hudY = 27;
|
||||
|
||||
renderText(0, hudY, separator);
|
||||
renderText(24, hudY+1, "COBBLESTONE");
|
||||
renderFormat(24, hudY+2, "FRAME: %d MS", frameDuration);
|
||||
renderCluster(0, hudY+1, invLeft);
|
||||
renderCluster(2, hudY+1, Nooncraft::getBlockInfo(2)->cluster);
|
||||
renderCluster(20, hudY+1, invRight);
|
||||
renderText(2, hudY+3, "1 2 3 4 5 6 7 8 9");
|
||||
}
|
||||
|
||||
// -
|
||||
int main(void)
|
||||
{
|
||||
prof_init();
|
||||
|
||||
renderText(0, 0, "NOONCRAFT");
|
||||
renderUpdate();
|
||||
World *world = Nooncraft::mkWorld(128, 128);
|
||||
if(!world)
|
||||
return 0;
|
||||
|
||||
getkey();
|
||||
Nooncraft::genWorld(world);
|
||||
|
||||
//-
|
||||
Camera *camera = new Camera(world);
|
||||
camera->visible = WorldRect(-13, 14, -6, 6);
|
||||
|
||||
volatile int nextFrame = 1;
|
||||
int t = timer_configure(TIMER_ANY, 1000000/20, GINT_CALL_SET(&nextFrame));
|
||||
timer_start(t);
|
||||
|
||||
bool runMainLoop = true;
|
||||
int frameDuration = 0;
|
||||
|
||||
while(runMainLoop) {
|
||||
while(!nextFrame)
|
||||
sleep();
|
||||
nextFrame = 0;
|
||||
|
||||
frameDuration = prof_exec({
|
||||
renderGame(camera, frameDuration);
|
||||
renderUpdate();
|
||||
}) / 1000;
|
||||
|
||||
key_event_t ev;
|
||||
while((ev = pollevent()).type != KEYEV_NONE) {
|
||||
if(ev.type == KEYEV_UP)
|
||||
continue;
|
||||
|
||||
if(ev.key == KEY_MENU)
|
||||
runMainLoop = false;
|
||||
}
|
||||
|
||||
if(keydown(KEY_LEFT))
|
||||
camera->moveBy(WorldCoord::Left);
|
||||
if(keydown(KEY_RIGHT))
|
||||
camera->moveBy(WorldCoord::Right);
|
||||
if(keydown(KEY_UP))
|
||||
camera->moveBy(WorldCoord::Up);
|
||||
if(keydown(KEY_DOWN))
|
||||
camera->moveBy(WorldCoord::Down);
|
||||
}
|
||||
|
||||
timer_stop(t);
|
||||
delete camera;
|
||||
delete world;
|
||||
prof_quit();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
17
src/world.h
17
src/world.h
|
@ -4,6 +4,7 @@
|
|||
#include "block.h"
|
||||
#include <stddef.h>
|
||||
#include <gint/defs/attributes.h>
|
||||
#include <gint/defs/util.h>
|
||||
|
||||
struct WorldCoord
|
||||
{
|
||||
|
@ -50,6 +51,17 @@ struct WorldRect
|
|||
int height() const {
|
||||
return ymax - ymin + 1;
|
||||
}
|
||||
|
||||
WorldCoord clampPoint(WorldCoord p) const {
|
||||
p.x = max(p.x, xmin);
|
||||
p.x = min(p.x, xmax);
|
||||
p.y = max(p.y, ymin);
|
||||
p.y = min(p.y, ymax);
|
||||
return p;
|
||||
}
|
||||
bool contains(WorldCoord p) const {
|
||||
return xmin <= p.x && p.x <= xmax && ymin <= p.y && p.y <= ymax;
|
||||
}
|
||||
};
|
||||
|
||||
struct World
|
||||
|
@ -76,6 +88,11 @@ struct World
|
|||
int ix = (x + limits.xmin) + (y + limits.ymin) * limits.width();
|
||||
return cells[ix];
|
||||
}
|
||||
|
||||
bool isPointOnWorldBorder(int16_t x, int16_t y) const {
|
||||
return x == worldBorder.xmin || x == worldBorder.xmax
|
||||
|| y == worldBorder.ymin || y == worldBorder.ymax;
|
||||
}
|
||||
};
|
||||
|
||||
namespace Nooncraft {
|
||||
|
|
Loading…
Reference in New Issue