/*************************************************************************** * __________ __ ___. * 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 "lib/helper.h" #include "lib/pluginlib_actions.h" #include "lib/pluginlib_exit.h" #include "fixedpoint.h" /* only used for FOV computation */ /* 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); for(unsigned int i = 0; i < road_length; ++i) add_sprite(road + i, &sprites[0]); } void do_early_init(void) { #ifdef HAVE_ADJUSTABLE_CPU_FREQ /* GIMME DAT RAW POWAH!!! */ rb->cpu_boost(true); #endif /* disable backlight timeout */ backlight_ignore_timeout(); init_alloc(); } #if LCD_DEPTH < 4 struct _grey_info _grey_info; #endif void do_late_init(void) { #if (LCD_DEPTH < 4) /* greylib init */ size_t buf_sz = util_alloc_remaining(); if(!grey_init(util_alloc(buf_sz), buf_sz, GREY_BUFFERED|GREY_RAWMAPPED|GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, NULL)) { error("grey init failed"); } grey_show(true); #endif } enum plugin_status do_flythrough(void) { struct camera_t camera; camera.depth = camera_calc_depth(CAMERA_FOV); LOGF("camera depth: %d", camera.depth); camera.pos.x = 0; /* y is automatically calculated */ camera.pos.z = 0; //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"); if(road_length == (unsigned int)-1) { warning("Failed to load map, using random map"); road_length = MAX_ROAD_LENGTH; generate_random_road(road, road_length, HILLS, CURVES); } long last_timestamp = *rb->current_tick; do_late_init(); while(1) { static const struct button_mapping *plugin_contexts[] = { pla_main_ctx }; int button = pluginlib_getaction(0, plugin_contexts, ARRAYLEN(plugin_contexts)); switch(button) { case PLA_UP: case PLA_UP_REPEAT: camera_height+=MANUAL_SPEED; break; case PLA_DOWN: case PLA_DOWN_REPEAT: camera_height-=MANUAL_SPEED; break; case PLA_LEFT: case PLA_LEFT_REPEAT: camera.pos.x-=MANUAL_SPEED; break; case PLA_RIGHT: case PLA_RIGHT_REPEAT: camera.pos.x+=MANUAL_SPEED; break; case PLA_CANCEL: #ifdef HAVE_ADJUSTABLE_CPU_FREQ rb->cpu_boost(false); #endif return PLUGIN_OK; default: exit_on_usb(button); break; } camera.pos.z += 512; /* loop the track right before going off the "end" */ camera.pos.z %= (road_length - DRAW_DIST) * SEGMENT_LENGTH; render(&camera, road, road_length, camera_height); SET_FOREGROUND(LCD_WHITE); SET_BACKGROUND(LCD_BLACK); int dt = *rb->current_tick - last_timestamp; char buf[16]; //rb->snprintf(buf, sizeof(buf), "FPS: %ld", HZ/(!dt?1:dt)); rb->snprintf(buf, sizeof(buf), "DT: %d", dt); PUTSXY(0, 0, buf); LCD_UPDATE(); //rb->sleep((HZ/100)-dt); rb->yield(); last_timestamp = *rb->current_tick; } } /* plugin_start(): plugin entry point */ /* contains main loop */ enum plugin_status plugin_start(const void *param) { (void) param; do_early_init(); enum plugin_status rc = do_flythrough(); #ifdef HAVE_ADJUSTABLE_CPU_FREQ rb->cpu_boost(false); #endif return rc; }