197 lines
4.9 KiB
C++
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;
|
|
}
|