├── .gitignore ├── .gitmodules ├── LICENSE ├── iconc.png ├── makefile ├── readme.md └── src ├── clouds.c ├── clouds.h ├── config.h ├── dino.c ├── dino.h ├── font ├── dino.fnt ├── font.c ├── font.h └── font.inc ├── gamestate.h ├── gfx ├── bird_0.png ├── bird_1.png ├── cactus_large_1.png ├── cactus_large_2.png ├── cactus_large_3.png ├── cactus_small_1.png ├── cactus_small_2.png ├── cactus_small_3.png ├── cloud_sprite.png ├── convimg.yaml ├── dino_dead.png ├── dino_duck_left.png ├── dino_duck_right.png ├── dino_left.png ├── dino_midair.png ├── dino_right.png ├── dino_stationary.png ├── dummy.png ├── horizon_0.png ├── horizon_1.png ├── horizon_2.png ├── horizon_3.png ├── horizon_4.png ├── moon_0.png ├── moon_1.png ├── moon_2.png ├── moon_3.png ├── moon_4.png ├── moon_5.png ├── moon_6.png ├── restart.png ├── spritemap.png ├── star_0.png ├── star_1.png └── star_2.png ├── graphics.c ├── graphics.h ├── lib ├── steam_controller.c └── steam_controller.h ├── main.c ├── night.c ├── night.h ├── obstacle.c ├── obstacle.h ├── physics.c ├── physics.h ├── score.c ├── score.h ├── sound.c ├── sound.h ├── sprites.c ├── sprites.h ├── usb.c ├── usb.h └── util.h /.gitignore: -------------------------------------------------------------------------------- 1 | src/gfx/*.c 2 | src/gfx/*.h 3 | src/gfx/convpng.log 4 | .idea/ 5 | bin/ 6 | cmake-build-debug/ 7 | /*.png 8 | !iconc.png 9 | obj/ 10 | orig.js 11 | dino_run.zip 12 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/hid"] 2 | path = src/hid 3 | url = https://github.com/commandblockguy/hiddrvce 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 John Cesarz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /iconc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/iconc.png -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # ---------------------------- 2 | # Set NAME to the program name 3 | # Set ICON to the png icon file name 4 | # Set DESCRIPTION to display within a compatible shell 5 | # Set COMPRESSED to "YES" to create a compressed program 6 | # ---------------------------- 7 | 8 | NAME = DINO 9 | COMPRESSED = YES 10 | ICON = iconc.png 11 | DESCRIPTION = "Dino Run CE" 12 | 13 | # ---------------------------- 14 | # Other Options (Advanced) 15 | # ---------------------------- 16 | 17 | GIT_COMMIT := $(shell git rev-parse --short HEAD) 18 | GIT_DIFF_STATUS := $(shell git diff-index --quiet HEAD; echo $$?) 19 | 20 | EXTRA_CFLAGS = -DCOMMIT=$(GIT_COMMIT) -DDIFF_STATUS=$(GIT_DIFF_STATUS) 21 | 22 | include $(shell cedev-config --makefile) 23 | 24 | $(OBJDIR)/font/font.src: $(SRCDIR)/font/font.inc 25 | 26 | $(SRCDIR)/font/font.inc: $(SRCDIR)/font/dino.fnt 27 | convfont -o carray -f $(SRCDIR)/font/dino.fnt $(SRCDIR)/font/font.inc 28 | 29 | clean_gfx: 30 | -rm src/gfx/convpng.log 31 | -rm src/gfx/*.c 32 | -rm src/gfx/*.h 33 | 34 | usb: 35 | make clean 36 | make EXTRA_CFLAGS=USE_USB=1 37 | 38 | no_usb: 39 | echo $(GIT_COMMIT) 40 | make clean 41 | make EXTRA_CFLAGS=USE_USB=0 42 | 43 | # Format a release for the Cemetech archives 44 | release: 45 | make clean 46 | make clean_gfx 47 | 48 | -rm -r dino_run 49 | mkdir dino_run 50 | cp readme.md dino_run 51 | markdown readme.md > dino_run/readme.html 52 | 53 | mkdir dino_run/source 54 | cp -r src iconc.png makefile dino_run/source 55 | 56 | make gfx 57 | make no_usb 58 | cp bin/DINO.8xp dino_run/DINO.8xp 59 | 60 | -rm dino_run.zip 61 | zip -r dino_run.zip dino_run 62 | rm -r dino_run 63 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Dinosaur Run CE 2 | 3 | A clone of Google Chrome's dinosaur game (from the no internet screen) for the TI-84 Plus CE graphing calculator. 4 | 5 | ![Preview](https://www.cemetech.net/media/archives/screenshots/2021/11/screenshot_111.png) 6 | 7 | ### Installation: 8 | Send DINO.8xp to the calculator using TI-Connect CE (for Windows and Mac) or TiLP (for Linux). 9 | Also send [the C libraries](https://github.com/CE-Programming/libraries/releases) to the calculator. 10 | To run, select DINO from the prgm menu and press enter. 11 | 12 | On older calculator OSes, you may need to open the catalog and select the Asm( token before running the program, so that the text `Asm(prgmDINO` is displayed. 13 | To avoid having to do this, either update your OS or use a shell such as [Cesium](https://github.com/mateoconlechuga/cesium/releases). 14 | 15 | On OS 5.5, you will need to use [arTIfiCE](https://yvantt.github.io/arTIfiCE/) to run native programs. 16 | 17 | I've made a [video tutorial](https://www.youtube.com/watch?v=_e8pgw9d7S4) for this process. 18 | 19 | ### Controls: 20 | UP to jump, DOWN to duck / fall, enter/2nd to restart, clear to exit. 21 | 22 | ### Building from source: 23 | The most up-to-date version of the source code may be found [on GitHub](https://github.com/commandblockguy/dino-run-ce). 24 | To build, you will need to install the [CE toolchain](https://github.com/CE-Programming/toolchain/releases). 25 | Run `make` in this directory to produce a binary in `bin/`. 26 | 27 | ### USB: 28 | Please note that USB support is still experimental and not recommended. 29 | To build with USB support, use `make usb` or set USE_USB to 1 in `config.h`. 30 | You will also need to send the [USB libraries](https://github.com/CE-Programming/toolchain/tree/usbdrvce). 31 | A (probably outdated) prebuilt version can be found [here](http://commandblockguy.xyz/downloads/usblibs.8xg). 32 | You will also need a USB Mini B OTG adapter to use most devices. 33 | Dino Run is compatible with HID boot devices (up/left click to jump, down/right click to jump) and the Steam controller (for rumble sounds). 34 | 35 | ### Contact: 36 | Questions / comments? 37 | 38 | * [Cemetech topic](https://www.cemetech.net/forum/viewtopic.php?p=283380) 39 | * Discord: [https://discord.gg/DZbmraw](https://discord.gg/DZbmraw) (commandblockguy#8263) 40 | * IRC: #cemetech on EFnet 41 | * Email: [commandblockguy1@gmail.com](mailto:commandblockguy1@gmail.com) 42 | * [GitHub issues](https://github.com/commandblockguy/dino-run-ce/issues) 43 | -------------------------------------------------------------------------------- /src/clouds.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "clouds.h" 3 | #include "config.h" 4 | #include "gamestate.h" 5 | 6 | void add_cloud(cloud_t *new) { 7 | new->x = new->last->x + new->last->gap; 8 | new->y = randInt(MIN_CLOUD_Y, MAX_CLOUD_Y); 9 | 10 | new->gap = randInt(MIN_CLOUD_GAP, MAX_CLOUD_GAP); 11 | } 12 | 13 | void update_clouds(void) { 14 | uint8_t i; 15 | uint8_t offset = 0; 16 | while(game.distance >= game.distance_to_cloud_movement) { 17 | offset++; 18 | game.distance_to_cloud_movement += CLOUD_PARALLAX_RATIO; 19 | } 20 | for(i = 0; i < NUM_CLOUDS; i++) { 21 | update_cloud(&game.clouds[i], offset); 22 | } 23 | } 24 | 25 | void update_cloud(cloud_t *cloud, uint8_t offset) { 26 | cloud->x -= offset; 27 | if(cloud->x + CLOUD_WIDTH < 0) { 28 | add_cloud(cloud); 29 | } 30 | } 31 | 32 | void init_clouds(void) { 33 | uint8_t i; 34 | 35 | /* Add the correct value of last to the first cloud */ 36 | game.clouds[0].last = &game.clouds[NUM_CLOUDS - 1]; 37 | add_cloud(&game.clouds[0]); 38 | 39 | for(i = 1; i < NUM_CLOUDS; i++) { 40 | game.clouds[i].last = &game.clouds[i - 1]; 41 | add_cloud(&game.clouds[i]); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/clouds.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_CLOUDS_H 2 | #define DINO_CLOUDS_H 3 | 4 | #include 5 | 6 | /* For each CLOUD_PARALLAX_RATIO pixels that the ground moves, the clouds move one pixel */ 7 | #define CLOUD_PARALLAX_RATIO 5 8 | 9 | #define NUM_CLOUDS 4 10 | #define MIN_CLOUD_GAP 100 11 | #define MAX_CLOUD_GAP 400 12 | #define MIN_CLOUD_Y (30 + TOP_Y) 13 | #define MAX_CLOUD_Y (71 + TOP_Y) 14 | #define CLOUD_WIDTH 46 15 | 16 | typedef struct Cloud { 17 | int24_t x; 18 | uint8_t y; 19 | uint24_t gap; 20 | const struct Cloud *last; 21 | } cloud_t; 22 | 23 | void add_cloud(cloud_t *new); 24 | 25 | void update_clouds(void); 26 | 27 | void update_cloud(cloud_t *cloud, uint8_t offset); 28 | 29 | void init_clouds(void); 30 | 31 | #endif //DINO_CLOUDS_H 32 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_CONFIG_H 2 | #define DINO_CONFIG_H 3 | 4 | #include 5 | 6 | #define GAME_HEIGHT 150 7 | #define TOP_Y ((LCD_HEIGHT - GAME_HEIGHT) / 2) 8 | #define BOTTOM_Y (GAME_HEIGHT + TOP_Y) 9 | #define GROUND_LEVEL (BOTTOM_Y - 12) 10 | 11 | #define FPS 60 12 | #define ONE_SECOND 32768 13 | #define FRAME_TIME (ONE_SECOND / FPS) 14 | 15 | #define TEXT_FADE_DELAY (ONE_SECOND * 2) 16 | #define TEXT_FADE_TIME (ONE_SECOND * 2) 17 | #define TEXT_FADE_FINAL_COLOR 128 18 | #define DO_FADE_TEXT 1 19 | 20 | #ifndef SHOW_FPS 21 | #define SHOW_FPS 0 22 | #endif 23 | #ifndef SHOW_BOXES 24 | #define SHOW_BOXES 0 25 | #endif 26 | #ifndef USE_CHEATS 27 | #define USE_CHEATS 0 28 | #endif 29 | 30 | #define GRAVITY 0.6 31 | #define INITIAL_JUMP_VELOCITY -10 32 | #define DROP_VELOCITY -5 33 | #define SPEED_DROP_COEFFICIENT 3 34 | #define MAX_JUMP_HEIGHT 63 35 | #define MIN_JUMP_HEIGHT 30 36 | 37 | #define INITIAL_SPEED 6 38 | #define ACCELERATION 0.001 39 | #define MAX_SPEED 13 40 | 41 | #define DINO_OFFSET_X 13 42 | 43 | #define SCORE_DIVISOR 40 44 | #define SCORE_DIGITS 5 45 | #define DISTANCE_METER_MAX 99999 46 | 47 | #define LETTERBOX 1 48 | 49 | #ifndef USE_USB 50 | #define USE_USB 0 51 | #endif 52 | #define MAX_HID_DEVICES 4 53 | 54 | #ifndef COMMIT 55 | #define COMMIT (N/A) 56 | #endif 57 | #ifndef DIFF_STATUS 58 | #define DIFF_STATUS 1 59 | #endif 60 | #ifndef VERSION 61 | #define VERSION 1.3 62 | #endif 63 | 64 | 65 | #endif //DINO_CONFIG_H 66 | -------------------------------------------------------------------------------- /src/dino.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dino.h" 3 | #include "util.h" 4 | #include "config.h" 5 | #include "gamestate.h" 6 | 7 | void dino_start_jump(void) { 8 | if(!game.dino.on_ground) return; 9 | if(game.dino.ducking) return; 10 | 11 | game.dino.velocity_y.combined = INT_TO_FIXED_POINT(INITIAL_JUMP_VELOCITY) - game.dino.velocity_x.combined / 10; 12 | game.dino.on_ground = false; 13 | 14 | #if USE_SOUND 15 | play_sound(&game.sound_player, &sounds[SOUND_JUMP]); 16 | #endif 17 | } 18 | 19 | void dino_end_jump(void) { 20 | if(game.dino.y.combined >= INT_TO_FIXED_POINT(GROUND_LEVEL - MIN_JUMP_HEIGHT) && !game.dino.dropping) return; 21 | if(game.dino.velocity_y.combined < INT_TO_FIXED_POINT(DROP_VELOCITY)) { 22 | game.dino.velocity_y.combined = INT_TO_FIXED_POINT(DROP_VELOCITY); 23 | } 24 | } 25 | 26 | void update_dino(void) { 27 | if(game.dino.velocity_x.combined < INT_TO_FIXED_POINT(MAX_SPEED)) { 28 | game.dino.velocity_x.combined += FLOAT_TO_FIXED_POINT(ACCELERATION); 29 | } 30 | 31 | if(game.dino.jumping) dino_start_jump(); 32 | if(!game.dino.jumping) dino_end_jump(); 33 | 34 | if(game.dino.y.combined <= INT_TO_FIXED_POINT(GROUND_LEVEL - MAX_JUMP_HEIGHT)) { 35 | dino_end_jump(); 36 | } 37 | 38 | if(game.dino.dropping) { 39 | dino_end_jump(); 40 | 41 | /* Make sure that we start dropping immediately */ 42 | if(game.dino.velocity_y.combined < INT_TO_FIXED_POINT(1)) 43 | game.dino.velocity_y.combined = INT_TO_FIXED_POINT(1); 44 | 45 | game.dino.y.combined += game.dino.velocity_y.combined * SPEED_DROP_COEFFICIENT; 46 | } else { 47 | game.dino.y.combined += game.dino.velocity_y.combined; 48 | } 49 | 50 | if(!game.dino.on_ground) { 51 | game.dino.velocity_y.combined += FLOAT_TO_FIXED_POINT(GRAVITY); 52 | } 53 | 54 | if(game.dino.y.combined > INT_TO_FIXED_POINT(GROUND_LEVEL)) { 55 | game.dino.y.combined = INT_TO_FIXED_POINT(GROUND_LEVEL); 56 | game.dino.velocity_y.combined = 0; 57 | game.dino.on_ground = true; 58 | } 59 | } -------------------------------------------------------------------------------- /src/dino.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_DINO_H 2 | #define DINO_DINO_H 3 | 4 | #include 5 | #include 6 | 7 | #include "util.h" 8 | 9 | typedef struct Dino { 10 | ufix_t y; 11 | ifix_t velocity_x; 12 | ifix_t velocity_y; 13 | bool alive; 14 | bool on_ground; 15 | bool ducking; 16 | bool dropping; 17 | bool jumping; 18 | } dino_t; 19 | 20 | #define DINO_HEIGHT 47 21 | #define DINO_WIDTH 44 22 | #define DINO_WIDTH_DUCK 59 23 | #define DINO_HEIGHT_DUCK 25 24 | 25 | /* Check if dino is on ground and if so start a jump */ 26 | void dino_start_jump(void); 27 | 28 | /* Stop jump and start falling if not doing so already */ 29 | void dino_end_jump(void); 30 | 31 | void update_dino(void); 32 | 33 | #endif //DINO_DINO_H 34 | -------------------------------------------------------------------------------- /src/font/dino.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/font/dino.fnt -------------------------------------------------------------------------------- /src/font/font.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "font.h" 5 | 6 | static const uint8_t font_data[] = { 7 | /* `make font` if font.inc does not exist */ 8 | #include "font.inc" 9 | }; 10 | 11 | const fontlib_font_t *font = (fontlib_font_t *)font_data; 12 | -------------------------------------------------------------------------------- /src/font/font.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_FONT_H 2 | #define DINO_FONT_H 3 | 4 | #include 5 | 6 | extern const fontlib_font_t *font; 7 | 8 | #endif //DINO_FONT_H 9 | -------------------------------------------------------------------------------- /src/font/font.inc: -------------------------------------------------------------------------------- 1 | 0x00, 0x0B, 0x37, 0x20, 0x12, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2 | 0x00, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 3 | 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 4 | 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 5 | 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0xB6, 0x00, 0xCC, 0x00, 0xE2, 0x00, 0xF8, 6 | 0x00, 0x0E, 0x01, 0x24, 0x01, 0x3A, 0x01, 0x50, 0x01, 0x66, 0x01, 0x7C, 0x01, 0x92, 0x01, 0xA8, 7 | 0x01, 0xBE, 0x01, 0xD4, 0x01, 0xEA, 0x01, 0x00, 0x02, 0x16, 0x02, 0x2C, 0x02, 0x42, 0x02, 0x58, 8 | 0x02, 0x6E, 0x02, 0x84, 0x02, 0x9A, 0x02, 0xB0, 0x02, 0xC6, 0x02, 0xDC, 0x02, 0xF2, 0x02, 0x08, 9 | 0x03, 0x1E, 0x03, 0x34, 0x03, 0x4A, 0x03, 0x60, 0x03, 0x76, 0x03, 0x8C, 0x03, 0xA2, 0x03, 0xB8, 10 | 0x03, 0xCE, 0x03, 0xE4, 0x03, 0xFA, 0x03, 0x10, 0x04, 0x26, 0x04, 0x3C, 0x04, 0x52, 0x04, 0x68, 11 | 0x04, 0x7E, 0x04, 0x94, 0x04, 0xAA, 0x04, 0xC0, 0x04, 0xD6, 0x04, 0xEC, 0x04, 0x02, 0x05, 0x18, 12 | 0x05, 0x2E, 0x05, 0x44, 0x05, 0x5A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 30 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 31 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x7F, 0x00, 0x67, 0x80, 0xE3, 0x80, 35 | 0xE3, 0x80, 0xE3, 0x80, 0xE3, 0x80, 0xF3, 0x00, 0x73, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x18, 0x00, 36 | 0x78, 0x00, 0x78, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 37 | 0xFF, 0x00, 0xFF, 0x00, 0x7F, 0x80, 0xFF, 0x80, 0xE3, 0x80, 0x07, 0x80, 0x3F, 0x00, 0x3F, 0x00, 38 | 0x7C, 0x00, 0xFC, 0x00, 0xF0, 0x80, 0xFF, 0x80, 0xFF, 0x80, 0x7F, 0x80, 0x7F, 0x00, 0x07, 0x00, 39 | 0x0C, 0x00, 0x3F, 0x00, 0x3F, 0x80, 0x03, 0x80, 0xE3, 0x80, 0xE3, 0x00, 0x7F, 0x00, 0x7F, 0x00, 40 | 0x0F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x77, 0x00, 0xF7, 0x00, 0xE7, 0x80, 0xFF, 0x80, 0xFF, 0x00, 41 | 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xC0, 0x00, 0xFF, 0x80, 0xFF, 0x80, 42 | 0x03, 0x80, 0x03, 0x80, 0xE3, 0x80, 0xE3, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x3F, 0x00, 0x7F, 0x00, 43 | 0x70, 0x00, 0xE0, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0xE3, 0x80, 0xE3, 0x80, 0xE3, 0x00, 0x7F, 0x00, 44 | 0x7F, 0x80, 0xFF, 0x80, 0xFF, 0x80, 0xE3, 0x00, 0x07, 0x00, 0x0F, 0x00, 0x0C, 0x00, 0x38, 0x00, 45 | 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x7C, 0x00, 0xFF, 0x00, 0xE3, 0x00, 0xF3, 0x00, 46 | 0xFF, 0x00, 0x7C, 0x80, 0x8F, 0x80, 0x8F, 0x80, 0x83, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x80, 47 | 0xFF, 0x80, 0xE3, 0x80, 0xE3, 0x80, 0xFF, 0x80, 0x7F, 0x80, 0x03, 0x80, 0x07, 0x00, 0x07, 0x00, 48 | 0x7C, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 58 | 0x1F, 0x80, 0x3B, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xE0, 0xFF, 0xE0, 0xE0, 0xE0, 59 | 0xE0, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xE0, 0xFF, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x80, 64 | 0xFF, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0xE0, 0xFF, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0xE0, 0x1F, 0xE0, 0x1F, 0x00, 0x38, 0x00, 0xE0, 0x00, 0xE0, 0xE0, 0xE3, 0xE0, 0xE0, 0xE0, 67 | 0xE0, 0xE0, 0x38, 0xE0, 0x1F, 0xE0, 0x1F, 0x80, 0xE3, 0x80, 0xE3, 0x80, 0xE3, 0x80, 0xE3, 0x80, 68 | 0xFF, 0x80, 0xFF, 0x80, 0xE3, 0x80, 0xE3, 0x80, 0xE3, 0x80, 0xE3, 0x80, 0xE3, 0x00, 0xFF, 0x00, 69 | 0xFF, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 70 | 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 71 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 72 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFB, 0xE0, 0xFF, 0xE0, 0xFF, 0xE0, 75 | 0xFF, 0xE0, 0xE4, 0xE0, 0xE4, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 | 0x00, 0x80, 0x3F, 0x80, 0x3F, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 78 | 0xE0, 0xE0, 0xE0, 0x80, 0x3F, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 79 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 80 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 81 | 0x00, 0x00, 0x00, 0x80, 0xFF, 0x80, 0xFF, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE3, 0x00, 82 | 0xFF, 0x00, 0xFF, 0x80, 0xE7, 0xE0, 0xE3, 0xE0, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 83 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 84 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 85 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 87 | 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFB, 0x80, 0x3F, 0x80, 0x3F, 0x00, 0x1F, 0x00, 0x04, 0x00, 88 | 0x04 -------------------------------------------------------------------------------- /src/gamestate.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_GAMESTATE_H 2 | #define DINO_GAMESTATE_H 3 | 4 | #include "dino.h" 5 | #include "clouds.h" 6 | #include "obstacle.h" 7 | #include "config.h" 8 | #include "night.h" 9 | #include "sound.h" 10 | #if USE_USB 11 | #include 12 | #include "hid/hid.h" 13 | #endif 14 | 15 | typedef struct Game { 16 | uint24_t frame; 17 | uint24_t distance; 18 | uint24_t score; 19 | uint24_t distance_to_score; 20 | uint24_t next_beep_score; 21 | bool distance_overrun; 22 | dino_t dino; 23 | cloud_t clouds[NUM_CLOUDS]; 24 | uint24_t distance_to_cloud_movement; 25 | obstacle_t obstacles[NUM_OBSTACLES]; 26 | uint24_t high_score; 27 | uint8_t day_stage; 28 | uint24_t distance_to_time_change; 29 | moon_t moon; 30 | star_t stars[MAX_NUM_STARS]; 31 | uint24_t star_movement_frame; 32 | #if USE_SOUND 33 | sound_player_t sound_player; 34 | #endif 35 | #if USE_USB 36 | struct { 37 | usb_device_t controller_dev; 38 | uint8_t controller_interface; 39 | hid_state_t hids[MAX_HID_DEVICES]; 40 | } usb; 41 | #endif 42 | } game_t; 43 | 44 | extern game_t game; 45 | 46 | #endif //DINO_GAMESTATE_H 47 | -------------------------------------------------------------------------------- /src/gfx/bird_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/bird_0.png -------------------------------------------------------------------------------- /src/gfx/bird_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/bird_1.png -------------------------------------------------------------------------------- /src/gfx/cactus_large_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/cactus_large_1.png -------------------------------------------------------------------------------- /src/gfx/cactus_large_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/cactus_large_2.png -------------------------------------------------------------------------------- /src/gfx/cactus_large_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/cactus_large_3.png -------------------------------------------------------------------------------- /src/gfx/cactus_small_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/cactus_small_1.png -------------------------------------------------------------------------------- /src/gfx/cactus_small_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/cactus_small_2.png -------------------------------------------------------------------------------- /src/gfx/cactus_small_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/cactus_small_3.png -------------------------------------------------------------------------------- /src/gfx/cloud_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/cloud_sprite.png -------------------------------------------------------------------------------- /src/gfx/convimg.yaml: -------------------------------------------------------------------------------- 1 | outputs: 2 | - type: c 3 | include-file: gfx.h 4 | palettes: 5 | - gfx_pal 6 | - night_pal 7 | converts: 8 | - images 9 | 10 | palettes: 11 | - name: gfx_pal 12 | fixed-entries: 13 | - color: {index: 0, r: 0, g: 0, b: 255} 14 | - color: {index: 1, r: 255, g: 255, b: 255} 15 | - color: {index: 2, r: 83, g: 83, b: 83} 16 | - color: {index: 3, r: 218, g: 218, b: 218} 17 | - color: {index: 4, r: 116, g: 116, b: 116} 18 | - color: {index: 5, r: 69, g: 69, b: 69} 19 | - color: {index: 6, r: 220, g: 25, b: 25} 20 | - color: {index: 7, r: 58, g: 181, b: 9} 21 | - color: {index: 8, r: 0, g: 0, b: 0} 22 | images: automatic 23 | 24 | - name: night_pal 25 | fixed-entries: 26 | - color: {index: 1, r: 0, g: 0, b: 0} 27 | - color: {index: 2, r: 173, g: 173, b: 173} 28 | - color: {index: 3, r: 37, g: 37, b: 37} 29 | - color: {index: 4, r: 139, g: 139, b: 139} 30 | 31 | converts: 32 | - name: images 33 | style: rlet 34 | transparent-color-index: 0 35 | palette: gfx_pal 36 | images: 37 | - bird_0.png 38 | - horizon_1.png 39 | - moon_5.png 40 | - bird_1.png 41 | - horizon_2.png 42 | - moon_6.png 43 | - cloud_sprite.png 44 | - horizon_3.png 45 | - restart.png 46 | - horizon_4.png 47 | - dino_duck_left.png 48 | - dino_duck_right.png 49 | - dino_left.png 50 | - dino_midair.png 51 | - dino_right.png 52 | - moon_0.png 53 | - star_0.png 54 | - dino_stationary.png 55 | - moon_1.png 56 | - star_1.png 57 | - dino_dead.png 58 | - moon_2.png 59 | - star_2.png 60 | - moon_3.png 61 | - horizon_0.png 62 | - moon_4.png 63 | - cactus_small_1.png 64 | - cactus_small_2.png 65 | - cactus_small_3.png 66 | - cactus_large_1.png 67 | - cactus_large_2.png 68 | - cactus_large_3.png 69 | -------------------------------------------------------------------------------- /src/gfx/dino_dead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/dino_dead.png -------------------------------------------------------------------------------- /src/gfx/dino_duck_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/dino_duck_left.png -------------------------------------------------------------------------------- /src/gfx/dino_duck_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/dino_duck_right.png -------------------------------------------------------------------------------- /src/gfx/dino_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/dino_left.png -------------------------------------------------------------------------------- /src/gfx/dino_midair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/dino_midair.png -------------------------------------------------------------------------------- /src/gfx/dino_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/dino_right.png -------------------------------------------------------------------------------- /src/gfx/dino_stationary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/dino_stationary.png -------------------------------------------------------------------------------- /src/gfx/dummy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/dummy.png -------------------------------------------------------------------------------- /src/gfx/horizon_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/horizon_0.png -------------------------------------------------------------------------------- /src/gfx/horizon_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/horizon_1.png -------------------------------------------------------------------------------- /src/gfx/horizon_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/horizon_2.png -------------------------------------------------------------------------------- /src/gfx/horizon_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/horizon_3.png -------------------------------------------------------------------------------- /src/gfx/horizon_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/horizon_4.png -------------------------------------------------------------------------------- /src/gfx/moon_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/moon_0.png -------------------------------------------------------------------------------- /src/gfx/moon_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/moon_1.png -------------------------------------------------------------------------------- /src/gfx/moon_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/moon_2.png -------------------------------------------------------------------------------- /src/gfx/moon_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/moon_3.png -------------------------------------------------------------------------------- /src/gfx/moon_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/moon_4.png -------------------------------------------------------------------------------- /src/gfx/moon_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/moon_5.png -------------------------------------------------------------------------------- /src/gfx/moon_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/moon_6.png -------------------------------------------------------------------------------- /src/gfx/restart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/restart.png -------------------------------------------------------------------------------- /src/gfx/spritemap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/spritemap.png -------------------------------------------------------------------------------- /src/gfx/star_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/star_0.png -------------------------------------------------------------------------------- /src/gfx/star_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/star_1.png -------------------------------------------------------------------------------- /src/gfx/star_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandblockguy/dino-run-ce/fb270ecd4034b42d66ff3270e39cb4c5e7dad5ca/src/gfx/star_2.png -------------------------------------------------------------------------------- /src/graphics.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "graphics.h" 8 | #include "gfx/gfx.h" 9 | #include "font/font.h" 10 | #include "sprites.h" 11 | #include "gamestate.h" 12 | #include "util.h" 13 | #include "clouds.h" 14 | #include "physics.h" 15 | 16 | void init_graphics(void) { 17 | gfx_Begin(); 18 | gfx_SetPalette(gfx_pal, sizeof_gfx_pal, 0); 19 | gfx_palette[WHITE] = 0xFFFF; 20 | gfx_FillScreen(BG_COLOR); 21 | 22 | fontlib_SetFont(font, 0); 23 | fontlib_SetWindowFullScreen(); 24 | 25 | #if LETTERBOX 26 | gfx_SetColor(BLACK); 27 | gfx_FillRectangle_NoClip(0, 0, LCD_WIDTH, TOP_Y); 28 | gfx_FillRectangle_NoClip(0, BOTTOM_Y, LCD_WIDTH, LCD_HEIGHT - BOTTOM_Y); 29 | gfx_SetDrawBuffer(); 30 | gfx_FillRectangle_NoClip(0, 0, LCD_WIDTH, TOP_Y); 31 | gfx_FillRectangle_NoClip(0, BOTTOM_Y, LCD_WIDTH, LCD_HEIGHT - BOTTOM_Y); 32 | #endif 33 | 34 | gfx_SetDrawBuffer(); 35 | } 36 | 37 | void draw(void) { 38 | uint8_t i; 39 | 40 | if(game.day_stage == DAWN) { 41 | invert_palette(true); 42 | } else if(game.day_stage == DUSK) { 43 | invert_palette(false); 44 | } 45 | 46 | gfx_SetColor(BG_COLOR); 47 | gfx_FillRectangle_NoClip(0, TOP_Y, LCD_WIDTH, BOTTOM_Y - TOP_Y ); 48 | 49 | draw_horizon(game.distance); 50 | 51 | if(game.day_stage != DAY) { 52 | if((gfx_palette[STAR_COLOR] & 0x1F) > (gfx_palette[BG_COLOR] & 0x1F)) { 53 | for(i = 0; i < MAX_NUM_STARS; i++) { 54 | draw_star(&game.stars[i]); 55 | } 56 | } 57 | 58 | if((gfx_palette[CLOUD_COLOR] & 0x1F) > (gfx_palette[BG_COLOR] & 0x1F)) 59 | draw_moon(); 60 | } 61 | 62 | for(i = 0; i < NUM_CLOUDS; i++) { 63 | draw_cloud(&game.clouds[i]); 64 | } 65 | 66 | for(i = 0; i < NUM_OBSTACLES; i++) { 67 | draw_obstacle(&game.obstacles[i]); 68 | } 69 | 70 | draw_dino(); 71 | 72 | draw_high_score(game.high_score); 73 | if(game.distance_overrun) { 74 | draw_distance_meter(0); 75 | } else { 76 | draw_distance_meter(game.score); 77 | } 78 | 79 | #if SHOW_FPS 80 | fps_counter(); 81 | #endif 82 | gfx_SwapDraw(); 83 | } 84 | 85 | void draw_horizon(uint24_t distance) { 86 | uint24_t total_offset = distance % (HORIZON_SEGMENT_WIDTH * NUM_HORIZONS); 87 | uint24_t segment_offset = total_offset % HORIZON_SEGMENT_WIDTH; 88 | 89 | uint8_t segment; 90 | int24_t x; 91 | uint8_t y; 92 | 93 | segment = total_offset / HORIZON_SEGMENT_WIDTH; 94 | x = -segment_offset; 95 | y = HORIZON_SPRITE_BASE - horizons[segment]->height; 96 | gfx_RLETSprite(horizons[segment], x, y); 97 | 98 | segment++; 99 | if(segment >= NUM_HORIZONS) segment = 0; 100 | x += HORIZON_SEGMENT_WIDTH; 101 | y = HORIZON_SPRITE_BASE - horizons[segment]->height; 102 | gfx_RLETSprite(horizons[segment], x, y); 103 | 104 | if(x + HORIZON_SEGMENT_WIDTH < LCD_WIDTH) { 105 | segment++; 106 | if(segment >= NUM_HORIZONS) segment = 0; 107 | x += HORIZON_SEGMENT_WIDTH; 108 | y = HORIZON_SPRITE_BASE - horizons[segment]->height; 109 | 110 | gfx_RLETSprite(horizons[segment], x, y); 111 | } 112 | } 113 | 114 | void draw_dino() { 115 | #if SHOW_BOXES 116 | uint8_t i; 117 | #endif 118 | gfx_rletsprite_t *sprite; 119 | uint8_t base_y = game.dino.y.parts.iPart; 120 | uint8_t y; 121 | uint24_t x = DINO_OFFSET_X; 122 | 123 | if(!game.dino.alive) { 124 | x = DINO_OFFSET_X + 2; 125 | sprite = dino_dead; 126 | base_y -= 2; 127 | } else if(!game.dino.on_ground) { 128 | sprite = dino_midair; 129 | } else if((game.frame & (2 * DINO_STEP_SPEED)) > DINO_STEP_SPEED) { 130 | /* Dino is on left foot */ 131 | sprite = game.dino.ducking ? dino_duck_left : dino_left; 132 | } else { 133 | /* Dino is on right foot */ 134 | sprite = game.dino.ducking ? dino_duck_right : dino_right; 135 | } 136 | 137 | y = base_y + 2 - sprite->height; 138 | gfx_RLETSprite_NoClip(sprite, x, y); 139 | 140 | #if SHOW_BOXES 141 | gfx_SetColor(DINO_BOX_COLOR); 142 | 143 | if(game.dino.ducking) { 144 | gfx_Rectangle(DINO_OFFSET_X + dino_box_ducking.x1, y + dino_box_ducking.y1, 145 | dino_box_ducking.x2 - dino_box_ducking.x1, 146 | dino_box_ducking.y2 - dino_box_ducking.y1); 147 | } else { 148 | for(i = 0; i < 5; i++) { 149 | const aabb_t *box = &dino_fine_boxes[i]; 150 | gfx_Rectangle(DINO_OFFSET_X + box->x1, y + box->y1, box->x2 - box->x1, box->y2 - box->y1); 151 | } 152 | } 153 | #endif 154 | } 155 | 156 | void draw_obstacle(const obstacle_t *obstacle) { 157 | #if SHOW_BOXES 158 | uint8_t i; 159 | #endif 160 | int24_t x; 161 | uint8_t y; 162 | gfx_rletsprite_t *sprite; 163 | 164 | x = obstacle->x - game.distance + DINO_OFFSET_X; 165 | 166 | if(x > LCD_WIDTH) return; 167 | 168 | y = obstacle->y; 169 | 170 | switch(obstacle->type) { 171 | case CACTUS_SMALL: 172 | sprite = small_cacti[obstacle->size - 1]; 173 | break; 174 | case CACTUS_LARGE: 175 | sprite = large_cacti[obstacle->size - 1]; 176 | break; 177 | case PTERODACTYL: 178 | if((game.frame & (2 * PTERODACTYL_FLAP_SPEED)) > PTERODACTYL_FLAP_SPEED) { 179 | sprite = bird_0; 180 | y += PTERODACTYL_0_Y_OFFSET; 181 | } 182 | else { 183 | sprite = bird_1; 184 | } 185 | break; 186 | default: 187 | return; 188 | } 189 | 190 | gfx_RLETSprite(sprite, x, y); 191 | 192 | #if SHOW_BOXES 193 | gfx_SetColor(OBSTACLE_BOX_COLOR); 194 | 195 | for(i = 0; i < obstacle_types[obstacle->type].num_boxes; i++) { 196 | const aabb_t *box = &obstacle_boxes[obstacle->type][i]; 197 | int j; 198 | for(j = 0; j < obstacle->size; j++) { 199 | gfx_Rectangle(x + j * obstacle_types[obstacle->type].width + box->x1, 200 | obstacle->y + box->y1, box->x2 - box->x1, 201 | box->y2 - box->y1); 202 | } 203 | } 204 | 205 | #endif 206 | } 207 | 208 | void draw_cloud(const cloud_t *cloud) { 209 | gfx_RLETSprite(cloud_sprite, cloud->x, cloud->y); 210 | } 211 | 212 | void draw_moon(void) { 213 | if(game.moon.phase == NUM_MOONS - 1) return; 214 | gfx_RLETSprite(moons[game.moon.phase], game.moon.x, MOON_Y); 215 | } 216 | 217 | void draw_star(const star_t *star) { 218 | gfx_RLETSprite(stars[star->type], star->x, star->y); 219 | } 220 | 221 | void draw_distance_meter(uint24_t score) { 222 | fontlib_SetCursorPosition(DISTANCE_METER_X, SCORE_TEXT_Y); 223 | fontlib_SetColors(FG_COLOR, BG_COLOR); 224 | fontlib_DrawUInt(score, SCORE_DIGITS); 225 | } 226 | 227 | void draw_high_score(uint24_t score) { 228 | fontlib_SetCursorPosition(HIGH_SCORE_X, SCORE_TEXT_Y); 229 | fontlib_SetColors(HS_COLOR, BG_COLOR); 230 | fontlib_DrawString("HI:"); 231 | fontlib_DrawUInt(score, SCORE_DIGITS); 232 | } 233 | 234 | void fps_counter(void) { 235 | gfx_SetColor(BLACK); 236 | gfx_FillRectangle_NoClip(0, 0, 25, 20); 237 | 238 | gfx_SetTextXY(0, 0); 239 | gfx_SetTextFGColor(WHITE); 240 | gfx_PrintInt(timer_1_Counter, 3); 241 | gfx_SetTextXY(0, 12); 242 | gfx_PrintInt(ONE_SECOND / (uint24_t) timer_1_Counter, 3); 243 | } 244 | 245 | void draw_game_over(void) { 246 | const char game_over_text[] = "GAMEOVER"; 247 | const char version_string[] = xstr(VERSION) "-" xstr(COMMIT) 248 | #if DIFF_STATUS 249 | "*" 250 | #endif 251 | #if USE_USB 252 | "U" 253 | #endif 254 | ; 255 | const uint24_t base_x = (LCD_WIDTH - GAME_OVER_TOTAL_WIDTH) / 2; 256 | uint8_t i; 257 | gfx_SetDrawScreen(); 258 | 259 | fontlib_SetColors(FG_COLOR, BG_COLOR); 260 | gfx_palette[FADE_TEXT] = 0x0000; 261 | 262 | for(i = 0; i < strlen(game_over_text); i++) { 263 | uint24_t x = base_x + (GAME_OVER_TEXT_WIDTH + GAME_OVER_TEXT_SPACING) * i; 264 | if(i >= 4) x += GAME_OVER_SPACE_WIDTH; 265 | fontlib_SetCursorPosition(x, GAME_OVER_TEXT_Y); 266 | fontlib_DrawGlyph(game_over_text[i]); 267 | } 268 | 269 | gfx_RLETSprite(restart, (LCD_WIDTH - restart_width) / 2, RESTART_BUTTON_Y); 270 | 271 | gfx_SetTextFGColor(FADE_TEXT); 272 | gfx_PrintStringXY("Dino Run CE by commandblockguy", 3, LCD_HEIGHT - 18); 273 | gfx_PrintStringXY(version_string, LCD_WIDTH - gfx_GetStringWidth(version_string) - 3, 2); 274 | 275 | gfx_SetDrawBuffer(); 276 | } 277 | 278 | void set_dynamic_palette(bool day) { 279 | uint8_t *palette; 280 | if(day) { 281 | palette = &gfx_pal[DYNAMIC_PALETTE_START * 2]; 282 | } else { 283 | palette = &night_pal[DYNAMIC_PALETTE_START * 2]; 284 | } 285 | gfx_SetPalette(palette, DYNAMIC_PALETTE_SIZE * 2, DYNAMIC_PALETTE_START); 286 | } 287 | 288 | void invert_palette(bool day) { 289 | uint8_t i; 290 | uint16_t *target_palette; 291 | 292 | if(day) { 293 | target_palette = (uint16_t*)gfx_pal; 294 | } else { 295 | target_palette = (uint16_t*)night_pal; 296 | } 297 | 298 | for(i = DYNAMIC_PALETTE_START; i < DYNAMIC_PALETTE_SIZE + DYNAMIC_PALETTE_START; i++) { 299 | uint16_t current = gfx_palette[i] & 0x1F; 300 | uint16_t target = target_palette[i] & 0x1F; 301 | uint8_t new; 302 | 303 | if(target < current) new = current - 1; 304 | else if(target > current) new = current + 1; 305 | else new = current; 306 | 307 | gfx_palette[i] = (new == 0x1F) << 15 | (new & 0x1F) << 10 | (new & 0x1F) << 5 | (new & 0x1F); 308 | } 309 | } 310 | -------------------------------------------------------------------------------- /src/graphics.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_GRAPHICS_H 2 | #define DINO_GRAPHICS_H 3 | 4 | #include "config.h" 5 | #include "dino.h" 6 | #include "gamestate.h" 7 | 8 | #define HORIZON_SPRITE_BASE (GROUND_LEVEL + 1) 9 | 10 | /* Number of frames between dino feet switches */ 11 | #define DINO_STEP_SPEED 5 12 | 13 | #define PTERODACTYL_FLAP_SPEED 10 14 | 15 | #define DISTANCE_METER_X 254 16 | #define HIGH_SCORE_X (DISTANCE_METER_X - 100) 17 | #define SCORE_TEXT_Y (TOP_Y + 10) 18 | 19 | #define GAME_OVER_TEXT_Y (TOP_Y + 42) 20 | #define GAME_OVER_TEXT_WIDTH 11 21 | #define GAME_OVER_TEXT_SPACING 13 22 | #define GAME_OVER_SPACE_WIDTH 10 23 | #define GAME_OVER_TOTAL_WIDTH 191 24 | #define RESTART_BUTTON_Y (TOP_Y + 75) 25 | 26 | #define MOON_Y (TOP_Y + 30) 27 | 28 | #define DYNAMIC_PALETTE_SIZE 4 29 | #define DYNAMIC_PALETTE_START 1 30 | 31 | enum { 32 | BG_COLOR = 1, 33 | FG_COLOR = 2, 34 | CLOUD_COLOR = 3, 35 | HS_COLOR = 4, 36 | STAR_COLOR = 5, 37 | OBSTACLE_BOX_COLOR = 6, 38 | DINO_BOX_COLOR = 7, 39 | BLACK = 8, 40 | WHITE = 9, 41 | FADE_TEXT = 10 42 | }; 43 | 44 | void init_graphics(void); 45 | 46 | void draw(void); 47 | 48 | void draw_horizon(uint24_t distance); 49 | 50 | void draw_dino(void); 51 | 52 | void draw_obstacle(const obstacle_t *obstacle); 53 | 54 | void draw_cloud(const cloud_t *cloud); 55 | 56 | void draw_moon(void); 57 | 58 | void draw_star(const star_t *star); 59 | 60 | void draw_distance_meter(uint24_t score); 61 | void draw_high_score(uint24_t score); 62 | 63 | void fps_counter(void); 64 | 65 | void draw_game_over(void); 66 | 67 | void set_dynamic_palette(bool day); 68 | 69 | void invert_palette(bool day); 70 | 71 | #endif //DINO_GRAPHICS_H 72 | -------------------------------------------------------------------------------- /src/lib/steam_controller.c: -------------------------------------------------------------------------------- 1 | #include "../config.h" 2 | #if USE_USB 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "steam_controller.h" 9 | 10 | #define VENDOR_STEAM 0x28DE 11 | #define DEVICE_WIRED 0x1102 12 | #define DEVICE_DONGLE 0x1142 13 | 14 | int8_t sc_GetInterface(usb_device_t dev) { 15 | usb_device_descriptor_t descriptor; 16 | usb_GetDescriptor(dev, USB_DEVICE_DESCRIPTOR, 0, 17 | &descriptor, sizeof(descriptor), NULL); 18 | if(descriptor.idVendor != VENDOR_STEAM) return -1; 19 | switch(descriptor.idProduct) { 20 | case DEVICE_WIRED: 21 | return 2; 22 | case DEVICE_DONGLE: 23 | return 1; 24 | default: 25 | return -1; 26 | } 27 | } 28 | 29 | struct DataPacket { 30 | uint8_t header; 31 | uint8_t request; 32 | sc_haptic_t haptic; 33 | uint16_t pulse_high; 34 | uint16_t pulse_low; 35 | uint16_t repeat_count; 36 | uint8_t padding[55]; 37 | }; 38 | 39 | usb_error_t tone_callback(usb_endpoint_t pEndpoint, 40 | usb_transfer_status_t status, 41 | size_t size, void *pVoid) { 42 | dbg_sprintf(dbgout, "callback called\n"); 43 | free(pVoid); 44 | return USB_SUCCESS; 45 | } 46 | 47 | const struct DataPacket sc_default_data = {0x8f, 0x08}; 48 | 49 | void sc_PlayTone(usb_device_t dev, uint8_t interface, 50 | sc_haptic_t haptic, uint16_t pulse_duration, 51 | uint16_t repeat_count) { 52 | struct DataPacket *data = malloc(sizeof(sc_default_data)); 53 | usb_control_setup_t setup = {0x21, 9, 0x300, 0, 64}; 54 | 55 | if(!dev) return; 56 | 57 | if(data) { 58 | dbg_sprintf(dbgout, "tone %u %u %u\n", haptic, pulse_duration, repeat_count); 59 | setup.wIndex = interface; 60 | memcpy(data, &sc_default_data, sizeof(sc_default_data)); 61 | data->haptic = haptic; 62 | data->pulse_high = data->pulse_low = pulse_duration; 63 | data->repeat_count = repeat_count; 64 | 65 | usb_ScheduleDefaultControlTransfer(dev, &setup, data, tone_callback, data); 66 | } else { 67 | dbg_sprintf(dbgout, "failed to alloc for PlayTone\n"); 68 | } 69 | } 70 | 71 | void sc_StopTone(usb_device_t dev, uint8_t interface, 72 | sc_haptic_t haptic) { 73 | struct DataPacket *data = malloc(sizeof(sc_default_data)); 74 | usb_control_setup_t setup = {0x21, 9, 0x300, 0, 64}; 75 | 76 | if(data) { 77 | setup.wIndex = interface; 78 | memcpy(data, &sc_default_data, sizeof(sc_default_data)); 79 | data->haptic = haptic; 80 | 81 | usb_ScheduleDefaultControlTransfer(dev, &setup, data, tone_callback, data); 82 | } else { 83 | dbg_sprintf(dbgout, "failed to alloc for StopTone\n"); 84 | } 85 | } 86 | 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /src/lib/steam_controller.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_STEAM_CONTROLLER_H 2 | #define DINO_STEAM_CONTROLLER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | enum { 9 | SC_HAPTIC_RIGHT, 10 | SC_HAPTIC_LEFT 11 | }; 12 | typedef bool sc_haptic_t; 13 | 14 | /** 15 | * Gets the interface number to use for controlling haptic feedback 16 | * @param dev USB device to check 17 | * @return Interface number, or -1 if not a steam controller 18 | */ 19 | int8_t sc_GetInterface(usb_device_t dev); 20 | 21 | /** 22 | * Plays a tone on the Steam controller 23 | * @param dev USB device 24 | * @param interface Interface from \c sc_GetInterface 25 | * @param haptic Which haptic feedback motor to use 26 | * @param pulse_duration Duration of each pulse. Use \c sc_FrequencyToDuration 27 | * @param repeat_count Number of times to repeat. Use \c sc_TimeToRepeatCount 28 | */ 29 | void sc_PlayTone(usb_device_t dev, uint8_t interface, 30 | sc_haptic_t haptic, uint16_t pulse_duration, 31 | uint16_t repeat_count); 32 | 33 | /** 34 | * Stops playing a tone on the Steam controller 35 | * @param dev USB device 36 | * @param interface Interface from \c sc_GetInterface 37 | * @param haptic Which haptic feedback motor to stop 38 | */ 39 | void sc_StopTone(usb_device_t dev, uint8_t interface, 40 | sc_haptic_t haptic); 41 | 42 | #define STEAM_CONTROLLER_MAGIC_PERIOD_RATIO 495483 43 | 44 | /** 45 | * Converts a frequency to a pulse duration 46 | * @param freq Frequency in hertz 47 | * @return Pulse duration for use with sc_PlayTone 48 | */ 49 | #define sc_FrequencyToDuration(freq) ((uint16_t)(STEAM_CONTROLLER_MAGIC_PERIOD_RATIO / freq)) 50 | 51 | /** 52 | * Converts a time and frequency to a repeat count 53 | * @param ms Time in milliseconds 54 | * @param freq Frequency in hertz 55 | * @return Repeat count for use with sc_PlayTone 56 | */ 57 | #define sc_TimeToRepeatCount(ms, freq) ((uint16_t)((ms * freq) / 1000)) 58 | 59 | 60 | #endif //DINO_STEAM_CONTROLLER_H 61 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "graphics.h" 12 | #include "gamestate.h" 13 | #include "util.h" 14 | #include "score.h" 15 | #include "night.h" 16 | #include "sound.h" 17 | 18 | #if USE_USB 19 | #include 20 | #include "usb.h" 21 | #include "lib/steam_controller.h" 22 | #include "hid/usb_hid_keys.h" 23 | #endif 24 | 25 | game_t game; 26 | 27 | void reset_timer(void) { 28 | timer_Control &= ~TIMER1_ENABLE; 29 | timer_1_Counter = 0; 30 | timer_1_MatchValue_1 = FRAME_TIME; 31 | timer_Control |= TIMER1_ENABLE; 32 | } 33 | 34 | bool play(void) { 35 | while(true) { 36 | uint8_t i; 37 | bool jump_pressed, duck_pressed; 38 | #if USE_USB 39 | usb_HandleEvents(); 40 | #endif 41 | #if USE_SOUND 42 | update_sound_player(&game.sound_player); 43 | #endif 44 | 45 | kb_Scan(); 46 | 47 | if(kb_IsDown(kb_KeyClear)) return false; 48 | 49 | #if USE_USB 50 | duck_pressed = kb_IsDown(kb_KeyDown) || 51 | any_hid_held(KEY_DOWN) || 52 | any_hid_mouse_held(HID_MOUSE_RIGHT); 53 | jump_pressed = kb_IsDown(kb_KeyUp) || 54 | any_hid_held(KEY_UP) || 55 | any_hid_held(KEY_SPACE) || 56 | any_hid_mouse_held(HID_MOUSE_LEFT); 57 | #else 58 | duck_pressed = kb_IsDown(kb_KeyDown) || kb_IsDown(kb_KeyAlpha); 59 | jump_pressed = kb_IsDown(kb_KeyUp) || kb_IsDown(kb_Key2nd); 60 | #endif 61 | 62 | game.dino.ducking = duck_pressed && game.dino.on_ground; 63 | game.dino.dropping = duck_pressed && !game.dino.on_ground; 64 | game.dino.jumping = jump_pressed; 65 | 66 | game.distance += game.dino.velocity_x.parts.iPart; 67 | if(game.distance > game.distance_to_score) { 68 | game.score++; 69 | game.distance_to_score += SCORE_DIVISOR; 70 | if(game.score > DISTANCE_METER_MAX) { 71 | game.distance_overrun = true; 72 | } 73 | } 74 | if(game.score >= game.next_beep_score) { 75 | game.next_beep_score += 100; 76 | #if USE_SOUND 77 | play_sound(&game.sound_player, &sounds[SOUND_ACHIEVEMENT]); 78 | #endif 79 | } 80 | 81 | update_dino(); 82 | 83 | update_obstacles(); 84 | 85 | update_clouds(); 86 | 87 | update_day_stage(); 88 | 89 | draw(); 90 | 91 | while(!(timer_IntStatus & TIMER1_MATCH1)) { 92 | timer_IntAcknowledge = TIMER1_MATCH1; 93 | kb_Scan(); 94 | if(kb_IsDown(kb_KeyClear)) break; 95 | #if USE_SOUND 96 | update_sound_player(&game.sound_player); 97 | #endif 98 | #if USE_USB 99 | usb_HandleEvents(); 100 | if(any_hid_held(KEY_ESC)) break; 101 | #endif 102 | } 103 | reset_timer(); 104 | 105 | game.frame++; 106 | 107 | if(!game.dino.alive) return true; 108 | } 109 | } 110 | 111 | bool game_over(void) { 112 | uint32_t initial_time = timer_1_Counter; 113 | draw_game_over(); 114 | #if USE_SOUND 115 | play_sound(&game.sound_player, &sounds[SOUND_DEATH]); 116 | #endif 117 | 118 | while(true) { 119 | #if DO_FADE_TEXT 120 | uint24_t capped_counter; 121 | if(timer_1_Counter - initial_time < TEXT_FADE_DELAY) { 122 | capped_counter = 0; 123 | } else if(timer_1_Counter - initial_time > TEXT_FADE_TIME - 1 + TEXT_FADE_DELAY) { 124 | capped_counter = TEXT_FADE_TIME - 1; 125 | } else { 126 | capped_counter = timer_1_Counter - initial_time - TEXT_FADE_DELAY; 127 | } 128 | 129 | /* Fade in the text */ 130 | gfx_palette[FADE_TEXT] = gfx_Darken(0xFFFF, capped_counter / (TEXT_FADE_TIME / TEXT_FADE_FINAL_COLOR)); 131 | #endif 132 | 133 | kb_Scan(); 134 | 135 | if(kb_IsDown(kb_KeyClear)) return true; 136 | if(kb_IsDown(kb_KeyEnter)) return false; 137 | if(kb_IsDown(kb_Key2nd)) return false; 138 | #if USE_SOUND 139 | update_sound_player(&game.sound_player); 140 | #endif 141 | #if USE_USB 142 | usb_HandleEvents(); 143 | if(any_hid_held(KEY_ESC)) return true; 144 | if(any_hid_held(KEY_ENTER)) return false; 145 | if(any_hid_mouse_held(HID_MOUSE_LEFT)) return false; 146 | #endif 147 | } 148 | } 149 | 150 | int main(void) { 151 | #if USE_USB 152 | start_usb(&game); 153 | #endif 154 | 155 | dbg_sprintf(dbgout, "Dino Run CE starting\n"); 156 | dbg_sprintf(dbgout, "Version %s\n", xstr(VERSION)); 157 | dbg_sprintf(dbgout, "Git commit %s, changed: %s\n", 158 | xstr(COMMIT), xstr(DIFF_STATUS)); 159 | dbg_sprintf(dbgout, "Built %s %s\n", __TIME__, __DATE__); 160 | 161 | timer_Control = TIMER1_ENABLE | TIMER1_32K | TIMER1_NOINT | TIMER1_UP | 162 | TIMER2_ENABLE | TIMER2_32K | TIMER2_NOINT | TIMER2_UP; 163 | 164 | init_graphics(); 165 | 166 | while(true) { 167 | bool quit; 168 | 169 | memset(&game, 0, sizeof(game) 170 | #if USE_USB 171 | - sizeof(game.usb) 172 | #endif 173 | ); 174 | reset_timer(); 175 | game.dino.alive = true; 176 | game.dino.on_ground = true; 177 | game.dino.y.combined = INT_TO_FIXED_POINT(GROUND_LEVEL); 178 | game.dino.velocity_x.combined = INT_TO_FIXED_POINT(INITIAL_SPEED); 179 | game.distance_to_score = SCORE_DIVISOR; 180 | game.high_score = get_score(); 181 | game.distance_to_time_change = NIGHT_CYCLE_INTERVAL; 182 | game.next_beep_score = 100; 183 | 184 | set_dynamic_palette(true); 185 | gfx_palette[FADE_TEXT] = 0; 186 | 187 | init_obstacles(); 188 | init_clouds(); 189 | #if USE_SOUND 190 | play_sound(&game.sound_player, &sounds[SOUND_JUMP]); 191 | #endif 192 | 193 | quit = !play(); 194 | set_score(game.score); 195 | if(quit) { 196 | /* Player pressed clear */ 197 | break; 198 | } else { 199 | /* Player died */ 200 | if(game_over()) break; 201 | } 202 | } 203 | 204 | exit: 205 | gfx_End(); 206 | 207 | #if USE_USB 208 | usb_Cleanup(); 209 | #endif 210 | return 0; 211 | } 212 | -------------------------------------------------------------------------------- /src/night.c: -------------------------------------------------------------------------------- 1 | #include "gamestate.h" 2 | #include "night.h" 3 | #include "sprites.h" 4 | 5 | void update_day_stage(void) { 6 | if(game.distance > game.distance_to_time_change) { 7 | game.day_stage++; 8 | if(game.day_stage >= NUM_DAY_STAGES) 9 | game.day_stage = DAY; 10 | 11 | switch(game.day_stage) { 12 | case DAY: 13 | game.distance_to_time_change += DAY_LENGTH; 14 | break; 15 | case DUSK: 16 | game.star_movement_frame = game.frame; 17 | game.moon.movement_frame = game.frame; 18 | game.moon.phase++; 19 | if(game.moon.phase > NUM_MOONS) game.moon.phase = 0; 20 | game.moon.x = LCD_WIDTH - 50; 21 | place_stars(); 22 | case DAWN: 23 | game.distance_to_time_change += INVERSION_DISTANCE; 24 | break; 25 | case NIGHT: 26 | game.distance_to_time_change += NIGHT_LENGTH; 27 | break; 28 | } 29 | } 30 | 31 | if(game.day_stage != DAY) { 32 | update_moon(); 33 | update_stars(); 34 | } 35 | } 36 | 37 | void update_stars(void) { 38 | uint8_t i, offset = 0; 39 | while(game.frame >= game.star_movement_frame) { 40 | offset++; 41 | game.star_movement_frame += STAR_SPEED_DIVISOR; 42 | } 43 | 44 | for(i = 0; i < MAX_NUM_STARS; i++) { 45 | update_star(&game.stars[i], offset); 46 | } 47 | } 48 | 49 | void update_star(star_t *star, uint8_t offset) { 50 | star->x -= offset; 51 | if(star->x + STAR_WIDTH < 0) 52 | star->x = LCD_WIDTH; 53 | } 54 | 55 | void update_moon(void) { 56 | uint8_t offset = 0; 57 | uint8_t width = MOON_WIDTH; 58 | while(game.frame >= game.moon.movement_frame) { 59 | offset++; 60 | game.moon.movement_frame += MOON_SPEED_DIVISOR; 61 | } 62 | game.moon.x -= offset; 63 | 64 | if(game.moon.phase == 3) width = 2 * MOON_WIDTH; 65 | if(game.moon.x + width < 0) 66 | game.moon.x = LCD_WIDTH; 67 | } 68 | 69 | void place_stars(void) { 70 | game.stars[0].x = randInt(0, LCD_WIDTH / 2); 71 | game.stars[0].y = randInt(TOP_Y, MAX_STAR_Y); 72 | 73 | game.stars[1].x = randInt(LCD_WIDTH / 2, LCD_WIDTH); 74 | game.stars[1].y = randInt(TOP_Y, MAX_STAR_Y); 75 | } 76 | -------------------------------------------------------------------------------- /src/night.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_NIGHT_H 2 | #define DINO_NIGHT_H 3 | 4 | #include 5 | 6 | enum { 7 | DAY, 8 | DUSK, 9 | NIGHT, 10 | DAWN, 11 | NUM_DAY_STAGES 12 | }; 13 | 14 | #define NIGHT_CYCLE_INTERVAL 28000 15 | #define INVERSION_FRAMES 32 16 | #define INVERSION_DISTANCE (INVERSION_FRAMES * MAX_SPEED) 17 | #define NIGHT_LENGTH (8000 - INVERSION_DISTANCE) 18 | #define DAY_LENGTH (20000 - INVERSION_DISTANCE) 19 | 20 | #define MOON_SPEED_DIVISOR 4 21 | #define STAR_SPEED_DIVISOR 3 22 | 23 | #define MAX_NUM_STARS 2 24 | 25 | #define STAR_WIDTH 9 26 | #define MOON_WIDTH 20 27 | 28 | #define MAX_STAR_Y (TOP_Y + 70) 29 | 30 | typedef struct { 31 | int24_t x; 32 | uint8_t y; 33 | uint8_t type; 34 | } star_t; 35 | 36 | typedef struct { 37 | uint8_t phase; 38 | int24_t x; 39 | uint24_t movement_frame; 40 | } moon_t; 41 | 42 | void update_day_stage(void); 43 | 44 | void update_moon(void); 45 | 46 | void update_stars(void); 47 | 48 | void update_star(star_t *star, uint8_t offset); 49 | 50 | void place_stars(void); 51 | 52 | #endif //DINO_NIGHT_H 53 | -------------------------------------------------------------------------------- /src/obstacle.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "obstacle.h" 5 | #include "config.h" 6 | #include "util.h" 7 | #include "physics.h" 8 | 9 | #if USE_USB 10 | #include "usb.h" 11 | #include "hid/usb_hid_keys.h" 12 | #endif 13 | 14 | static uint24_t get_gap(obstacle_t *obstacle); 15 | 16 | void add_obstacle(obstacle_t *new) { 17 | obstacle_type_index_t max_possible_type; 18 | const obstacle_type_data_t *type_data; 19 | 20 | if(game.dino.velocity_x.combined < FLOAT_TO_FIXED_POINT(PTERODACTYL_MIN_SPEED)) { 21 | max_possible_type = CACTUS_LARGE; 22 | } else { 23 | max_possible_type = PTERODACTYL; 24 | } 25 | 26 | new->type = randInt(0, max_possible_type); 27 | type_data = &obstacle_types[new->type]; 28 | 29 | if(game.dino.velocity_x.combined > type_data->multiple_speed.combined) { 30 | new->size = randInt(1, MAX_CACTI_LENGTH); 31 | } else { 32 | new->size = 1; 33 | } 34 | 35 | new->width = type_data->width * new->size; 36 | new->height = type_data->height; 37 | 38 | if(new->type == PTERODACTYL) { 39 | uint8_t heights[3] = {TOP_Y + 100, TOP_Y + 75, TOP_Y + 50}; 40 | new->y = heights[randInt(0,2)]; 41 | 42 | if(randInt(0,1)) { 43 | new->velocity.combined = FLOAT_TO_FIXED_POINT(PTERODACTYL_FLY_SPEED); 44 | } else { 45 | new->velocity.combined = FLOAT_TO_FIXED_POINT(-PTERODACTYL_FLY_SPEED); 46 | } 47 | } else { 48 | new->y = type_data->y; 49 | new->velocity.combined = 0; 50 | } 51 | 52 | new->x_offset.combined = 0; 53 | new->x = new->last->x + new->last->gap; 54 | 55 | new->gap = get_gap(new); 56 | } 57 | 58 | void update_obstacles(void) { 59 | uint8_t i; 60 | for(i = 0; i < NUM_OBSTACLES; i++) { 61 | update_obstacle(&game.obstacles[i]); 62 | 63 | if(check_collision(&game.obstacles[i])) { 64 | #if USE_CHEATS 65 | if(!kb_IsDown(kb_KeyGraph) 66 | #if USE_USB 67 | && !any_hid_held(KEY_F5) 68 | #endif 69 | ) 70 | #endif 71 | game.dino.alive = false; 72 | } 73 | } 74 | } 75 | 76 | void update_obstacle(obstacle_t *obstacle) { 77 | if(obstacle->x < game.distance - DINO_OFFSET_X + LCD_WIDTH) { 78 | obstacle->x_offset.combined += obstacle->velocity.combined; 79 | } 80 | 81 | if(obstacle->x_offset.parts.iPart) { 82 | obstacle->x += obstacle->x_offset.parts.iPart; 83 | obstacle->x_offset.parts.iPart = 0; 84 | } 85 | 86 | if((int24_t)(obstacle->x + obstacle->width) < (int24_t)(game.distance - DINO_OFFSET_X)) { 87 | add_obstacle(obstacle); 88 | } 89 | } 90 | 91 | void init_obstacles(void) { 92 | uint8_t i; 93 | const ifix_t dino_speed = {INT_TO_FIXED_POINT(INITIAL_SPEED)}; 94 | /* Initialize the first obstacle with the last obstacle */ 95 | game.obstacles[NUM_OBSTACLES - 1].gap = 1000; 96 | game.obstacles[0].last = &game.obstacles[NUM_OBSTACLES - 1]; 97 | add_obstacle(&game.obstacles[0]); 98 | 99 | for(i = 1; i < NUM_OBSTACLES; i++) { 100 | game.obstacles[i].last = &game.obstacles[i - 1]; 101 | add_obstacle(&game.obstacles[i]); 102 | } 103 | } 104 | 105 | static uint24_t get_gap(obstacle_t *obstacle) { 106 | uint24_t min_gap = obstacle->width * game.dino.velocity_x.parts.iPart 107 | + obstacle_types[obstacle->type].min_gap; 108 | uint24_t max_gap = min_gap * MAX_GAP_COEFFICIENT; 109 | 110 | return randInt(min_gap, max_gap) + obstacle->width; 111 | } 112 | 113 | const obstacle_type_data_t obstacle_types[NUM_OBSTACLE_TYPES] = { 114 | { 115 | 17, 116 | 35, 117 | TOP_Y + 105, 118 | INT_TO_FIXED_POINT(4), 119 | 72, 120 | 3 121 | }, 122 | { 123 | 25, 124 | 50, 125 | TOP_Y + 90, 126 | INT_TO_FIXED_POINT(7), 127 | 72, 128 | 3 129 | }, 130 | { 131 | 46, 132 | 27, 133 | 0, 134 | -1, 135 | 90, 136 | 5 137 | } 138 | }; 139 | -------------------------------------------------------------------------------- /src/obstacle.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_OBSTACLE_H 2 | #define DINO_OBSTACLE_H 3 | 4 | #include 5 | #include 6 | #include "util.h" 7 | #include "dino.h" 8 | 9 | /* The max number of cacti in one group */ 10 | #define MAX_CACTI_LENGTH 3 11 | 12 | #define NUM_OBSTACLES 3 13 | 14 | #define PTERODACTYL_MIN_SPEED 8.5 15 | #define PTERODACTYL_FLY_SPEED 0.8 16 | 17 | #define MAX_GAP_COEFFICIENT 3 / 2 18 | 19 | enum ObstacleTypeIndex { 20 | CACTUS_SMALL, 21 | CACTUS_LARGE, 22 | PTERODACTYL, 23 | NUM_OBSTACLE_TYPES 24 | }; 25 | typedef uint8_t obstacle_type_index_t; 26 | 27 | typedef struct ObstacleTypeData { 28 | uint8_t width; 29 | uint8_t height; 30 | uint8_t y; 31 | ufix_t multiple_speed; 32 | uint8_t min_gap; 33 | uint8_t num_boxes; 34 | } obstacle_type_data_t; 35 | 36 | extern const obstacle_type_data_t obstacle_types[NUM_OBSTACLE_TYPES]; 37 | 38 | typedef struct Obstacle { 39 | uint24_t x; 40 | uint8_t y; 41 | uint8_t height; 42 | uint8_t width; 43 | obstacle_type_index_t type; 44 | uint8_t size; 45 | ifix_t velocity; 46 | ifix_t x_offset; 47 | uint24_t gap; 48 | const struct Obstacle *last; 49 | } obstacle_t; 50 | 51 | /* Add a new obstacle at location new. */ 52 | /* last should be the obstacle furthest from the dino (last to be added) */ 53 | void add_obstacle(obstacle_t *new); 54 | 55 | void update_obstacles(void); 56 | 57 | void update_obstacle(obstacle_t *obstacle); 58 | 59 | void init_obstacles(void); 60 | 61 | #endif //DINO_OBSTACLE_H 62 | -------------------------------------------------------------------------------- /src/physics.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "obstacle.h" 4 | #include "physics.h" 5 | #include "clouds.h" 6 | #include "config.h" 7 | #include "util.h" 8 | #include "dino.h" 9 | 10 | /* Apologies to whoever has to read this. I tried to keep it contained to one function. */ 11 | bool check_collision(const obstacle_t *obstacle) { 12 | aabb_t obstacle_box = {1, 1, 0, 0}; 13 | uint8_t base_y = game.dino.y.parts.iPart - (game.dino.ducking ? DINO_HEIGHT_DUCK : DINO_HEIGHT); 14 | 15 | obstacle_box.x2 = obstacle->width - 1; 16 | obstacle_box.y2 = obstacle->height - 1; 17 | 18 | if(check_AABB_collision(game.dino.ducking ? &dino_box_ducking : &rough_dino_box, 19 | game.distance, base_y, &obstacle_box, obstacle->x, obstacle->y)) { 20 | uint8_t max_obstacle = obstacle_types[obstacle->type].num_boxes; 21 | uint8_t obstacle_num; 22 | for(obstacle_num = 0; obstacle_num < max_obstacle; obstacle_num++) { 23 | uint8_t j; 24 | for(j = 0; j < obstacle->size; j++) { 25 | if(game.dino.ducking) { 26 | if(check_AABB_collision(&dino_box_ducking, game.distance, base_y, 27 | &obstacle_boxes[obstacle->type][obstacle_num], 28 | obstacle->x + j * obstacle_types[obstacle->type].width, 29 | obstacle->y)) { 30 | return true; 31 | } 32 | } else { 33 | uint8_t dino_box; 34 | for(dino_box = 0; dino_box < 6; dino_box++) { 35 | if(check_AABB_collision(&dino_fine_boxes[dino_box], 36 | game.distance, base_y, 37 | &obstacle_boxes[obstacle->type][obstacle_num], 38 | obstacle->x + j * obstacle_types[obstacle->type].width, 39 | obstacle->y)) { 40 | return true; 41 | } 42 | } 43 | } 44 | } 45 | } 46 | } 47 | return false; 48 | } 49 | 50 | bool check_AABB_collision(const aabb_t *bb1, uint24_t x1, uint8_t y1, 51 | const aabb_t *bb2, uint24_t x2, uint8_t y2) { 52 | return bb1->x1 + x1 < bb2->x2 + x2 && 53 | bb1->x2 + x1 > bb2->x1 + x2 && 54 | bb1->y1 + y1 < bb2->y2 + y2 && 55 | bb1->y2 + y1 > bb2->y1 + y2; 56 | } 57 | 58 | const aabb_t obstacle_boxes[NUM_OBSTACLE_TYPES][5] = { 59 | { 60 | {0, 7, 5, 34}, 61 | {4, 0, 10, 34}, 62 | {10, 4, 17, 18} 63 | }, 64 | { 65 | {0, 12, 7, 50}, 66 | {8, 0, 15, 49}, 67 | {13, 10, 23, 48} 68 | }, 69 | { 70 | {15, 15, 31, 20}, 71 | {18, 21, 42, 27}, 72 | {2, 14, 6, 17}, 73 | {6, 10, 10, 17}, 74 | {10, 8, 16, 17} 75 | } 76 | }; 77 | 78 | const aabb_t dino_fine_boxes[6] = { 79 | {22, 0, 39, 16}, 80 | {1, 18, 31, 27}, 81 | {10, 35, 24, 43}, 82 | {1, 24, 30, 29}, 83 | {5, 30, 26, 34}, 84 | {9, 34, 24, 38} 85 | }; 86 | 87 | const aabb_t rough_dino_box = {1, 1, DINO_WIDTH - 1, DINO_HEIGHT - 1}; 88 | const aabb_t dino_box_ducking = {1, 1, DINO_WIDTH_DUCK - 1, DINO_HEIGHT_DUCK - 1}; 89 | -------------------------------------------------------------------------------- /src/physics.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_PHYSICS_H 2 | #define DINO_PHYSICS_H 3 | 4 | #include "gamestate.h" 5 | 6 | typedef struct AABB { 7 | uint24_t x1; 8 | uint8_t y1; 9 | uint24_t x2; 10 | uint8_t y2; 11 | } aabb_t; 12 | 13 | bool check_collision(const obstacle_t *obstacle); 14 | 15 | bool check_AABB_collision(const aabb_t *bb1, uint24_t x1, uint8_t y1, 16 | const aabb_t *bb2, uint24_t x2, uint8_t y2); 17 | 18 | extern const aabb_t obstacle_boxes[NUM_OBSTACLE_TYPES][5]; 19 | extern const aabb_t dino_fine_boxes[6]; 20 | extern const aabb_t rough_dino_box; 21 | extern const aabb_t dino_box_ducking; 22 | 23 | #endif //DINO_PHYSICS_H 24 | -------------------------------------------------------------------------------- /src/score.c: -------------------------------------------------------------------------------- 1 | #include "score.h" 2 | 3 | uint24_t get_score(void) { 4 | ti_var_t slot; 5 | uint24_t score; 6 | 7 | slot = ti_Open(SCORE_APPVAR_NAME, "r"); 8 | if(!slot) return 0; 9 | 10 | ti_Read(&score, sizeof(score), 1, slot); 11 | 12 | ti_Close(slot); 13 | if(score > 99999) return 99999; 14 | return score; 15 | } 16 | 17 | void set_score(uint24_t score) { 18 | ti_var_t slot; 19 | uint24_t old_score = get_score(); 20 | 21 | if(score > 99999) score = 99999; 22 | 23 | if(score <= old_score) return; 24 | 25 | slot = ti_Open(SCORE_APPVAR_NAME, "w"); 26 | if(!slot) return; 27 | 28 | ti_Write(&score, sizeof(score), 1, slot); 29 | 30 | ti_SetArchiveStatus(true, slot); 31 | ti_Close(slot); 32 | } 33 | -------------------------------------------------------------------------------- /src/score.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_SCORE_H 2 | #define DINO_SCORE_H 3 | 4 | #include 5 | #include 6 | 7 | #define SCORE_APPVAR_NAME "DinoHS" 8 | 9 | uint24_t get_score(void); 10 | void set_score(uint24_t score); 11 | 12 | #endif //DINO_SCORE_H 13 | -------------------------------------------------------------------------------- /src/sound.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sound.h" 3 | #include "gamestate.h" 4 | 5 | #if USE_SOUND 6 | #include "lib/steam_controller.h" 7 | 8 | void play_sound(sound_player_t *player, const sound_t *sound) { 9 | player->sound = sound; 10 | 11 | if(sound->num_tones > 1) { 12 | player->next_tone = 1; 13 | player->next_tone_time = (uint24_t)timer_2_Counter + 14 | sound->tones[1].time; 15 | dbg_sprintf(dbgout, "player %p\n", player); 16 | dbg_sprintf(dbgout, "more than one tone\n"); 17 | dbg_sprintf(dbgout, "time %u\n", sound->tones[1].time); 18 | } else { 19 | player->next_tone = 0; 20 | player->next_tone_time = 0; 21 | dbg_sprintf(dbgout, "only one tone\n"); 22 | } 23 | 24 | play_tone(&sound->tones[0]); 25 | } 26 | 27 | void update_sound_player(sound_player_t *player) { 28 | if(!player->next_tone || !player->next_tone_time) return; 29 | 30 | if((uint24_t)timer_2_Counter > player->next_tone_time) { 31 | uint24_t current_relative_time, new_relative_time; 32 | play_tone(&player->sound->tones[player->next_tone]); 33 | 34 | current_relative_time = player->sound->tones[player->next_tone].time; 35 | 36 | player->next_tone++; 37 | 38 | if(player->next_tone >= player->sound->num_tones) { 39 | player->sound = NULL; 40 | player->next_tone = 0; 41 | player->next_tone_time = 0; 42 | return; 43 | } 44 | 45 | new_relative_time = player->sound->tones[player->next_tone].time; 46 | player->next_tone_time += new_relative_time - current_relative_time; 47 | } 48 | } 49 | 50 | void play_tone(const tone_t *tone) { 51 | sc_PlayTone(game.usb.controller_dev, game.usb.controller_interface, 52 | SC_HAPTIC_RIGHT, tone->pulse_duration, tone->repeat_count); 53 | } 54 | 55 | const sound_t sounds[3] = { 56 | { 57 | 1, 58 | { 59 | { 60 | 0, 61 | sc_FrequencyToDuration(527), 62 | sc_TimeToRepeatCount(36, 527) 63 | } 64 | } 65 | }, 66 | { 67 | 2, 68 | { 69 | { 70 | 0, 71 | sc_FrequencyToDuration(67), 72 | 2 73 | }, 74 | { 75 | 68 * 32768 / 1000, 76 | sc_FrequencyToDuration(67), 77 | 5 78 | } 79 | } 80 | }, 81 | { 82 | 2, 83 | { 84 | { 85 | 0, 86 | sc_FrequencyToDuration(525), 87 | sc_TimeToRepeatCount(80, 525) 88 | }, 89 | { 90 | 90 * 32768 / 1000, 91 | sc_FrequencyToDuration(786), 92 | sc_TimeToRepeatCount(220,786) 93 | } 94 | } 95 | }, 96 | }; 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /src/sound.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_SOUND_H 2 | #define DINO_SOUND_H 3 | 4 | #include 5 | #include "config.h" 6 | 7 | #define MAX_TONES 2 8 | 9 | enum Sounds { 10 | SOUND_JUMP, 11 | SOUND_DEATH, 12 | SOUND_ACHIEVEMENT, 13 | }; 14 | 15 | typedef struct { 16 | uint24_t time; 17 | uint16_t pulse_duration; 18 | uint16_t repeat_count; 19 | } tone_t; 20 | 21 | typedef struct { 22 | uint8_t num_tones; 23 | tone_t tones[MAX_TONES]; 24 | } sound_t; 25 | 26 | typedef struct { 27 | sound_t *sound; 28 | uint8_t next_tone; 29 | uint24_t next_tone_time; 30 | } sound_player_t; 31 | 32 | #ifndef USE_SOUND 33 | #define USE_SOUND USE_USB 34 | #endif 35 | 36 | void play_sound(sound_player_t *player, const sound_t *sound); 37 | 38 | void update_sound_player(sound_player_t *player); 39 | 40 | void play_tone(const tone_t *tone); 41 | 42 | extern const sound_t sounds[3]; 43 | 44 | #endif //DINO_SOUND_H 45 | -------------------------------------------------------------------------------- /src/sprites.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "gfx/gfx.h" 4 | 5 | gfx_rletsprite_t *small_cacti[] = {cactus_small_1, cactus_small_2, cactus_small_3}; 6 | gfx_rletsprite_t *large_cacti[] = {cactus_large_1, cactus_large_2, cactus_large_3}; 7 | gfx_rletsprite_t *moons[] = {moon_0, moon_1, moon_2, moon_3, moon_4, moon_5, moon_6, NULL}; 8 | gfx_rletsprite_t *stars[] = {star_0, star_1, star_2}; 9 | gfx_rletsprite_t *horizons[] = {horizon_0, horizon_1, horizon_2, horizon_3, horizon_4}; 10 | -------------------------------------------------------------------------------- /src/sprites.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_SPRITES_H 2 | #define DINO_SPRITES_H 3 | 4 | #include 5 | #include "gfx/gfx.h" 6 | 7 | #define NUM_SMALL_CACTI 3 8 | #define NUM_LARGE_CACTI 3 9 | #define NUM_MOONS 8 10 | #define NUM_STARS 3 11 | #define NUM_HORIZONS 5 12 | 13 | #define HORIZON_SEGMENT_WIDTH horizon_0_width 14 | 15 | #define PTERODACTYL_0_Y_OFFSET 6 16 | 17 | extern gfx_rletsprite_t *small_cacti[NUM_SMALL_CACTI]; 18 | extern gfx_rletsprite_t *large_cacti[NUM_LARGE_CACTI]; 19 | extern gfx_rletsprite_t *moons[NUM_MOONS]; 20 | extern gfx_rletsprite_t *stars[NUM_STARS]; 21 | extern gfx_rletsprite_t *horizons[NUM_HORIZONS]; 22 | 23 | #endif //DINO_SPRITES_H 24 | -------------------------------------------------------------------------------- /src/usb.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "config.h" 3 | 4 | #if USE_USB 5 | #include "usb.h" 6 | #include "gamestate.h" 7 | #include "lib/steam_controller.h" 8 | #include "hid/hid.h" 9 | 10 | static usb_error_t handle_usb_event(usb_event_t event, void *event_data, 11 | usb_callback_data_t *callback_data); 12 | static hid_state_t *get_hid_slot(void); 13 | 14 | static usb_error_t handle_usb_event(usb_event_t event, void *event_data, 15 | usb_callback_data_t *callback_data) { 16 | switch(event) { 17 | case USB_DEVICE_CONNECTED_EVENT: { 18 | usb_device_t dev = event_data; 19 | hid_state_t *hid = get_hid_slot(); 20 | int8_t interface; 21 | dbg_sprintf(dbgout, "got device\n"); 22 | game.usb.controller_dev = dev; 23 | usb_ResetDevice(dev); 24 | usb_WaitForEvents(); 25 | interface = sc_GetInterface(dev); 26 | if(interface != -1) { 27 | uint8_t conf_desc[256]; 28 | size_t len; 29 | dbg_sprintf(dbgout, "got steam interface %u\n", interface); 30 | game.usb.controller_interface = interface; 31 | len = usb_GetConfigurationDescriptorTotalLength(dev, 0); 32 | usb_GetDescriptor(dev, USB_CONFIGURATION_DESCRIPTOR, 0, 33 | &conf_desc, 256, NULL); 34 | usb_SetConfiguration(dev, (usb_configuration_descriptor_t*)&conf_desc, len); 35 | } 36 | 37 | if(hid) { 38 | uint8_t i; 39 | union conf_desc { 40 | uint8_t bytes[256]; 41 | usb_configuration_descriptor_t conf; 42 | usb_descriptor_t desc; 43 | } conf_desc; 44 | 45 | size_t len; 46 | 47 | len = usb_GetConfigurationDescriptorTotalLength(dev, 0); 48 | usb_GetDescriptor(dev, USB_CONFIGURATION_DESCRIPTOR, 0, 49 | &conf_desc, 256, NULL); 50 | usb_SetConfiguration(dev, (usb_configuration_descriptor_t*)&conf_desc, len); 51 | 52 | for(i = 0; i < conf_desc.conf.bNumInterfaces; i++) { 53 | hid_error_t error; 54 | 55 | error = hid_Init(hid, dev, i); 56 | if(!error) { 57 | dbg_sprintf(dbgout, "got interface %u\n", i); 58 | hid_SetIdleTime(hid, 0); 59 | hid = get_hid_slot(); 60 | if(!hid) { 61 | dbg_sprintf(dbgout, "Ran out of HID slots\n"); 62 | return USB_SUCCESS; 63 | } 64 | } 65 | } 66 | } else { 67 | dbg_sprintf(dbgout, "No HID slots available\n"); 68 | return USB_IGNORE; 69 | } 70 | 71 | break; 72 | } 73 | case USB_DEVICE_DISCONNECTED_EVENT: { 74 | dbg_sprintf(dbgout, "device disconnected\n"); 75 | break; 76 | } 77 | default: 78 | break; 79 | } 80 | return USB_SUCCESS; 81 | } 82 | 83 | void start_usb(void) { 84 | dbg_sprintf(dbgout, "initting usb\n"); 85 | usb_Init(handle_usb_event, NULL, NULL, USB_DEFAULT_INIT_FLAGS); 86 | } 87 | 88 | static hid_state_t *get_hid_slot(void) { 89 | uint8_t i; 90 | for(i = 0; i < MAX_HID_DEVICES; i++) { 91 | if(!game.usb.hids[i].active) return &game.usb.hids[i]; 92 | } 93 | return NULL; 94 | } 95 | 96 | bool any_hid_held(uint8_t key_code) { 97 | uint8_t i; 98 | for(i = 0; i < MAX_HID_DEVICES; i++) { 99 | if(game.usb.hids[i].active) { 100 | if(hid_KbdIsKeyDown(&game.usb.hids[i], key_code)) return true; 101 | } 102 | } 103 | return false; 104 | } 105 | 106 | bool any_hid_mouse_held(uint8_t button) { 107 | uint8_t i; 108 | for(i = 0; i < MAX_HID_DEVICES; i++) { 109 | if(game.usb.hids[i].active) { 110 | if(hid_MouseIsButtonDown(&game.usb.hids[i], button)) return true; 111 | } 112 | } 113 | return false; 114 | } 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /src/usb.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_USB_H 2 | #define DINO_USB_H 3 | 4 | #include 5 | #include "gamestate.h" 6 | 7 | void start_usb(); 8 | 9 | bool any_hid_held(uint8_t key_code); 10 | bool any_hid_mouse_held(uint8_t button); 11 | 12 | #endif //DINO_USB_H 13 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | #ifndef DINO_UTIL_H 2 | #define DINO_UTIL_H 3 | 4 | #include 5 | 6 | typedef union { 7 | int24_t combined; 8 | struct { 9 | int16_t fPart; 10 | int8_t iPart; 11 | } parts; 12 | } ifix_t; 13 | 14 | typedef union { 15 | uint24_t combined; 16 | struct { 17 | uint16_t fPart; 18 | uint8_t iPart; 19 | } parts; 20 | } ufix_t; 21 | 22 | #define INT_TO_FIXED_POINT(i) ((i) << 16) 23 | #define FLOAT_TO_FIXED_POINT(i) (((i) * (1 << 16))) 24 | 25 | #define str(a) #a 26 | #define xstr(a) str(a) 27 | 28 | #endif //DINO_UTIL_H 29 | --------------------------------------------------------------------------------