/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2015 Franklin Wei
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/*
* This code draws heavily on
* Jake Gordon's "How to build a racing game" tutorial at
*
*
*
* and
*
* Louis Gorenfield's "Lou's Pseudo 3d Page" at
*
*
*
* Thanks!
*/
#include "plugin.h"
#include "xracer.h"
#include "compat.h"
#include "generator.h"
#include "graphics.h"
#include "map.h"
#include "maps.h"
#include "road.h"
#include "sprite.h"
#include "util.h"
#include "fixedpoint.h" /* only used for FOV computation */
const struct plugin_api *rb;
/* can move to audiobuf if too big... */
struct road_segment road[MAX_ROAD_LENGTH];
/* this can be changed to allow for variable-sized maps */
unsigned int road_length=MAX_ROAD_LENGTH;
int camera_height = CAMERA_HEIGHT;
void generate_test_road(void)
{
gen_reset();
add_road(road, road_length, 0, road_length, 0, 0);
}
void do_early_init(void)
{
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
/* GIMME DAT RAW POWAH!!! */
rb->cpu_boost(true);
#endif
init_alloc();
}
void do_late_init(void)
{
}
enum plugin_status do_flythrough(void)
{
struct camera_t camera;
camera.depth = LCD_WIDTH/CAMERA_TAN;
camera.pos.x = 0;
/* y is automatically calculated */
camera.pos.z = 0;
camera.draw_dist = DRAW_DIST;
//generate_test_road();
//road_length = load_map(road, MAX_ROAD_LENGTH, loop_map, ARRAYLEN(loop_map));
//road_length = load_external_map(road, MAX_ROAD_LENGTH, "/output.xrm");
road_length = MAX_ROAD_LENGTH;
generate_random_road(road, road_length, HILLS, CURVES);
do_late_init();
long last_timestamp = *current_tick;
uint64_t frame = 0;
while(1)
{
int button = rb->button_get();
int mod = rb->modifier_get();
switch(button)
{
case BUTTON_UP:
switch(mod)
{
case MODIFIER_NONE:
camera_height += MANUAL_SPEED;
break;
case MODIFIER_CTRL:
camera.depth += 1;
break;
case MODIFIER_ALT:
camera.pos.z += MANUAL_SPEED;
break;
}
break;
case BUTTON_DOWN:
switch(mod)
{
case MODIFIER_NONE:
camera_height -= MANUAL_SPEED;
break;
case MODIFIER_CTRL:
camera.depth -= 1;
break;
case MODIFIER_ALT:
camera.pos.z -= MANUAL_SPEED;
break;
}
break;
case BUTTON_LEFT:
switch(mod)
{
case MODIFIER_NONE:
camera.pos.x -= MANUAL_SPEED;
break;
case MODIFIER_CTRL:
camera.draw_dist -= 8;
break;
}
break;
case BUTTON_RIGHT:
switch(mod)
{
case MODIFIER_NONE:
camera.pos.x += MANUAL_SPEED;
break;
case MODIFIER_CTRL:
camera.draw_dist += 8;
break;
}
break;
}
camera.pos.z += 512;
/* loop the track right before going off the "end" */
camera.pos.z %= (road_length - camera.draw_dist) * SEGMENT_LENGTH;
render(&camera, road, road_length, camera_height);
char buf[32];
int dt = *current_tick - last_timestamp;
snprintf(buf, sizeof(buf), "DT: %d", dt);
SET_FOREGROUND(LCD_WHITE);
PUTSXY(0, 0, buf);
snprintf(buf, sizeof(buf), "CAMERA: (%d, %d, %d)", camera.pos.x, camera.pos.y, camera.pos.z);
SET_FOREGROUND(LCD_WHITE);
PUTSXY(0, 12, buf);
snprintf(buf, sizeof(buf), "DEPTH: %d", camera.depth);
SET_FOREGROUND(LCD_WHITE);
PUTSXY(0, 24, buf);
snprintf(buf, sizeof(buf), "DRAWDIST: %d", camera.draw_dist);
SET_FOREGROUND(LCD_WHITE);
PUTSXY(0, 36, buf);
snprintf(buf, sizeof(buf), "FRAME #%d", frame);
SET_FOREGROUND(LCD_WHITE);
PUTSXY(0, 48, buf);
snprintf(buf, sizeof(buf), "FPS: %d", HZ/(!dt?1:dt));
SET_FOREGROUND(LCD_WHITE);
PUTSXY(0, 60, buf);
LCD_UPDATE();
//rb->sleep((HZ/100)-dt);
YIELD();
last_timestamp = *current_tick;
++frame;
}
}
/* plugin_start(): plugin entry point */
/* contains main loop */
enum plugin_status xracer_main(const struct plugin_api *param)
{
rb = param;
do_early_init();
enum plugin_status rc = do_flythrough();
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
rb->cpu_boost(false);
#endif
return rc;
}