Nooncraft/src/main.cpp

197 lines
4.9 KiB
C++

#include "render.h"
#include "world.h"
#include "camera.h"
#include "game.h"
#include <gint/keyboard.h>
#include <gint/timer.h>
#include <gint/cpu.h>
#include <libprof.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define NOONCRAFT_ENABLE_USB
#ifdef NOONCRAFT_ENABLE_USB
#include <gint/usb.h>
#include <gint/usb-ff-bulk.h>
#include <gint/display.h>
static bool getkey_recording = false;
static bool getkey_global_shortcuts(key_event_t ev)
{
if(usb_is_open() && ev.key == KEY_XOT && !ev.shift && !ev.alpha) {
usb_fxlink_screenshot(true);
return true;
}
if(usb_is_open() && ev.key == KEY_FRAC && !ev.shift && !ev.alpha) {
if(!getkey_recording) {
dupdate_set_hook(GINT_CALL(usb_fxlink_videocapture, (int)false));
usb_fxlink_videocapture(true);
getkey_recording = true;
}
else {
dupdate_set_hook(GINT_CALL_NULL);
getkey_recording = false;
}
return true;
}
return false;
}
#endif /* NOONCRAFT_ENABLE_USB */
static char debugMessage[128];
static void renderGame(Game *game)
{
char separator[57];
memset(separator, '-', 56);
separator[56] = 0;
Camera *camera = game->camera;
renderClear();
GlyphCluster playerCluster(GLYPH_DEGREE_UNDERLINE, ' ',
GLYPH_CAPITAL_LAMBDA, ' ');
GlyphCluster cursorCluster(0, GLYPH_OPLUS, 0, 0);
if(game->isBreakingBlock()) {
static Glyph breakingGlyphs[4] = {
GLYPH_MIDDLE_DOT, GLYPH_SMALL_SQUARE, GLYPH_CURRENCY_SIGN, 0x7f,
};
int stage = game->blockBreakingProgress();
cursorCluster.glyphs[1] = breakingGlyphs[stage];
}
Nooncraft::renderCamera(26, 12, camera, game->playerPos, playerCluster,
game->cursorPos, cursorCluster);
GlyphCluster invLeft(' ', GLYPH_PARALLEL_TO, ' ', GLYPH_PARALLEL_TO);
GlyphCluster invRight(GLYPH_PARALLEL_TO, ' ', GLYPH_PARALLEL_TO, ' ');
int hudY = 27;
renderText(0, hudY, separator);
renderText(22, hudY+1, "HAND: COBBLESTONE");
renderFormat(46, hudY+1, "X%d Y%d", game->playerPos.x, game->playerPos.y);
BlockInfo *pointedBlockInfo = game->pointedBlockInfo();
char const *pointedBlockName =
pointedBlockInfo ? pointedBlockInfo->name : "(NOTHING)";
renderFormat(22, hudY+2, "CURSOR: %s", pointedBlockName);
renderFormat(22, hudY+3, debugMessage);
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();
srand(0xc0ffee);
#ifdef NOONCRAFT_ENABLE_USB
usb_interface_t const *interfaces[] = { &usb_ff_bulk, NULL };
usb_open(interfaces, GINT_CALL_NULL);
getkey_set_feature_function(getkey_global_shortcuts);
#endif /* NOONCRAFT_ENABLE_USB */
/* Should be a square */
World *world = Nooncraft::mkWorld(128, 128);
if(!world)
return 0;
renderClear();
renderText(0, 0, "GENERATING WORLD...");
renderUpdate();
Nooncraft::genWorld(world);
Camera *camera = new Camera(world);
camera->visible = WorldRect(-13, 14, -6, 6);
Game game;
game.world = world;
game.camera = camera;
game.playerPos = world->findSpawnPoint();
// TODO: Potential world border overflow here (unlikely)
game.cursorPos = game.playerPos + WorldCoord::Right;
game.damageTicks = -1;
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;
int tick = 0;
while(runMainLoop) {
while(!nextFrame)
sleep();
nextFrame = 0;
tick++;
frameDuration = prof_exec({
sprintf(debugMessage, "FRAME: %d MS", frameDuration);
// sprintf(debugMessage, "VORONOI: %d MS", voronoiTime / 1000);
renderGame(&game);
renderUpdate();
}) / 1000;
key_event_t ev;
while((ev = pollevent()).type != KEYEV_NONE) {
if(ev.type == KEYEV_UP) {
if(ev.key == KEY_OPTN) {
game.damageTicks = -1;
continue;
}
continue;
}
if(getkey_global_shortcuts(ev))
continue;
if(ev.key == KEY_MENU)
runMainLoop = false;
if(ev.key == KEY_OPTN) {
if(game.world->canBreakBlock(game.cursorPos))
game.damageTicks = 0;
}
}
/* Clamp speed to 10 blocks/s */
if(tick % 2 == 0 && !game.isBreakingBlock()) {
if(keydown(KEY_LEFT) && !keydown(KEY_SHIFT))
game.movePlayerBy(WorldCoord::Left);
if(keydown(KEY_RIGHT) && !keydown(KEY_SHIFT))
game.movePlayerBy(WorldCoord::Right);
if(keydown(KEY_UP) && !keydown(KEY_SHIFT))
game.movePlayerBy(WorldCoord::Up);
if(keydown(KEY_DOWN) && !keydown(KEY_SHIFT))
game.movePlayerBy(WorldCoord::Down);
if(keydown(KEY_LEFT) && keydown(KEY_SHIFT))
game.moveCursorBy(WorldCoord::Left);
if(keydown(KEY_RIGHT) && keydown(KEY_SHIFT))
game.moveCursorBy(WorldCoord::Right);
if(keydown(KEY_UP) && keydown(KEY_SHIFT))
game.moveCursorBy(WorldCoord::Up);
if(keydown(KEY_DOWN) && keydown(KEY_SHIFT))
game.moveCursorBy(WorldCoord::Down);
}
game.updateBlockBreaking();
}
timer_stop(t);
delete camera;
delete world;
prof_quit();
return 1;
}