├── src ├── gfx │ ├── convimg.out │ ├── convimg.yaml.lst │ ├── DUCKSPT.8xv │ ├── GAME │ │ ├── pause.png │ │ ├── bg_bush.png │ │ ├── bg_tree.png │ │ ├── bullet.png │ │ ├── c_ground.png │ │ ├── c_panel.png │ │ ├── fly_away.png │ │ ├── bg_ground.png │ │ ├── c_mountain.png │ │ ├── crosshair.png │ │ ├── kill_board.png │ │ ├── bullet_board.png │ │ ├── panel_icon_1.png │ │ ├── panel_icon_2.png │ │ ├── panel_icon_3.png │ │ ├── panel_icon_4.png │ │ ├── panel_icon_5.png │ │ └── score_board.png │ ├── DUCKS │ │ ├── Clay_1.png │ │ ├── Clay_2.png │ │ ├── Clay_3.png │ │ ├── Clay_4.png │ │ ├── Duck_A_1.png │ │ ├── Duck_A_2.png │ │ ├── Duck_A_3.png │ │ ├── Duck_B_1.png │ │ ├── Duck_B_2.png │ │ ├── Duck_B_3.png │ │ ├── Duck_Shot.png │ │ ├── Duckb_A_1.png │ │ ├── Duckb_A_2.png │ │ ├── Duckb_A_3.png │ │ ├── Duckb_B_1.png │ │ ├── Duckb_B_2.png │ │ ├── Duckb_B_3.png │ │ ├── Duckc_A_1.png │ │ ├── Duckc_A_2.png │ │ ├── Duckc_A_3.png │ │ ├── Duckc_B_1.png │ │ ├── Duckc_B_2.png │ │ ├── Duckc_B_3.png │ │ ├── Duck_Fall_1.png │ │ ├── Duck_Fall_2.png │ │ ├── Duckb_Fall_1.png │ │ ├── Duckb_Fall_2.png │ │ ├── Duckb_Shot.png │ │ ├── Duckc_Fall_1.png │ │ ├── Duckc_Fall_2.png │ │ ├── Duckc_Shot.png │ │ ├── Duck_Flyaway_1.png │ │ ├── Duck_Flyaway_2.png │ │ ├── Duck_Flyaway_3.png │ │ ├── Duckb_Flyaway_1.png │ │ ├── Duckb_Flyaway_2.png │ │ ├── Duckb_Flyaway_3.png │ │ ├── Duckc_Flyaway_1.png │ │ ├── Duckc_Flyaway_2.png │ │ └── Duckc_Flyaway_3.png │ ├── DOG │ │ ├── dog_bird_1.png │ │ ├── dog_bird_2.png │ │ ├── dog_jump_1.png │ │ ├── dog_jump_2.png │ │ ├── dog_laugh_1.png │ │ ├── dog_laugh_2.png │ │ ├── dog_walk_0.png │ │ ├── dog_walk_1.png │ │ ├── dog_walk_2.png │ │ ├── dog_walk_3.png │ │ ├── dog_walk_4.png │ │ ├── dog_walk_5.png │ │ └── dog_walk_6.png │ ├── MENU │ │ ├── Title_Menu.png │ │ ├── cr_symbol.png │ │ └── menu_arrow.png │ ├── DUCKSPT.c │ ├── convimg.yaml │ └── DUCKSPT.h ├── menu.h ├── save.h ├── utils.h ├── player.h ├── dog.h ├── utils.c ├── save.c ├── ducks.h ├── main.c ├── ui.h ├── menu.c ├── player.c ├── dog.c ├── ui.c └── ducks.c ├── icon.png ├── images ├── banner.png ├── CONCEPTS │ ├── menu.png │ ├── game_a.png │ ├── game_b.png │ └── game_c.png └── SCREENSHOTS │ ├── GAME A │ └── SHOWCASE_1.png │ ├── GAME B │ └── SHOWCASE_1.png │ └── GAME C │ └── SHOWCASE_1.png ├── docs ├── DUCKHUNT_MANUAL.pdf └── RELEASE_README.pdf ├── .gitignore ├── Makefile ├── LICENSE └── README.md /src/gfx/convimg.out: -------------------------------------------------------------------------------- 1 | DUCKSPT.h 2 | DUCKSPT.c 3 | DUCKSPT.8xv 4 | -------------------------------------------------------------------------------- /src/gfx/convimg.yaml.lst: -------------------------------------------------------------------------------- 1 | DUCKSPT.h 2 | DUCKSPT.c 3 | DUCKSPT.8xv 4 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/icon.png -------------------------------------------------------------------------------- /images/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/images/banner.png -------------------------------------------------------------------------------- /src/gfx/DUCKSPT.8xv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKSPT.8xv -------------------------------------------------------------------------------- /src/gfx/GAME/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/pause.png -------------------------------------------------------------------------------- /docs/DUCKHUNT_MANUAL.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/docs/DUCKHUNT_MANUAL.pdf -------------------------------------------------------------------------------- /docs/RELEASE_README.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/docs/RELEASE_README.pdf -------------------------------------------------------------------------------- /images/CONCEPTS/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/images/CONCEPTS/menu.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Clay_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Clay_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Clay_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Clay_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Clay_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Clay_3.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Clay_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Clay_4.png -------------------------------------------------------------------------------- /src/gfx/GAME/bg_bush.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/bg_bush.png -------------------------------------------------------------------------------- /src/gfx/GAME/bg_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/bg_tree.png -------------------------------------------------------------------------------- /src/gfx/GAME/bullet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/bullet.png -------------------------------------------------------------------------------- /src/gfx/GAME/c_ground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/c_ground.png -------------------------------------------------------------------------------- /src/gfx/GAME/c_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/c_panel.png -------------------------------------------------------------------------------- /src/gfx/GAME/fly_away.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/fly_away.png -------------------------------------------------------------------------------- /images/CONCEPTS/game_a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/images/CONCEPTS/game_a.png -------------------------------------------------------------------------------- /images/CONCEPTS/game_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/images/CONCEPTS/game_b.png -------------------------------------------------------------------------------- /images/CONCEPTS/game_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/images/CONCEPTS/game_c.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_bird_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_bird_1.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_bird_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_bird_2.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_jump_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_jump_1.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_jump_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_jump_2.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_laugh_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_laugh_1.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_laugh_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_laugh_2.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_walk_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_walk_0.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_walk_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_walk_1.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_walk_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_walk_2.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_walk_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_walk_3.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_walk_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_walk_4.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_walk_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_walk_5.png -------------------------------------------------------------------------------- /src/gfx/DOG/dog_walk_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DOG/dog_walk_6.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duck_A_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duck_A_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duck_A_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duck_A_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duck_A_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duck_A_3.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duck_B_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duck_B_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duck_B_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duck_B_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duck_B_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duck_B_3.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duck_Shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duck_Shot.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckb_A_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckb_A_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckb_A_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckb_A_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckb_A_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckb_A_3.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckb_B_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckb_B_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckb_B_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckb_B_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckb_B_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckb_B_3.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckc_A_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckc_A_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckc_A_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckc_A_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckc_A_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckc_A_3.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckc_B_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckc_B_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckc_B_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckc_B_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckc_B_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckc_B_3.png -------------------------------------------------------------------------------- /src/gfx/GAME/bg_ground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/bg_ground.png -------------------------------------------------------------------------------- /src/gfx/GAME/c_mountain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/c_mountain.png -------------------------------------------------------------------------------- /src/gfx/GAME/crosshair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/crosshair.png -------------------------------------------------------------------------------- /src/gfx/GAME/kill_board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/kill_board.png -------------------------------------------------------------------------------- /src/gfx/MENU/Title_Menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/MENU/Title_Menu.png -------------------------------------------------------------------------------- /src/gfx/MENU/cr_symbol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/MENU/cr_symbol.png -------------------------------------------------------------------------------- /src/gfx/MENU/menu_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/MENU/menu_arrow.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duck_Fall_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duck_Fall_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duck_Fall_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duck_Fall_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckb_Fall_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckb_Fall_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckb_Fall_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckb_Fall_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckb_Shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckb_Shot.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckc_Fall_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckc_Fall_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckc_Fall_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckc_Fall_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckc_Shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckc_Shot.png -------------------------------------------------------------------------------- /src/gfx/GAME/bullet_board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/bullet_board.png -------------------------------------------------------------------------------- /src/gfx/GAME/panel_icon_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/panel_icon_1.png -------------------------------------------------------------------------------- /src/gfx/GAME/panel_icon_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/panel_icon_2.png -------------------------------------------------------------------------------- /src/gfx/GAME/panel_icon_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/panel_icon_3.png -------------------------------------------------------------------------------- /src/gfx/GAME/panel_icon_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/panel_icon_4.png -------------------------------------------------------------------------------- /src/gfx/GAME/panel_icon_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/panel_icon_5.png -------------------------------------------------------------------------------- /src/gfx/GAME/score_board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/GAME/score_board.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duck_Flyaway_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duck_Flyaway_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duck_Flyaway_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duck_Flyaway_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duck_Flyaway_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duck_Flyaway_3.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckb_Flyaway_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckb_Flyaway_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckb_Flyaway_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckb_Flyaway_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckb_Flyaway_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckb_Flyaway_3.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckc_Flyaway_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckc_Flyaway_1.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckc_Flyaway_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckc_Flyaway_2.png -------------------------------------------------------------------------------- /src/gfx/DUCKS/Duckc_Flyaway_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/src/gfx/DUCKS/Duckc_Flyaway_3.png -------------------------------------------------------------------------------- /images/SCREENSHOTS/GAME A/SHOWCASE_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/images/SCREENSHOTS/GAME A/SHOWCASE_1.png -------------------------------------------------------------------------------- /images/SCREENSHOTS/GAME B/SHOWCASE_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/images/SCREENSHOTS/GAME B/SHOWCASE_1.png -------------------------------------------------------------------------------- /images/SCREENSHOTS/GAME C/SHOWCASE_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlvajoyAsante/DuckHunt/HEAD/images/SCREENSHOTS/GAME C/SHOWCASE_1.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # VS Code files 2 | *~ 3 | .vs/ 4 | .vscode/ 5 | 6 | # Build results 7 | [Dd]ebug/ 8 | [Dd]ebugPublic/ 9 | [Rr]elease/ 10 | [Bb]in/ 11 | [Oo]bj/ 12 | [Ll]og/ 13 | [Ll]ogs/ -------------------------------------------------------------------------------- /src/menu.h: -------------------------------------------------------------------------------- 1 | #ifndef MENU_H 2 | #define MENU_H 3 | 4 | #define COPYRIGHT_TEXT "1984 NINT ENDO CO., LT D." 5 | 6 | #include 7 | #include 8 | 9 | /* Main Menu information */ 10 | struct menu_t 11 | { 12 | // Menu Option 13 | int option; 14 | }; 15 | extern struct menu_t menu; 16 | 17 | /** 18 | * @brief Render Menu and get user input 19 | * 20 | * @return true: user want to play 21 | * @return false: user does not want to play 22 | */ 23 | bool init_menu(void); 24 | 25 | #endif -------------------------------------------------------------------------------- /src/save.h: -------------------------------------------------------------------------------- 1 | #ifndef SAVE_H 2 | #define SAVE_H 3 | 4 | #include 5 | #include 6 | 7 | #define SAVE_APPVAR_NAME "DCKSAVE" 8 | 9 | /** 10 | * @brief Saves game data to SAVE_APPVAR_NAME 11 | * 12 | */ 13 | void save_game(void); 14 | 15 | /** 16 | * @brief Loads game data from SAVE_APPVAR_NAME 17 | * 18 | * @return true the data from the SAVE_APPVAR_NAME was loaded 19 | * @return false the data from the SAVE_APPVAR_NAME wasn't loaded 20 | */ 21 | bool load_game(void); 22 | 23 | #endif -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # ---------------------------- 2 | # Program Options 3 | # ---------------------------- 4 | 5 | NAME ?= DUCKHUNT 6 | ICON ?= icon.png 7 | DESCRIPTION ?= "(c) 2021-2023, Alvajoy Asante" 8 | COMPRESSED ?= YES 9 | ARCHIVED ?= NO 10 | 11 | CFLAGS ?= -Wall -Wextra -Oz 12 | CXXFLAGS ?= -Wall -Wextra -Oz 13 | 14 | # ---------------------------- 15 | 16 | ifndef CEDEV 17 | $(error CEDEV environment path variable is not set) 18 | endif 19 | 20 | include $(CEDEV)/meta/makefile.mk 21 | 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Alvajoy Asante 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 | -------------------------------------------------------------------------------- /src/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_H 2 | #define UTILS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * @brief Renders a traditional rectangle from the game 10 | * 11 | * @param x X-Position 12 | * @param y Y-Position 13 | * @param w Width 14 | * @param h Height 15 | */ 16 | void ui_rectangle(int x, int y, int w, int h); 17 | 18 | /** 19 | * @brief This function returns the next position of a point based on the given start, end, and speed. 20 | * Note: This is used in recursion! 21 | * 22 | * @param start Starting position 23 | * @param end Ending Position 24 | * @param speed Speed of object 25 | * @return int next position 26 | */ 27 | int Goto_Pos(int start, int end, uint8_t speed); 28 | 29 | /** 30 | * @brief This function calculates the distance between two points. 31 | * 32 | * @param x1: The x-coordinate of the first point. 33 | * @param y1: The y-coordinate of the first point. 34 | * @param x2: The x-coordinate of the second point. 35 | * @param y2: The y-coordinate of the second point. 36 | * @return int: The distance between the two points. 37 | */ 38 | int get_distance(int x1, int y1, int x2, int y2); 39 | 40 | #endif -------------------------------------------------------------------------------- /src/player.h: -------------------------------------------------------------------------------- 1 | #ifndef PLAYER_H 2 | #define PLAYER_H 3 | 4 | #define TIMER_RECOIL_MAX 30 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* Player information */ 12 | struct player_t 13 | { 14 | // Player position 15 | int x; 16 | int y; 17 | 18 | // Player Overall Score 19 | int score; 20 | 21 | // Player Movement Speed 22 | int speed; 23 | 24 | // Player Bullet amount 25 | int bullets; 26 | 27 | // Player Level and round information 28 | int level; 29 | int round; 30 | 31 | // Player Rendering information 32 | gfx_sprite_t *back_buffer; 33 | uint8_t timer; 34 | }; 35 | extern struct player_t player; 36 | 37 | /** 38 | * @brief Checks for user keys 39 | * 40 | * @return true user does not want to exit 41 | * @return false user wants to exit 42 | */ 43 | bool player_keys(void); 44 | 45 | /** 46 | * @brief Renders player cursor 47 | * 48 | */ 49 | void draw_player(void); 50 | 51 | /** 52 | * @brief Get the player buffer layer object 53 | * 54 | */ 55 | void get_player_buffer_layer(void); 56 | 57 | /** 58 | * @brief Draw the player buffer layer object 59 | * 60 | */ 61 | void draw_player_buffer_layer(void); 62 | 63 | #endif -------------------------------------------------------------------------------- /src/dog.h: -------------------------------------------------------------------------------- 1 | #ifndef DOG_H 2 | #define DOG_H 3 | 4 | #include 5 | #include 6 | 7 | /* Dog modes */ 8 | enum DOG_ACTIONS 9 | { 10 | DOG_HIDDEN = 0, 11 | DOG_RUN_TO_CENTER = 1, 12 | DOG_PEEK_UP = 2, 13 | DOG_LAUGH = 3 14 | }; 15 | 16 | /* Dog infomation */ 17 | struct dog_t 18 | { 19 | // dog position 20 | int x; 21 | int y; 22 | 23 | // used for movement animations 24 | int gotoX; 25 | int gotoY; 26 | 27 | // speed of movement 28 | int speed; 29 | 30 | // animation mode 31 | int mode; 32 | 33 | // costume number 34 | int cnum; 35 | 36 | // tick 37 | int tick; 38 | 39 | // animation timer 40 | int animate; 41 | 42 | gfx_sprite_t *back_buffer; 43 | }; 44 | extern struct dog_t dog; 45 | 46 | /** 47 | * @brief Render the dog animation = 48 | * 49 | */ 50 | void dog_Render(void); 51 | 52 | /** 53 | * @brief Update the dog animation 54 | * 55 | */ 56 | void dog_Update(void); 57 | 58 | /** 59 | * @brief Sets the dog animation 60 | * 61 | * @param mode DogMode enum 62 | */ 63 | void dog_SetMode(uint8_t mode); 64 | 65 | /** 66 | * @brief Loops and draws dog scene base on set mode 67 | * 68 | */ 69 | void draw_dog_scene(void); 70 | 71 | /** 72 | * @brief Draw the dog buffer layer 73 | * 74 | */ 75 | void draw_dog_buffer_layer(void); 76 | 77 | /** 78 | * @brief Get the dog buffer layer 79 | * 80 | */ 81 | void get_dog_buffer_layer(void); 82 | 83 | #endif -------------------------------------------------------------------------------- /src/utils.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | void ui_rectangle(int x, int y, int w, int h) 4 | { 5 | gfx_SetColor(16); 6 | for (int i = 0; i < w; i++) 7 | { 8 | if (i == 0 || i == w - 1) 9 | { 10 | gfx_VertLine(x + i, y + 1, h - 2); 11 | } 12 | else 13 | gfx_VertLine(x + i, y, h); 14 | } 15 | 16 | gfx_SetColor(2); 17 | 18 | x++; 19 | y++; 20 | w -= 2; 21 | h -= 2; 22 | for (int i = 0; i < w; i++) 23 | { 24 | if (i == 0 || i == w - 1) 25 | { 26 | gfx_VertLine(x + i, y + 1, h - 2); 27 | } 28 | else 29 | gfx_VertLine(x + i, y, h); 30 | } 31 | } 32 | 33 | int Goto_Pos(int start, int end, uint8_t speed) 34 | { 35 | if (start == end) 36 | return start; 37 | 38 | /* Checks if the postion is speed distance */ 39 | if (start - end <= speed && start - end >= -(speed)) 40 | return end; 41 | 42 | /* Checks if the position is less than the destination position */ 43 | if (start < end) 44 | { 45 | start += speed; 46 | } 47 | else if (start > end) 48 | { 49 | start -= speed; 50 | } 51 | 52 | return start; 53 | } 54 | 55 | int get_distance(int x1, int y1, int x2, int y2) 56 | { 57 | // Use the Pythagorean theorem to calculate the distance. 58 | int dx = x2 - x1; 59 | int dy = y2 - y1; 60 | int distance = sqrt(dx * dx + dy * dy); 61 | 62 | return distance; 63 | } 64 | -------------------------------------------------------------------------------- /src/save.c: -------------------------------------------------------------------------------- 1 | #include "save.h" 2 | #include "ui.h" 3 | #include "player.h" 4 | 5 | /** 6 | * @brief initialize game settings 7 | * 8 | */ 9 | static void init_settings(void) 10 | { 11 | game.high_score = 12000; 12 | game.start = game.amount_fallen = game.fallen_id = game.enemies_amount = game.advance_amount = game.total_hits = 0; 13 | reset_hud_hits(); 14 | } 15 | 16 | void save_game(void) 17 | { 18 | uint8_t slot; 19 | 20 | /* is the current score less than high score then return */ 21 | if (player.score <= GAME_HIGH_SCORE) 22 | { 23 | return; 24 | } 25 | else 26 | { 27 | GAME_HIGH_SCORE = player.score; 28 | } 29 | 30 | /* Open appvar and save data */ 31 | slot = ti_Open(SAVE_APPVAR_NAME, "w"); 32 | ti_Write(&game, sizeof(struct game_t), 1, slot); 33 | ti_Close(slot); 34 | } 35 | 36 | bool load_game(void) 37 | { 38 | uint8_t slot; 39 | 40 | /* Check if file exist and load data */ 41 | if ((slot = ti_Open(SAVE_APPVAR_NAME, "r")) != 0) 42 | { 43 | if (ti_Read(&game, sizeof(struct game_t), 1, slot)) 44 | { 45 | /* Reset other data beside high-score */ 46 | game.start = game.amount_fallen = game.fallen_id = game.enemies_amount = game.advance_amount = game.total_hits = 0; 47 | } 48 | 49 | ti_Close(slot); 50 | 51 | return 1; 52 | } 53 | else 54 | { 55 | /* File does not exist */ 56 | init_settings(); 57 | } 58 | 59 | return 0; 60 | } -------------------------------------------------------------------------------- /src/ducks.h: -------------------------------------------------------------------------------- 1 | #ifndef DUCKS_H 2 | #define DUCKS_H 3 | 4 | #include 5 | #include 6 | 7 | /* Actions of the ducks */ 8 | enum DUCK_ACTIONS 9 | { 10 | DUCK_SHOT = 1, 11 | DUCK_FLYAWAY = 2, 12 | DUCK_FORCED_FLYAWAY = 3 13 | }; 14 | 15 | /* Enemies information */ 16 | struct enemies_t 17 | { 18 | // position of duck 19 | int x; 20 | int y; 21 | 22 | // is bird dead / alive or not active. 23 | bool active; 24 | bool shot; 25 | bool fly_away; 26 | 27 | // Determines the amount of points 28 | int points; 29 | 30 | // predetermined based on level 31 | int speed; 32 | 33 | // used for movement (animations) 34 | int gotoX; 35 | int gotoY; 36 | 37 | // custom number 38 | int cnum; 39 | 40 | // determines sprites angle 41 | int angle; 42 | 43 | // "mode" of enemies 44 | int type; 45 | 46 | // animation timer 47 | int animate; 48 | 49 | gfx_sprite_t *back_buffer; 50 | }; 51 | extern struct enemies_t enemies[2]; 52 | 53 | /** 54 | * @brief Renders enemies information 55 | * 56 | */ 57 | void draw_enemies(void); 58 | 59 | /** 60 | * @brief Updates enemies information 61 | * 62 | */ 63 | void update_enemies(void); 64 | 65 | /** 66 | * @brief Initialise enemies 67 | * 68 | * @param amount amount of enemies you want to Initialise 69 | */ 70 | void init_enemies(uint8_t amount); 71 | 72 | /** 73 | * @brief Draw the duck buffer layer 74 | * 75 | */ 76 | void draw_duck_buffer_layer(void); 77 | 78 | /** 79 | * @brief Get the duck buffer layer 80 | * 81 | */ 82 | void get_duck_buffer_layer(void); 83 | 84 | #endif -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------- 3 | * Program Name: DUCKHUNT 4 | * Author: Alvajoy 'Alvajoy123' Asante 5 | * License: GNU 3 6 | * Description: A NES clone of Duck Hunt 7 | *-------------------------------------- 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "ducks.h" 16 | #include "dog.h" 17 | #include "menu.h" 18 | #include "ui.h" 19 | #include "save.h" 20 | #include "player.h" 21 | #include "gfx/DUCKSPT.h" 22 | 23 | int main(void) 24 | { 25 | /* Seed Random */ 26 | srand(rtc_Time()); 27 | 28 | /* Check for the sprite appvar */ 29 | if (!DUCKSPT_init()) 30 | { 31 | os_ClrHome(); 32 | os_PutStrFull("Missing 'DUCKSPT' File!"); 33 | os_NewLine(); 34 | os_PutStrFull("Press any key to exit."); 35 | while (!os_GetCSC()) 36 | ; 37 | goto end; 38 | } 39 | 40 | /* Loading Game Data */ 41 | load_game(); 42 | 43 | /* Begin Canvas */ 44 | gfx_Begin(); 45 | 46 | /* Canvas Setup */ 47 | gfx_SetPalette(palette, sizeof_palette, 0); 48 | gfx_SetDrawBuffer(); 49 | gfx_SetTransparentColor(0); 50 | gfx_SetTextFGColor(2); // black 51 | 52 | menu: 53 | /* Render menu and check if user want to exit */ 54 | if (!init_menu()) 55 | goto end; 56 | 57 | /* Game play begins here */ 58 | draw_scene(); 59 | 60 | do 61 | { 62 | /* Grabbing Buffer Layer of the scene*/ 63 | get_buffer_layer(); 64 | 65 | /* Render layer */ 66 | draw_enemies(); 67 | draw_player(); 68 | 69 | // ################# 70 | 71 | gfx_Blit(1); 72 | 73 | // ################# 74 | 75 | /* Updating layer */ 76 | update_scene(); 77 | draw_buffer_layer(); 78 | update_enemies(); 79 | } while (player_keys()); 80 | 81 | delay(100); 82 | 83 | /* Saving Game Data */ 84 | save_game(); 85 | 86 | goto menu; 87 | 88 | end: 89 | gfx_End(); 90 | return 1; 91 | } -------------------------------------------------------------------------------- /src/gfx/DUCKSPT.c: -------------------------------------------------------------------------------- 1 | #include "DUCKSPT.h" 2 | #include 3 | 4 | #define DUCKSPT_HEADER_SIZE 0 5 | 6 | unsigned char *DUCKSPT_appvar[75] = 7 | { 8 | (unsigned char*)0, 9 | (unsigned char*)52, 10 | (unsigned char*)1774, 11 | (unsigned char*)4016, 12 | (unsigned char*)5698, 13 | (unsigned char*)6756, 14 | (unsigned char*)7918, 15 | (unsigned char*)9080, 16 | (unsigned char*)11282, 17 | (unsigned char*)13477, 18 | (unsigned char*)15599, 19 | (unsigned char*)17794, 20 | (unsigned char*)19996, 21 | (unsigned char*)22118, 22 | (unsigned char*)24664, 23 | (unsigned char*)25652, 24 | (unsigned char*)26640, 25 | (unsigned char*)27628, 26 | (unsigned char*)28622, 27 | (unsigned char*)29616, 28 | (unsigned char*)30610, 29 | (unsigned char*)31170, 30 | (unsigned char*)31730, 31 | (unsigned char*)32852, 32 | (unsigned char*)33974, 33 | (unsigned char*)35096, 34 | (unsigned char*)35997, 35 | (unsigned char*)36985, 36 | (unsigned char*)37973, 37 | (unsigned char*)38961, 38 | (unsigned char*)39955, 39 | (unsigned char*)40949, 40 | (unsigned char*)41943, 41 | (unsigned char*)42503, 42 | (unsigned char*)43063, 43 | (unsigned char*)44185, 44 | (unsigned char*)45307, 45 | (unsigned char*)46429, 46 | (unsigned char*)47330, 47 | (unsigned char*)48318, 48 | (unsigned char*)49306, 49 | (unsigned char*)50294, 50 | (unsigned char*)51288, 51 | (unsigned char*)52282, 52 | (unsigned char*)53276, 53 | (unsigned char*)53836, 54 | (unsigned char*)54396, 55 | (unsigned char*)55518, 56 | (unsigned char*)56640, 57 | (unsigned char*)57762, 58 | (unsigned char*)58663, 59 | (unsigned char*)58921, 60 | (unsigned char*)59179, 61 | (unsigned char*)59437, 62 | (unsigned char*)59695, 63 | (unsigned char*)59853, 64 | (unsigned char*)60661, 65 | (unsigned char*)61428, 66 | (unsigned char*)61451, 67 | (unsigned char*)61474, 68 | (unsigned char*)61489, 69 | (unsigned char*)61514, 70 | (unsigned char*)61534, 71 | (unsigned char*)61552, 72 | (unsigned char*)61611, 73 | (unsigned char*)62287, 74 | (unsigned char*)62655, 75 | (unsigned char*)62717, 76 | (unsigned char*)62793, 77 | (unsigned char*)62919, 78 | (unsigned char*)62983, 79 | (unsigned char*)63078, 80 | (unsigned char*)63171, 81 | (unsigned char*)63199, 82 | (unsigned char*)63235, 83 | }; 84 | 85 | unsigned char DUCKSPT_init(void) 86 | { 87 | unsigned int data, i; 88 | uint8_t appvar; 89 | 90 | appvar = ti_Open("DUCKSPT", "r"); 91 | if (appvar == 0) 92 | { 93 | return 0; 94 | } 95 | 96 | data = (unsigned int)ti_GetDataPtr(appvar) - (unsigned int)DUCKSPT_appvar[0] + DUCKSPT_HEADER_SIZE; 97 | for (i = 0; i < 75; i++) 98 | { 99 | DUCKSPT_appvar[i] += data; 100 | } 101 | 102 | ti_Close(appvar); 103 | 104 | return 1; 105 | } 106 | 107 | -------------------------------------------------------------------------------- /src/ui.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_H 2 | #define UI_H 3 | 4 | /* Version management */ 5 | #define DUCKHUNT_VERSION "PRE-ALPHA" 6 | 7 | /* Used to manage hidden development */ 8 | #define UNDER_DEVELOPMENT 1 9 | 10 | /* Manages the animation length */ 11 | #define TIMER_ANIMATE_MAX 4 12 | 13 | /* Canvas Information */ 14 | #define GAME_CANVAS_X_MIN 32 15 | #define GAME_CANVAS_X_MAX 287 16 | #define GAME_CANVAS_Y_MIN 8 17 | #define GAME_CANVAS_Y_MAX 230 18 | 19 | /* Game Information */ 20 | #define DUCK_FALLEN_AMOUNT game.amount_fallen 21 | #define DUCK_FALLEN_ID game.fallen_id 22 | #define DUCK_AMOUNT game.enemies_amount 23 | #define GAME_HIGH_SCORE game.high_score 24 | #define GAME_ADVANCE_THRESHOLD game.advance_amount 25 | #define GAME_TOTAL_HITS game.total_hits 26 | 27 | /* Fly Away Information */ 28 | #define DUCK_FLYAWAY_TIMER game.force_flyaway_timer 29 | #define DUCK_FLYAWAY_MAX 900 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | /* Game Information */ 36 | struct game_t 37 | { 38 | // Determines wether the game started 39 | bool start; 40 | 41 | // Amount of enemies fallen 42 | int amount_fallen; 43 | 44 | // Last fallen enemy array index 45 | int fallen_id; 46 | 47 | // Amount of enemies in game 48 | int enemies_amount; 49 | 50 | // Overall game high score 51 | int high_score; 52 | 53 | // amount of duck killed to advance to the next round 54 | int advance_amount; 55 | 56 | // Enemy hit tracker use HUD 57 | int duck_hits[10]; 58 | 59 | // total hit attempts 60 | int total_hits; 61 | 62 | // Duck Fly away timer 63 | int force_flyaway_timer; 64 | 65 | bool forced_flyaway; 66 | }; 67 | extern struct game_t game; 68 | 69 | /* Rendering Screen */ 70 | /** 71 | * @brief Initialise the Game based on menu option 72 | * 73 | */ 74 | void init_duckhunt(void); 75 | 76 | /** 77 | * @brief Update the data on the screen 78 | * 79 | */ 80 | void update_scene(void); 81 | 82 | /** 83 | * @brief Render the scene based on the menu option 84 | * 85 | */ 86 | void draw_scene(void); 87 | 88 | /* HUD Management */ 89 | /** 90 | * @brief Reset the duck hits on HUD 91 | * 92 | */ 93 | void reset_hud_hits(void); 94 | 95 | /** 96 | * @brief Gets the current position of the duck hits panel 97 | * 98 | * @return int amount in of true in boolean array game.duck_hits 99 | */ 100 | int get_hud_hits_position(void); 101 | 102 | /** 103 | * @brief Get the total shot ducks in hits hud 104 | * 105 | * @return int total 106 | */ 107 | int get_hud_hits_shot(void); 108 | 109 | /** 110 | * @brief Bubble sort the hits panel from smallest to greatest. 111 | * 112 | */ 113 | void bubble_sort_hits_panel(void); 114 | 115 | 116 | /* Buffer Layer Management */ 117 | /** 118 | * @brief Get the buffer layer of player, and enemies 119 | * 120 | */ 121 | void get_buffer_layer(void); 122 | 123 | /** 124 | * @brief Renders the buffer layers of player, and enemies 125 | * 126 | */ 127 | void draw_buffer_layer(void); 128 | 129 | #endif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DuckHunt 2 | 3 | 4 |
5 | 6 |
7 | 8 | 9 | > Duck Hunt is a classic game that has been enjoyed by generations of gamers. Now, you can experience the thrill of hunting ducks on your TI-84 Plus CE! 10 | 11 | ## Features 12 | 13 | * Multiple game modes, including 1 Duck Shooting, 2 Duck Shooting, and Clay Shooting 14 | 15 | * Bonus Duck types with various point amounts 16 | 17 | * Overall high-score 18 | 19 | * Compatible with TI-84 Plus CE calculators 20 | 21 | ## Installation 22 | 23 | * Download and install TI-Connect CE or TILP if you don't already have connectivity software. 24 | 25 | * Transfer to the calculator the latest C libraries to your calculator; you can find them at this link: 26 | https://github.com/CE-Programming/libraries/releases/latest 27 | 28 | * Transfer the 2 files from Github release: (DUCKHUNT, DUCKSPT) 29 | 30 | ## Run 31 | 32 | Run DuckHunt from the homescreen by pressing `[prgm]` and selecting `DUCKHUNT`, 33 | Your screen should look like this (press Enter when it does): 34 | 35 | prgmDUCKHUNT 36 | 37 | Note: If your OS is 5.5 or higher, use the arTIfiCE exploit tool to run the program: https://yvantt.github.io/arTIfiCE/. 38 | 39 | ## How to Play 40 | 41 | 42 |

Unable to display PDF file. Download instead.

43 |
44 | 45 | 46 | ## Controls 47 | 48 | [←→↓↑] - Move cursor 49 | [2nd] - Shoot bullet 50 | [mode] - Pause game 51 | [del] - Quit to homescreen 52 | 53 | 54 | ## Concepts Images 55 | 56 | ![](./images/CONCEPTS/menu.png) ![](./images/CONCEPTS/game_a.png) 57 | 58 | ![](./images/CONCEPTS/game_b.png) ![](./images/CONCEPTS/game_c.png) 59 | 60 | ## Development 61 | Current State: 62 | 63 | | GAME A | GAME B | GAME C | 64 | | ------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------- | 65 | | ![](./images/SCREENSHOTS/GAME%20A/SHOWCASE_1.png) | ![](./images/SCREENSHOTS/GAME%20B/SHOWCASE_1.png) | ![](./images/SCREENSHOTS/GAME%20C/SHOWCASE_1.png) | 66 | 67 | 68 | > *Keep up to date on the recent development by checking out the [New Discord Server](https://discord.gg/xyUZgnD4UJ "New Discord Server") or on [Cemetech Forums](https://www.cemetech.net/forum/viewtopic.php?t=15070 "Cemetech Forums"). You can also view the [Trello Board](https://trello.com/b/NkkezsJu/duckhunt-development-c) For more information about the development.* 69 | 70 | ## Credit 71 | 72 | * DuckHunt was written from scratch based off of NES Duck Hunt mechanics. 73 | 74 | * Images/Sprites are copyright of Nintendo. 75 | 76 | * DuckHunt is an independent game that is not affiliated with Nintendo. It is a humble attempt to recreate a classic and beloved game. 77 | 78 | ------------ 79 | 80 | Copyright © 2021 - 2023, ***Alvajoy Asante*** 81 | -------------------------------------------------------------------------------- /src/menu.c: -------------------------------------------------------------------------------- 1 | #include "menu.h" 2 | #include "ui.h" 3 | #include "gfx/DUCKSPT.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | struct menu_t menu; 10 | 11 | bool init_menu(void) 12 | { 13 | gfx_sprite_t *temp_sprite; 14 | sk_key_t key; 15 | 16 | /* Setting up menu GUI */ 17 | gfx_FillScreen(2); // Black 18 | 19 | menu.option = 1; 20 | 21 | /* Render Game Title */ 22 | temp_sprite = gfx_MallocSprite(Title_Menu_width, Title_Menu_height); 23 | zx7_Decompress(temp_sprite, Title_Menu_compressed); 24 | gfx_TransparentSprite(temp_sprite, 86, 32); 25 | free(temp_sprite); 26 | 27 | /* Render Game Modes */ 28 | gfx_SetTextFGColor(6); // Orange 29 | gfx_SetTextXY(89, 133); 30 | gfx_PrintString("GAME A 1 DUCK"); 31 | gfx_SetTextXY(89, 149); 32 | gfx_PrintString("GAME B 2 DUCK"); 33 | 34 | #if UNDER_DEVELOPMENT 35 | gfx_SetTextXY(89, 164); 36 | gfx_PrintString("GAME C LOCKED!"); 37 | #else 38 | gfx_SetTextXY(89, 164); 39 | gfx_PrintString("GAME C CLAY SHOOTING"); 40 | #endif 41 | 42 | /* Render Highscore */ 43 | gfx_SetTextFGColor(16); // Green 44 | gfx_SetTextXY(85, 190); 45 | gfx_PrintString("TOP SCORE = "); 46 | gfx_PrintInt(game.high_score, 5); 47 | 48 | /* Render Nintendo Copyright */ 49 | temp_sprite = gfx_MallocSprite(cr_symbol_width, cr_symbol_height); 50 | zx7_Decompress(temp_sprite, cr_symbol_compressed); 51 | gfx_TransparentSprite(temp_sprite, (LCD_WIDTH - (gfx_GetStringWidth(COPYRIGHT_TEXT) + cr_symbol_width)) / 2, 213); 52 | free(temp_sprite); 53 | 54 | gfx_SetTextScale(1, 1); 55 | gfx_SetTextFGColor(1); // White 56 | gfx_SetTextXY((LCD_WIDTH - (gfx_GetStringWidth(COPYRIGHT_TEXT) - (cr_symbol_width + 4))) / 2, 214); 57 | gfx_PrintString(COPYRIGHT_TEXT); 58 | 59 | /* Render Version Number */ 60 | gfx_SetTextScale(1, 1); 61 | gfx_SetTextFGColor(1); // White 62 | gfx_SetTextXY((LCD_WIDTH - gfx_GetStringWidth(DUCKHUNT_VERSION)) / 2, 228); 63 | gfx_PrintString(DUCKHUNT_VERSION); 64 | 65 | /* Decompress Cursor */ 66 | temp_sprite = gfx_MallocSprite(menu_arrow_width, menu_arrow_height); 67 | zx7_Decompress(temp_sprite, menu_arrow_compressed); 68 | 69 | /* Loop to manage user input */ 70 | while (1) 71 | { 72 | /* Clear cursor position */ 73 | gfx_SetColor(2); // black 74 | gfx_FillRectangle(60, 130, 14, 43); 75 | 76 | /* Scan and manage keys */ 77 | kb_Scan(); 78 | key = kb_Data[7]; 79 | 80 | switch (key) 81 | { 82 | case kb_Up: 83 | if (menu.option > 1) 84 | { 85 | menu.option--; 86 | } 87 | 88 | delay(65); 89 | break; 90 | 91 | case kb_Down: 92 | #if UNDER_DEVELOPMENT 93 | if (menu.option < 2) 94 | #else 95 | if (menu.option < 3) 96 | #endif 97 | { 98 | menu.option++; 99 | } 100 | 101 | delay(65); 102 | break; 103 | } 104 | 105 | /* Check if [2nd], [Enter] was clicked */ 106 | if (kb_Data[1] == kb_2nd || kb_Data[6] == kb_Enter) 107 | break; 108 | 109 | /* Check if user wants to exit */ 110 | if (kb_Data[1] == kb_Del) 111 | { 112 | free(temp_sprite); 113 | delay(60); 114 | 115 | /* Return false if user does not want to play */ 116 | return false; 117 | } 118 | 119 | /* Render arrow sprite based on menu position */ 120 | switch (menu.option) 121 | { 122 | case 1: 123 | gfx_TransparentSprite(temp_sprite, 61, 131); 124 | break; 125 | 126 | case 2: 127 | gfx_TransparentSprite(temp_sprite, 61, 145); 128 | break; 129 | 130 | case 3: 131 | gfx_TransparentSprite(temp_sprite, 61, 161); 132 | break; 133 | } 134 | 135 | // ################ 136 | 137 | gfx_Blit(1); 138 | 139 | // ############### 140 | } 141 | 142 | /* Free the temp sprite used for rendering */ 143 | free(temp_sprite); 144 | 145 | /* Start the game based on menu option */ 146 | init_duckhunt(); 147 | 148 | /* Return true if use want to play*/ 149 | return true; 150 | } 151 | -------------------------------------------------------------------------------- /src/gfx/convimg.yaml: -------------------------------------------------------------------------------- 1 | palettes: 2 | - name: palette 3 | fixed-entries: 4 | # Default Colors 5 | - color: { index: 0, r: 255, g: 0, b: 128 } # Transparent color 6 | - color: { index: 1, r: 255, g: 255, b: 255 } # White 7 | - color: { index: 2, r: 0, g: 0, b: 0 } # Black 8 | # Cloud colors 9 | - color: { index: 3, r: 99, g: 173, b: 255 } 10 | - color: { index: 4, r: 255, g: 204, b: 197 } 11 | - color: { index: 5, r: 74, g: 206, b: 222 } 12 | # Ground color 13 | - color: { index: 6, r: 255, g: 95, b: 0 } 14 | - color: { index: 7, r: 173, g: 173, b: 173 } 15 | images: automatic 16 | 17 | converts: 18 | - name: dog 19 | palette: palette 20 | transparent-color-index: 0 21 | images: 22 | - DOG/dog_bird_1.png 23 | - DOG/dog_bird_2.png 24 | - DOG/dog_jump_1.png 25 | - DOG/dog_jump_2.png 26 | - DOG/dog_laugh_1.png 27 | - DOG/dog_laugh_2.png 28 | - DOG/dog_walk_0.png 29 | - DOG/dog_walk_1.png 30 | - DOG/dog_walk_2.png 31 | - DOG/dog_walk_3.png 32 | - DOG/dog_walk_4.png 33 | - DOG/dog_walk_5.png 34 | - DOG/dog_walk_6.png 35 | 36 | - name: ducks 37 | palette: palette 38 | transparent-color-index: 0 39 | images: 40 | # Duck a 41 | - DUCKS/Duck_A_1.png 42 | - DUCKS/Duck_A_2.png 43 | - DUCKS/Duck_A_3.png 44 | - DUCKS/Duck_B_1.png 45 | - DUCKS/Duck_B_2.png 46 | - DUCKS/Duck_B_3.png 47 | - DUCKS/Duck_Fall_1.png 48 | - DUCKS/Duck_Fall_2.png 49 | - DUCKS/Duck_Flyaway_1.png 50 | - DUCKS/Duck_Flyaway_2.png 51 | - DUCKS/Duck_Flyaway_3.png 52 | - DUCKS/Duck_Shot.png 53 | # Duck b 54 | - DUCKS/Duckb_A_1.png 55 | - DUCKS/Duckb_A_2.png 56 | - DUCKS/Duckb_A_3.png 57 | - DUCKS/Duckb_B_1.png 58 | - DUCKS/Duckb_B_2.png 59 | - DUCKS/Duckb_B_3.png 60 | - DUCKS/Duckb_Fall_1.png 61 | - DUCKS/Duckb_Fall_2.png 62 | - DUCKS/Duckb_Flyaway_1.png 63 | - DUCKS/Duckb_Flyaway_2.png 64 | - DUCKS/Duckb_Flyaway_3.png 65 | - DUCKS/Duckb_Shot.png 66 | # Duck c 67 | - DUCKS/Duckc_A_1.png 68 | - DUCKS/Duckc_A_2.png 69 | - DUCKS/Duckc_A_3.png 70 | - DUCKS/Duckc_B_1.png 71 | - DUCKS/Duckc_B_2.png 72 | - DUCKS/Duckc_B_3.png 73 | - DUCKS/Duckc_Fall_1.png 74 | - DUCKS/Duckc_Fall_2.png 75 | - DUCKS/Duckc_Flyaway_1.png 76 | - DUCKS/Duckc_Flyaway_2.png 77 | - DUCKS/Duckc_Flyaway_3.png 78 | - DUCKS/Duckc_Shot.png 79 | # Clay 80 | - DUCKS/Clay_1.png 81 | - DUCKS/Clay_2.png 82 | - DUCKS/Clay_3.png 83 | - DUCKS/Clay_4.png 84 | 85 | - name: game 86 | palette: palette 87 | compress: zx7 88 | transparent-color-index: 0 89 | images: 90 | - GAME/bg_bush.png 91 | - GAME/bg_ground.png 92 | - GAME/bg_tree.png 93 | - GAME/panel_icon_1.png 94 | - GAME/panel_icon_2.png 95 | - GAME/panel_icon_3.png 96 | - GAME/panel_icon_4.png 97 | - GAME/panel_icon_5.png 98 | - GAME/bullet.png 99 | - GAME/bullet_board.png 100 | - GAME/c_ground.png 101 | - GAME/c_mountain.png 102 | - GAME/c_panel.png 103 | - GAME/crosshair.png 104 | - GAME/fly_away.png 105 | - GAME/kill_board.png 106 | - GAME/pause.png 107 | - GAME/score_board.png 108 | 109 | - name: menu 110 | palette: palette 111 | compress: zx7 112 | transparent-color-index: 0 113 | images: 114 | - MENU/cr_symbol.png 115 | - MENU/menu_arrow.png 116 | - MENU/Title_Menu.png 117 | 118 | outputs: 119 | - type: appvar 120 | name: DUCKSPT 121 | include-file: DUCKSPT.h 122 | source-format: c 123 | palettes: 124 | - palette 125 | converts: 126 | - dog 127 | - ducks 128 | - game 129 | - menu 130 | -------------------------------------------------------------------------------- /src/player.c: -------------------------------------------------------------------------------- 1 | #include "player.h" 2 | #include "ui.h" 3 | #include "ducks.h" 4 | #include "dog.h" 5 | #include "menu.h" 6 | #include "gfx/DUCKSPT.h" 7 | 8 | struct player_t player; 9 | 10 | /** 11 | * @brief Render reward if duck shot 12 | * 13 | * @param enemy_id index of enemy shot 14 | * @return int reward of duck 15 | */ 16 | static int returnReward(int enemy_id) 17 | { 18 | int level; 19 | int rewards[][5] = { 20 | {500, 800, 1000, 1000, 1000}, // Duck A 21 | {1000, 1600, 2000, 2000, 2000}, // Duck B 22 | {1500, 2400, 3000, 3000, 3000}, // Duck C 23 | {10000, 10000, 15000, 20000, 30000}, // Clay 24 | }; 25 | 26 | /* Set level index */ 27 | if (player.round >= 1 && player.round <= 5) 28 | { 29 | level = 0; 30 | } 31 | else if (player.round >= 6 && player.round <= 10) 32 | { 33 | level = 1; 34 | } 35 | else if (player.round >= 11 && player.round <= 15) 36 | { 37 | level = 2; 38 | } 39 | else if (player.round >= 16 && player.round <= 20) 40 | { 41 | level = 3; 42 | } 43 | else 44 | { 45 | level = 4; 46 | } 47 | 48 | /* Return the reward */ 49 | return rewards[(enemies[enemy_id].type) - 1][level]; 50 | } 51 | 52 | /** 53 | * @brief Renders shoot and checks if enemies have been shot 54 | * 55 | */ 56 | static void shoot(void) 57 | { 58 | gfx_sprite_t *back_buffer; 59 | 60 | /* Return can't shoot just yet! */ 61 | if (DUCK_FLYAWAY_TIMER == DUCK_FLYAWAY_MAX) 62 | return; 63 | 64 | /* Check if there is bullets to shoot */ 65 | if (player.bullets != 0) 66 | { 67 | player.bullets--; 68 | } 69 | else 70 | { 71 | return; 72 | } 73 | 74 | /* Check if ducks overlaps cursor */ 75 | for (int i = 0; i < DUCK_AMOUNT; i++) 76 | { 77 | 78 | if (enemies[i].active && !enemies[i].shot) 79 | { 80 | /* Reset the shooting timer */ 81 | player.timer = 0; 82 | 83 | if (enemies[i].x < (player.x - 5) + 10 && enemies[i].x + 33 > player.x - 5) 84 | { 85 | if (enemies[i].y < (player.y - 5) + 10 && enemies[i].y + 23 > player.y - 5) 86 | { 87 | 88 | /* Prime the duck for shooting */ 89 | enemies[i].angle = 0; 90 | enemies[i].shot = true; 91 | 92 | if (menu.option < 3) 93 | { 94 | // Game A and B 95 | enemies[i].gotoY = 140; 96 | enemies[i].gotoX = enemies[i].x; 97 | enemies[i].speed = 4; 98 | enemies[i].cnum = 7; // costume shot 99 | enemies[i].animate = 0; 100 | } 101 | else 102 | { 103 | // Game C 104 | } 105 | 106 | /* Determine Score */ 107 | player.score += returnReward(i); 108 | 109 | /* Register Hit duck */ 110 | game.duck_hits[get_hud_hits_position()] = 1; 111 | 112 | DUCK_FALLEN_AMOUNT++; 113 | GAME_TOTAL_HITS++; 114 | } 115 | } 116 | } 117 | } 118 | 119 | /* Render the white shot rectangle */ 120 | back_buffer = gfx_MallocSprite(20, 20); 121 | gfx_GetSprite(back_buffer, player.x - 10, player.y - 10); 122 | 123 | gfx_SetColor(1); 124 | gfx_FillRectangle(player.x - 10, player.y - 10, 20, 20); 125 | 126 | gfx_Blit(1); 127 | 128 | delay(50); 129 | 130 | gfx_Sprite(back_buffer, player.x - 10, player.y - 10); 131 | 132 | free(back_buffer); 133 | 134 | /* Reset Fly Away timer */ 135 | DUCK_FLYAWAY_TIMER = 0; 136 | } 137 | 138 | bool player_keys(void) 139 | { 140 | kb_key_t key = kb_Data[7]; 141 | 142 | kb_Scan(); 143 | 144 | /* Updates the player timer for shooting recoil */ 145 | if (player.timer < TIMER_RECOIL_MAX) 146 | player.timer++; 147 | 148 | /* Check for exit */ 149 | if (kb_Data[1] == kb_Del) 150 | return 0; 151 | 152 | /* if there is nothing in dog.mode then user can mover the cursor. */ 153 | if (kb_Data[1] == kb_2nd) 154 | { 155 | if (player.timer == TIMER_RECOIL_MAX) 156 | { 157 | shoot(); 158 | } 159 | return 1; 160 | } 161 | 162 | switch (key) 163 | { 164 | case kb_Up: 165 | if (player.y - player.speed >= 16) 166 | { 167 | player.y -= player.speed; 168 | } 169 | else 170 | { 171 | player.y = 16; 172 | } 173 | break; 174 | 175 | case kb_Down: 176 | if (player.y + player.speed <= 155) 177 | { 178 | player.y += player.speed; 179 | } 180 | else 181 | { 182 | player.y = 155; 183 | } 184 | break; 185 | 186 | case kb_Left: 187 | if (player.x - player.speed >= 40) 188 | { 189 | player.x -= player.speed; 190 | } 191 | else 192 | { 193 | player.x = 40; 194 | } 195 | break; 196 | 197 | case kb_Right: 198 | if (player.x + player.speed <= 279) 199 | { 200 | player.x += player.speed; 201 | } 202 | else 203 | { 204 | player.x = 279; 205 | } 206 | break; 207 | } 208 | 209 | if (kb_IsDown(kb_KeyUp) && kb_IsDown(kb_KeyRight)) 210 | { 211 | if (player.y - player.speed >= 16) 212 | { 213 | player.y -= player.speed; 214 | } 215 | else 216 | player.y = 16; 217 | 218 | if (player.x + player.speed <= 279) 219 | { 220 | player.x += player.speed; 221 | } 222 | else 223 | player.x = 279; 224 | 225 | return 1; 226 | } 227 | 228 | if (kb_IsDown(kb_KeyUp) && kb_IsDown(kb_KeyLeft)) 229 | { 230 | if (player.y - player.speed >= 16) 231 | { 232 | player.y -= player.speed; 233 | } 234 | else 235 | player.y = 16; 236 | 237 | if (player.x - player.speed >= 40) 238 | { 239 | player.x -= player.speed; 240 | } 241 | else 242 | player.x = 40; 243 | 244 | return 1; 245 | } 246 | 247 | if (kb_IsDown(kb_KeyDown) && kb_IsDown(kb_KeyRight)) 248 | { 249 | if (player.y + player.speed <= 155) 250 | { 251 | player.y += player.speed; 252 | } 253 | else 254 | player.y = 155; 255 | 256 | if (player.x + player.speed <= 279) 257 | { 258 | player.x += player.speed; 259 | } 260 | else 261 | player.x = 279; 262 | 263 | return 1; 264 | } 265 | 266 | if (kb_IsDown(kb_KeyDown) && kb_IsDown(kb_KeyLeft)) 267 | { 268 | if (player.y + player.speed <= 155) 269 | { 270 | player.y += player.speed; 271 | } 272 | else 273 | player.y = 155; 274 | 275 | if (player.x - player.speed >= 40) 276 | { 277 | player.x -= player.speed; 278 | } 279 | else 280 | player.x = 40; 281 | 282 | return 1; 283 | } 284 | 285 | return 1; 286 | } 287 | 288 | void draw_player(void) 289 | { 290 | gfx_sprite_t *temp; 291 | 292 | /* Checks if the player has bullets */ 293 | if (player.bullets == 0 || DUCK_FLYAWAY_TIMER == DUCK_FLYAWAY_MAX) 294 | return; 295 | 296 | /* Render crosshair cursor */ 297 | temp = gfx_MallocSprite(crosshair_width, crosshair_height); 298 | zx7_Decompress(temp, crosshair_compressed); 299 | 300 | gfx_TransparentSprite(temp, player.x - 12, player.y - 12); 301 | 302 | free(temp); 303 | } 304 | 305 | void get_player_buffer_layer(void) 306 | { 307 | /* Allocate space for back buffer */ 308 | if (player.back_buffer == NULL) 309 | player.back_buffer = gfx_MallocSprite(crosshair_width, crosshair_height); 310 | 311 | /* Grab player back buffer */ 312 | gfx_GetSprite(player.back_buffer, player.x - 12, player.y - 12); 313 | } 314 | 315 | void draw_player_buffer_layer(void) 316 | { 317 | if (player.back_buffer != NULL) 318 | { 319 | /* Render player back buffer*/ 320 | gfx_Sprite(player.back_buffer, player.x - 12, player.y - 12); 321 | 322 | /* Free player back buffer */ 323 | free(player.back_buffer); 324 | } 325 | 326 | player.back_buffer = NULL; 327 | } -------------------------------------------------------------------------------- /src/dog.c: -------------------------------------------------------------------------------- 1 | #include "dog.h" 2 | #include "ducks.h" 3 | #include "ui.h" 4 | #include "utils.h" 5 | #include "menu.h" 6 | #include "gfx/DUCKSPT.h" 7 | 8 | struct dog_t dog; 9 | 10 | /** 11 | * Sets the dog animation type 12 | * (run to the center, jump over the grass, and peek when a duck has been shot) 13 | */ 14 | void dog_SetMode(uint8_t mode) 15 | { 16 | dog.mode = mode; 17 | dog.speed = 1; 18 | dog.tick = 1; 19 | dog.animate = 0; 20 | dog.back_buffer = NULL; 21 | 22 | switch (mode) 23 | { 24 | case DOG_RUN_TO_CENTER: 25 | dog.x = 32; 26 | dog.y = 160; 27 | dog.cnum = 1; 28 | break; 29 | 30 | case DOG_PEEK_UP: 31 | if (menu.option == 1) 32 | { 33 | dog.cnum = 10; 34 | } 35 | else if (menu.option == 2) 36 | { 37 | dog.cnum = 11; 38 | } 39 | 40 | dog.y = 159; 41 | 42 | if (enemies[DUCK_FALLEN_ID].x > 231) 43 | { 44 | dog.x = 231; 45 | } 46 | else 47 | { 48 | dog.x = enemies[DUCK_FALLEN_ID].x; 49 | } 50 | 51 | dog.gotoY = dog.y - 30; 52 | 53 | break; 54 | 55 | case DOG_LAUGH: 56 | /* Set the costume to laugh */ 57 | dog.cnum = 12; 58 | 59 | /* place the dog under the grass */ 60 | dog.y = 159; 61 | 62 | /* Prepare to move via gotoY */ 63 | dog.gotoY = dog.y - 30; 64 | 65 | /* Set the position of the dog in the center */ 66 | dog.x = (LCD_WIDTH - dog_laugh_1_width) / 2; 67 | break; 68 | } 69 | } 70 | 71 | static void dog_manage_cnum(void) 72 | { 73 | switch (dog.cnum) 74 | { 75 | case 1: 76 | dog.cnum = 2; 77 | break; 78 | 79 | case 2: 80 | dog.cnum = 3; 81 | break; 82 | 83 | case 3: 84 | dog.cnum = 4; 85 | break; 86 | 87 | case 4: 88 | dog.cnum = 1; 89 | break; 90 | 91 | case 5: 92 | dog.cnum = 6; 93 | break; 94 | 95 | case 6: 96 | dog.cnum = 5; 97 | break; 98 | 99 | case 12: 100 | dog.cnum = 13; 101 | break; 102 | 103 | case 13: 104 | dog.cnum = 12; 105 | break; 106 | } 107 | } 108 | 109 | static void dog_animate(void) 110 | { 111 | switch (dog.cnum) 112 | { 113 | case 1: 114 | gfx_TransparentSprite(dog_walk_0, dog.x, dog.y); 115 | break; 116 | 117 | case 2: 118 | gfx_TransparentSprite(dog_walk_1, dog.x, dog.y); 119 | break; 120 | 121 | case 3: 122 | gfx_TransparentSprite(dog_walk_2, dog.x, dog.y); 123 | break; 124 | 125 | case 4: 126 | gfx_TransparentSprite(dog_walk_3, dog.x, dog.y); 127 | break; 128 | 129 | case 5: 130 | gfx_TransparentSprite(dog_walk_4, dog.x, dog.y); 131 | break; 132 | 133 | case 6: 134 | gfx_TransparentSprite(dog_walk_5, dog.x, dog.y); 135 | break; 136 | 137 | case 7: 138 | gfx_TransparentSprite(dog_walk_6, dog.x, dog.y - 8); 139 | break; 140 | 141 | case 8: 142 | gfx_TransparentSprite(dog_jump_1, dog.x, dog.y); 143 | break; 144 | 145 | case 9: 146 | gfx_TransparentSprite(dog_jump_2, dog.x, dog.y); 147 | break; 148 | 149 | case 10: 150 | gfx_TransparentSprite(dog_bird_1, dog.x, dog.y); 151 | break; 152 | 153 | case 11: 154 | gfx_TransparentSprite(dog_bird_2, dog.x, dog.y); 155 | break; 156 | 157 | case 12: 158 | gfx_TransparentSprite(dog_laugh_1, dog.x, dog.y); 159 | break; 160 | 161 | case 13: 162 | gfx_TransparentSprite(dog_laugh_2, dog.x, dog.y); 163 | break; 164 | } 165 | 166 | if (dog.animate == TIMER_ANIMATE_MAX || dog.mode == DOG_LAUGH) 167 | { 168 | dog_manage_cnum(); 169 | } 170 | } 171 | 172 | static void draw_back(void) 173 | { 174 | gfx_sprite_t *temp = NULL; 175 | 176 | // tree 177 | temp = gfx_MallocSprite(bg_tree_width, bg_tree_height); 178 | zx7_Decompress(temp, bg_tree_compressed); 179 | gfx_TransparentSprite(temp, 44, 39); 180 | free(temp); 181 | 182 | // bush 183 | temp = gfx_MallocSprite(bg_bush_width, bg_bush_height); 184 | zx7_Decompress(temp, bg_bush_compressed); 185 | gfx_TransparentSprite(temp, 218, 132); 186 | free(temp); 187 | } 188 | 189 | static void draw_grass(void) 190 | { 191 | gfx_sprite_t *temp = NULL; 192 | 193 | // Grass 194 | temp = gfx_MallocSprite(bg_ground_width, bg_ground_height); 195 | zx7_Decompress(temp, bg_ground_compressed); 196 | gfx_TransparentSprite(temp, 32, 156); 197 | free(temp); 198 | 199 | // bullet board 200 | temp = gfx_MallocSprite(bullet_board_width, bullet_board_height); 201 | zx7_Decompress(temp, bullet_board_compressed); 202 | gfx_TransparentSprite(temp, 52, 209); 203 | free(temp); 204 | 205 | // kill board 206 | temp = gfx_MallocSprite(kill_board_width, kill_board_height); 207 | zx7_Decompress(temp, kill_board_compressed); 208 | gfx_TransparentSprite(temp, 92, 209); 209 | free(temp); 210 | 211 | // score board 212 | temp = gfx_MallocSprite(score_board_width, score_board_height); 213 | zx7_Decompress(temp, score_board_compressed); 214 | gfx_TransparentSprite(temp, 220, 209); 215 | free(temp); 216 | 217 | // Print Score Board Information 218 | update_scene(); 219 | } 220 | 221 | /** 222 | * Draws the dog based on the sprite number. (needs work) 223 | */ 224 | void dog_Render(void) 225 | { 226 | if (dog.mode == DOG_PEEK_UP) 227 | { 228 | draw_back(); 229 | } 230 | 231 | /* Draw the Sprite of the dog */ 232 | dog_animate(); 233 | 234 | if ((dog.mode == DOG_RUN_TO_CENTER && dog.tick == 3) || dog.mode == DOG_LAUGH) 235 | { 236 | /* Set the transparent color of the duck based on the player game mode (aka menu.option) */ 237 | switch (menu.option) 238 | { 239 | case 1: 240 | gfx_SetTransparentColor(4); 241 | break; 242 | 243 | case 2: 244 | gfx_SetTransparentColor(5); 245 | break; 246 | } 247 | 248 | /* Render the grass block right after the duck */ 249 | // draw_dog_buffer_layer(); 250 | if (dog.back_buffer != NULL) 251 | gfx_TransparentSprite(dog.back_buffer, dog.x - 10, dog.y - 10); 252 | 253 | /* reset transparent color */ 254 | gfx_SetTransparentColor(0); 255 | } 256 | 257 | if (dog.mode == DOG_PEEK_UP) 258 | { 259 | draw_grass(); 260 | } 261 | } 262 | 263 | /** 264 | * Updates the dog movements based on the dog mode. 265 | */ 266 | void dog_Update(void) 267 | { 268 | switch (dog.mode) 269 | { 270 | case DOG_RUN_TO_CENTER: 271 | if (dog.tick == 1) 272 | { 273 | if (dog.x == 100 / 2) 274 | { 275 | dog.cnum = 5; 276 | dog.animate = TIMER_ANIMATE_MAX; 277 | for (int i = 0; i < 3; i++) 278 | { 279 | get_dog_buffer_layer(); 280 | dog_Render(); 281 | // ############### 282 | gfx_Blit(1); 283 | // ############### 284 | draw_dog_buffer_layer(); 285 | delay(TIMER_ANIMATE_MAX * 50); 286 | } 287 | dog.cnum = 1; 288 | dog.x++; 289 | return; 290 | } 291 | 292 | dog.x = Goto_Pos(dog.x, 100, dog.speed); 293 | 294 | if (dog.x == 100) 295 | { 296 | dog.cnum = 7; 297 | dog.tick++; 298 | } 299 | } 300 | 301 | if (dog.tick == 2) 302 | { 303 | if (dog.x == 100) 304 | { 305 | dog.cnum = 5; 306 | dog.animate = TIMER_ANIMATE_MAX; 307 | for (int i = 0; i < 3; i++) 308 | { 309 | get_dog_buffer_layer(); 310 | dog_Render(); 311 | // ############### 312 | gfx_Blit(1); 313 | // ############### 314 | draw_dog_buffer_layer(); 315 | delay(TIMER_ANIMATE_MAX * 50); 316 | } 317 | 318 | dog.cnum = 7; 319 | get_dog_buffer_layer(); 320 | dog_Render(); 321 | // ############### 322 | gfx_Blit(1); 323 | // ############### 324 | draw_dog_buffer_layer(); 325 | delay(TIMER_ANIMATE_MAX * 50); 326 | } 327 | 328 | dog.cnum = 8; 329 | dog.x = Goto_Pos(dog.x, 145, dog.speed + 1); 330 | dog.y = Goto_Pos(dog.y, 115, dog.speed + 1); 331 | if (dog.y == 115 && dog.x == 145) 332 | dog.tick++; 333 | } 334 | 335 | if (dog.tick == 3) 336 | { 337 | dog.cnum = 9; 338 | dog.y = Goto_Pos(dog.y, 160, dog.speed + 2); 339 | if (dog.y == 160) 340 | dog.mode = DOG_HIDDEN; 341 | } 342 | 343 | break; 344 | 345 | case DOG_PEEK_UP: 346 | case DOG_LAUGH: 347 | /* Peek Up */ 348 | if (dog.tick == 1) 349 | { 350 | /* Check if the code is equal to it final gotoY position */ 351 | if (dog.y == dog.gotoY) 352 | { 353 | /* Animate the dog laughing */ 354 | if (dog.mode == DOG_LAUGH) 355 | { 356 | /* Check if you can still animate `issue # 4` */ 357 | if (dog.animate < TIMER_ANIMATE_MAX) 358 | break; 359 | } 360 | 361 | dog.tick++; 362 | dog.gotoY = dog.y + 30; 363 | 364 | /* Pause when the dog reaches the top */ 365 | if (dog.mode == DOG_PEEK_UP) 366 | { 367 | delay(TIMER_ANIMATE_MAX * 50); 368 | } 369 | } 370 | 371 | /* Different Speeds for dog modes */ 372 | if (dog.mode == DOG_PEEK_UP) { 373 | dog.y = Goto_Pos(dog.y, dog.gotoY, dog.speed + 2); 374 | } else { 375 | dog.y = Goto_Pos(dog.y, dog.gotoY, dog.speed); 376 | } 377 | 378 | } 379 | 380 | /* Peek Down */ 381 | if (dog.tick == 2) 382 | { 383 | if (dog.y == dog.gotoY) 384 | dog.mode = DOG_HIDDEN; 385 | 386 | dog.y = Goto_Pos(dog.y, dog.gotoY, dog.speed + 2); 387 | } 388 | break; 389 | } 390 | 391 | if (dog.animate < TIMER_ANIMATE_MAX) 392 | { 393 | dog.animate++; 394 | } 395 | else 396 | { 397 | dog.animate = 0; 398 | } 399 | } 400 | 401 | /** 402 | * Draws the dog jumping for the beginning of the game. 403 | */ 404 | void draw_dog_scene(void) 405 | { 406 | do 407 | { 408 | get_dog_buffer_layer(); 409 | dog_Render(); 410 | 411 | // ############### 412 | gfx_Blit(1); 413 | // ############### 414 | 415 | draw_dog_buffer_layer(); 416 | dog_Update(); 417 | } while (dog.mode != DOG_HIDDEN); 418 | } 419 | 420 | void get_dog_buffer_layer(void) 421 | { 422 | if (dog.back_buffer == NULL) 423 | dog.back_buffer = gfx_MallocSprite(70, 60); 424 | 425 | gfx_GetSprite(dog.back_buffer, dog.x - 10, dog.y - 10); 426 | } 427 | 428 | void draw_dog_buffer_layer(void) 429 | { 430 | if (dog.back_buffer != NULL) 431 | { 432 | /* Render player back buffer*/ 433 | gfx_Sprite(dog.back_buffer, dog.x - 10, dog.y - 10); 434 | 435 | /* Free the back buffer */ 436 | free(dog.back_buffer); 437 | } 438 | 439 | dog.back_buffer = NULL; 440 | } -------------------------------------------------------------------------------- /src/gfx/DUCKSPT.h: -------------------------------------------------------------------------------- 1 | #ifndef DUCKSPT_appvar_include_file 2 | #define DUCKSPT_appvar_include_file 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #define sizeof_palette 52 9 | #define palette (DUCKSPT_appvar[0]) 10 | #define dog_palette_offset 0 11 | #define dog_bird_1_width 43 12 | #define dog_bird_1_height 40 13 | #define DUCKSPT_dog_dog_bird_1_index 1 14 | #define dog_bird_1 ((gfx_sprite_t*)DUCKSPT_appvar[1]) 15 | #define dog_bird_2_width 56 16 | #define dog_bird_2_height 40 17 | #define DUCKSPT_dog_dog_bird_2_index 2 18 | #define dog_bird_2 ((gfx_sprite_t*)DUCKSPT_appvar[2]) 19 | #define dog_jump_1_width 35 20 | #define dog_jump_1_height 48 21 | #define DUCKSPT_dog_dog_jump_1_index 3 22 | #define dog_jump_1 ((gfx_sprite_t*)DUCKSPT_appvar[3]) 23 | #define dog_jump_2_width 33 24 | #define dog_jump_2_height 32 25 | #define DUCKSPT_dog_dog_jump_2_index 4 26 | #define dog_jump_2 ((gfx_sprite_t*)DUCKSPT_appvar[4]) 27 | #define dog_laugh_1_width 29 28 | #define dog_laugh_1_height 40 29 | #define DUCKSPT_dog_dog_laugh_1_index 5 30 | #define dog_laugh_1 ((gfx_sprite_t*)DUCKSPT_appvar[5]) 31 | #define dog_laugh_2_width 29 32 | #define dog_laugh_2_height 40 33 | #define DUCKSPT_dog_dog_laugh_2_index 6 34 | #define dog_laugh_2 ((gfx_sprite_t*)DUCKSPT_appvar[6]) 35 | #define dog_walk_0_width 55 36 | #define dog_walk_0_height 40 37 | #define DUCKSPT_dog_dog_walk_0_index 7 38 | #define dog_walk_0 ((gfx_sprite_t*)DUCKSPT_appvar[7]) 39 | #define dog_walk_1_width 51 40 | #define dog_walk_1_height 43 41 | #define DUCKSPT_dog_dog_walk_1_index 8 42 | #define dog_walk_1 ((gfx_sprite_t*)DUCKSPT_appvar[8]) 43 | #define dog_walk_2_width 53 44 | #define dog_walk_2_height 40 45 | #define DUCKSPT_dog_dog_walk_2_index 9 46 | #define dog_walk_2 ((gfx_sprite_t*)DUCKSPT_appvar[9]) 47 | #define dog_walk_3_width 51 48 | #define dog_walk_3_height 43 49 | #define DUCKSPT_dog_dog_walk_3_index 10 50 | #define dog_walk_3 ((gfx_sprite_t*)DUCKSPT_appvar[10]) 51 | #define dog_walk_4_width 55 52 | #define dog_walk_4_height 40 53 | #define DUCKSPT_dog_dog_walk_4_index 11 54 | #define dog_walk_4 ((gfx_sprite_t*)DUCKSPT_appvar[11]) 55 | #define dog_walk_5_width 53 56 | #define dog_walk_5_height 40 57 | #define DUCKSPT_dog_dog_walk_5_index 12 58 | #define dog_walk_5 ((gfx_sprite_t*)DUCKSPT_appvar[12]) 59 | #define dog_walk_6_width 53 60 | #define dog_walk_6_height 48 61 | #define DUCKSPT_dog_dog_walk_6_index 13 62 | #define dog_walk_6 ((gfx_sprite_t*)DUCKSPT_appvar[13]) 63 | #define ducks_palette_offset 0 64 | #define Duck_A_1_width 34 65 | #define Duck_A_1_height 29 66 | #define DUCKSPT_ducks_Duck_A_1_index 14 67 | #define Duck_A_1 ((gfx_sprite_t*)DUCKSPT_appvar[14]) 68 | #define Duck_A_2_width 34 69 | #define Duck_A_2_height 29 70 | #define DUCKSPT_ducks_Duck_A_2_index 15 71 | #define Duck_A_2 ((gfx_sprite_t*)DUCKSPT_appvar[15]) 72 | #define Duck_A_3_width 34 73 | #define Duck_A_3_height 29 74 | #define DUCKSPT_ducks_Duck_A_3_index 16 75 | #define Duck_A_3 ((gfx_sprite_t*)DUCKSPT_appvar[16]) 76 | #define Duck_B_1_width 32 77 | #define Duck_B_1_height 31 78 | #define DUCKSPT_ducks_Duck_B_1_index 17 79 | #define Duck_B_1 ((gfx_sprite_t*)DUCKSPT_appvar[17]) 80 | #define Duck_B_2_width 32 81 | #define Duck_B_2_height 31 82 | #define DUCKSPT_ducks_Duck_B_2_index 18 83 | #define Duck_B_2 ((gfx_sprite_t*)DUCKSPT_appvar[18]) 84 | #define Duck_B_3_width 32 85 | #define Duck_B_3_height 31 86 | #define DUCKSPT_ducks_Duck_B_3_index 19 87 | #define Duck_B_3 ((gfx_sprite_t*)DUCKSPT_appvar[19]) 88 | #define Duck_Fall_1_width 18 89 | #define Duck_Fall_1_height 31 90 | #define DUCKSPT_ducks_Duck_Fall_1_index 20 91 | #define Duck_Fall_1 ((gfx_sprite_t*)DUCKSPT_appvar[20]) 92 | #define Duck_Fall_2_width 18 93 | #define Duck_Fall_2_height 31 94 | #define DUCKSPT_ducks_Duck_Fall_2_index 21 95 | #define Duck_Fall_2 ((gfx_sprite_t*)DUCKSPT_appvar[21]) 96 | #define Duck_Flyaway_1_width 32 97 | #define Duck_Flyaway_1_height 35 98 | #define DUCKSPT_ducks_Duck_Flyaway_1_index 22 99 | #define Duck_Flyaway_1 ((gfx_sprite_t*)DUCKSPT_appvar[22]) 100 | #define Duck_Flyaway_2_width 32 101 | #define Duck_Flyaway_2_height 35 102 | #define DUCKSPT_ducks_Duck_Flyaway_2_index 23 103 | #define Duck_Flyaway_2 ((gfx_sprite_t*)DUCKSPT_appvar[23]) 104 | #define Duck_Flyaway_3_width 32 105 | #define Duck_Flyaway_3_height 35 106 | #define DUCKSPT_ducks_Duck_Flyaway_3_index 24 107 | #define Duck_Flyaway_3 ((gfx_sprite_t*)DUCKSPT_appvar[24]) 108 | #define Duck_Shot_width 31 109 | #define Duck_Shot_height 29 110 | #define DUCKSPT_ducks_Duck_Shot_index 25 111 | #define Duck_Shot ((gfx_sprite_t*)DUCKSPT_appvar[25]) 112 | #define Duckb_A_1_width 34 113 | #define Duckb_A_1_height 29 114 | #define DUCKSPT_ducks_Duckb_A_1_index 26 115 | #define Duckb_A_1 ((gfx_sprite_t*)DUCKSPT_appvar[26]) 116 | #define Duckb_A_2_width 34 117 | #define Duckb_A_2_height 29 118 | #define DUCKSPT_ducks_Duckb_A_2_index 27 119 | #define Duckb_A_2 ((gfx_sprite_t*)DUCKSPT_appvar[27]) 120 | #define Duckb_A_3_width 34 121 | #define Duckb_A_3_height 29 122 | #define DUCKSPT_ducks_Duckb_A_3_index 28 123 | #define Duckb_A_3 ((gfx_sprite_t*)DUCKSPT_appvar[28]) 124 | #define Duckb_B_1_width 32 125 | #define Duckb_B_1_height 31 126 | #define DUCKSPT_ducks_Duckb_B_1_index 29 127 | #define Duckb_B_1 ((gfx_sprite_t*)DUCKSPT_appvar[29]) 128 | #define Duckb_B_2_width 32 129 | #define Duckb_B_2_height 31 130 | #define DUCKSPT_ducks_Duckb_B_2_index 30 131 | #define Duckb_B_2 ((gfx_sprite_t*)DUCKSPT_appvar[30]) 132 | #define Duckb_B_3_width 32 133 | #define Duckb_B_3_height 31 134 | #define DUCKSPT_ducks_Duckb_B_3_index 31 135 | #define Duckb_B_3 ((gfx_sprite_t*)DUCKSPT_appvar[31]) 136 | #define Duckb_Fall_1_width 18 137 | #define Duckb_Fall_1_height 31 138 | #define DUCKSPT_ducks_Duckb_Fall_1_index 32 139 | #define Duckb_Fall_1 ((gfx_sprite_t*)DUCKSPT_appvar[32]) 140 | #define Duckb_Fall_2_width 18 141 | #define Duckb_Fall_2_height 31 142 | #define DUCKSPT_ducks_Duckb_Fall_2_index 33 143 | #define Duckb_Fall_2 ((gfx_sprite_t*)DUCKSPT_appvar[33]) 144 | #define Duckb_Flyaway_1_width 32 145 | #define Duckb_Flyaway_1_height 35 146 | #define DUCKSPT_ducks_Duckb_Flyaway_1_index 34 147 | #define Duckb_Flyaway_1 ((gfx_sprite_t*)DUCKSPT_appvar[34]) 148 | #define Duckb_Flyaway_2_width 32 149 | #define Duckb_Flyaway_2_height 35 150 | #define DUCKSPT_ducks_Duckb_Flyaway_2_index 35 151 | #define Duckb_Flyaway_2 ((gfx_sprite_t*)DUCKSPT_appvar[35]) 152 | #define Duckb_Flyaway_3_width 32 153 | #define Duckb_Flyaway_3_height 35 154 | #define DUCKSPT_ducks_Duckb_Flyaway_3_index 36 155 | #define Duckb_Flyaway_3 ((gfx_sprite_t*)DUCKSPT_appvar[36]) 156 | #define Duckb_Shot_width 31 157 | #define Duckb_Shot_height 29 158 | #define DUCKSPT_ducks_Duckb_Shot_index 37 159 | #define Duckb_Shot ((gfx_sprite_t*)DUCKSPT_appvar[37]) 160 | #define Duckc_A_1_width 34 161 | #define Duckc_A_1_height 29 162 | #define DUCKSPT_ducks_Duckc_A_1_index 38 163 | #define Duckc_A_1 ((gfx_sprite_t*)DUCKSPT_appvar[38]) 164 | #define Duckc_A_2_width 34 165 | #define Duckc_A_2_height 29 166 | #define DUCKSPT_ducks_Duckc_A_2_index 39 167 | #define Duckc_A_2 ((gfx_sprite_t*)DUCKSPT_appvar[39]) 168 | #define Duckc_A_3_width 34 169 | #define Duckc_A_3_height 29 170 | #define DUCKSPT_ducks_Duckc_A_3_index 40 171 | #define Duckc_A_3 ((gfx_sprite_t*)DUCKSPT_appvar[40]) 172 | #define Duckc_B_1_width 32 173 | #define Duckc_B_1_height 31 174 | #define DUCKSPT_ducks_Duckc_B_1_index 41 175 | #define Duckc_B_1 ((gfx_sprite_t*)DUCKSPT_appvar[41]) 176 | #define Duckc_B_2_width 32 177 | #define Duckc_B_2_height 31 178 | #define DUCKSPT_ducks_Duckc_B_2_index 42 179 | #define Duckc_B_2 ((gfx_sprite_t*)DUCKSPT_appvar[42]) 180 | #define Duckc_B_3_width 32 181 | #define Duckc_B_3_height 31 182 | #define DUCKSPT_ducks_Duckc_B_3_index 43 183 | #define Duckc_B_3 ((gfx_sprite_t*)DUCKSPT_appvar[43]) 184 | #define Duckc_Fall_1_width 18 185 | #define Duckc_Fall_1_height 31 186 | #define DUCKSPT_ducks_Duckc_Fall_1_index 44 187 | #define Duckc_Fall_1 ((gfx_sprite_t*)DUCKSPT_appvar[44]) 188 | #define Duckc_Fall_2_width 18 189 | #define Duckc_Fall_2_height 31 190 | #define DUCKSPT_ducks_Duckc_Fall_2_index 45 191 | #define Duckc_Fall_2 ((gfx_sprite_t*)DUCKSPT_appvar[45]) 192 | #define Duckc_Flyaway_1_width 32 193 | #define Duckc_Flyaway_1_height 35 194 | #define DUCKSPT_ducks_Duckc_Flyaway_1_index 46 195 | #define Duckc_Flyaway_1 ((gfx_sprite_t*)DUCKSPT_appvar[46]) 196 | #define Duckc_Flyaway_2_width 32 197 | #define Duckc_Flyaway_2_height 35 198 | #define DUCKSPT_ducks_Duckc_Flyaway_2_index 47 199 | #define Duckc_Flyaway_2 ((gfx_sprite_t*)DUCKSPT_appvar[47]) 200 | #define Duckc_Flyaway_3_width 32 201 | #define Duckc_Flyaway_3_height 35 202 | #define DUCKSPT_ducks_Duckc_Flyaway_3_index 48 203 | #define Duckc_Flyaway_3 ((gfx_sprite_t*)DUCKSPT_appvar[48]) 204 | #define Duckc_Shot_width 31 205 | #define Duckc_Shot_height 29 206 | #define DUCKSPT_ducks_Duckc_Shot_index 49 207 | #define Duckc_Shot ((gfx_sprite_t*)DUCKSPT_appvar[49]) 208 | #define Clay_1_width 16 209 | #define Clay_1_height 16 210 | #define DUCKSPT_ducks_Clay_1_index 50 211 | #define Clay_1 ((gfx_sprite_t*)DUCKSPT_appvar[50]) 212 | #define Clay_2_width 16 213 | #define Clay_2_height 16 214 | #define DUCKSPT_ducks_Clay_2_index 51 215 | #define Clay_2 ((gfx_sprite_t*)DUCKSPT_appvar[51]) 216 | #define Clay_3_width 16 217 | #define Clay_3_height 16 218 | #define DUCKSPT_ducks_Clay_3_index 52 219 | #define Clay_3 ((gfx_sprite_t*)DUCKSPT_appvar[52]) 220 | #define Clay_4_width 16 221 | #define Clay_4_height 16 222 | #define DUCKSPT_ducks_Clay_4_index 53 223 | #define Clay_4 ((gfx_sprite_t*)DUCKSPT_appvar[53]) 224 | #define game_palette_offset 0 225 | #define bg_bush_width 32 226 | #define bg_bush_height 40 227 | #define DUCKSPT_game_bg_bush_compressed_index 54 228 | #define bg_bush_compressed DUCKSPT_appvar[54] 229 | #define bg_ground_width 255 230 | #define bg_ground_height 56 231 | #define DUCKSPT_game_bg_ground_compressed_index 55 232 | #define bg_ground_compressed DUCKSPT_appvar[55] 233 | #define bg_tree_width 69 234 | #define bg_tree_height 140 235 | #define DUCKSPT_game_bg_tree_compressed_index 56 236 | #define bg_tree_compressed DUCKSPT_appvar[56] 237 | #define panel_icon_1_width 7 238 | #define panel_icon_1_height 7 239 | #define DUCKSPT_game_panel_icon_1_compressed_index 57 240 | #define panel_icon_1_compressed DUCKSPT_appvar[57] 241 | #define panel_icon_2_width 7 242 | #define panel_icon_2_height 7 243 | #define DUCKSPT_game_panel_icon_2_compressed_index 58 244 | #define panel_icon_2_compressed DUCKSPT_appvar[58] 245 | #define panel_icon_3_width 7 246 | #define panel_icon_3_height 7 247 | #define DUCKSPT_game_panel_icon_3_compressed_index 59 248 | #define panel_icon_3_compressed DUCKSPT_appvar[59] 249 | #define panel_icon_4_width 7 250 | #define panel_icon_4_height 7 251 | #define DUCKSPT_game_panel_icon_4_compressed_index 60 252 | #define panel_icon_4_compressed DUCKSPT_appvar[60] 253 | #define panel_icon_5_width 7 254 | #define panel_icon_5_height 7 255 | #define DUCKSPT_game_panel_icon_5_compressed_index 61 256 | #define panel_icon_5_compressed DUCKSPT_appvar[61] 257 | #define bullet_width 4 258 | #define bullet_height 7 259 | #define DUCKSPT_game_bullet_compressed_index 62 260 | #define bullet_compressed DUCKSPT_appvar[62] 261 | #define bullet_board_width 29 262 | #define bullet_board_height 21 263 | #define DUCKSPT_game_bullet_board_compressed_index 63 264 | #define bullet_board_compressed DUCKSPT_appvar[63] 265 | #define c_ground_width 255 266 | #define c_ground_height 43 267 | #define DUCKSPT_game_c_ground_compressed_index 64 268 | #define c_ground_compressed DUCKSPT_appvar[64] 269 | #define c_mountain_width 255 270 | #define c_mountain_height 45 271 | #define DUCKSPT_game_c_mountain_compressed_index 65 272 | #define c_mountain_compressed DUCKSPT_appvar[65] 273 | #define c_panel_width 255 274 | #define c_panel_height 8 275 | #define DUCKSPT_game_c_panel_compressed_index 66 276 | #define c_panel_compressed DUCKSPT_appvar[66] 277 | #define crosshair_width 25 278 | #define crosshair_height 25 279 | #define DUCKSPT_game_crosshair_compressed_index 67 280 | #define crosshair_compressed DUCKSPT_appvar[67] 281 | #define fly_away_width 73 282 | #define fly_away_height 17 283 | #define DUCKSPT_game_fly_away_compressed_index 68 284 | #define fly_away_compressed DUCKSPT_appvar[68] 285 | #define kill_board_width 117 286 | #define kill_board_height 21 287 | #define DUCKSPT_game_kill_board_compressed_index 69 288 | #define kill_board_compressed DUCKSPT_appvar[69] 289 | #define pause_width 49 290 | #define pause_height 33 291 | #define DUCKSPT_game_pause_compressed_index 70 292 | #define pause_compressed DUCKSPT_appvar[70] 293 | #define score_board_width 53 294 | #define score_board_height 21 295 | #define DUCKSPT_game_score_board_compressed_index 71 296 | #define score_board_compressed DUCKSPT_appvar[71] 297 | #define menu_palette_offset 0 298 | #define cr_symbol_width 8 299 | #define cr_symbol_height 8 300 | #define DUCKSPT_menu_cr_symbol_compressed_index 72 301 | #define cr_symbol_compressed DUCKSPT_appvar[72] 302 | #define menu_arrow_width 12 303 | #define menu_arrow_height 10 304 | #define DUCKSPT_menu_menu_arrow_compressed_index 73 305 | #define menu_arrow_compressed DUCKSPT_appvar[73] 306 | #define Title_Menu_width 143 307 | #define Title_Menu_height 65 308 | #define DUCKSPT_menu_Title_Menu_compressed_index 74 309 | #define Title_Menu_compressed DUCKSPT_appvar[74] 310 | #define DUCKSPT_entries_num 75 311 | extern unsigned char *DUCKSPT_appvar[75]; 312 | unsigned char DUCKSPT_init(void); 313 | 314 | #ifdef __cplusplus 315 | } 316 | #endif 317 | 318 | #endif 319 | -------------------------------------------------------------------------------- /src/ui.c: -------------------------------------------------------------------------------- 1 | #include "ui.h" 2 | #include "utils.h" 3 | #include "ducks.h" 4 | #include "menu.h" 5 | #include "dog.h" 6 | #include "player.h" 7 | #include "gfx/DUCKSPT.h" 8 | 9 | struct game_t game; 10 | 11 | /* https://www.geeksforgeeks.org/bubble-sort/# */ 12 | static void swap(int *xp, int *yp) 13 | { 14 | int temp = *xp; 15 | *xp = *yp; 16 | *yp = temp; 17 | } 18 | 19 | void bubble_sort_hits_panel(void) 20 | { 21 | int i, j; 22 | bool swapped; 23 | 24 | for (i = 0; i < 10 - 1; i++) 25 | { 26 | swapped = false; 27 | for (j = 0; j < 10 - i - 1; j++) 28 | { 29 | if (game.duck_hits[j] > game.duck_hits[j + 1]) 30 | { 31 | swap(&game.duck_hits[j], &game.duck_hits[j + 1]); 32 | swapped = true; 33 | 34 | update_scene(); 35 | gfx_Blit(1); 36 | delay(50); 37 | } 38 | } 39 | 40 | // If no two elements were swapped by inner loop, 41 | // then break 42 | if (swapped == false) 43 | break; 44 | } 45 | 46 | delay(300); 47 | } 48 | 49 | /* Used to get the amount of shot ducks based off the HUD */ 50 | int get_hud_hits_shot(void) 51 | { 52 | int tick = 0; 53 | 54 | for (int i = 0; i < 10; i++) 55 | { 56 | if (game.duck_hits[i] == DUCK_SHOT) 57 | { 58 | tick++; 59 | } 60 | } 61 | 62 | return tick; 63 | } 64 | 65 | static void flyaway_scene(void) 66 | { 67 | gfx_sprite_t *temp = gfx_MallocSprite(fly_away_width, fly_away_height); 68 | gfx_sprite_t *back_buff = gfx_MallocSprite(fly_away_width, fly_away_height); 69 | 70 | gfx_GetSprite(back_buff, 124, 103); 71 | 72 | zx7_Decompress(temp, fly_away_compressed); 73 | gfx_TransparentSprite(temp, 124, 103); 74 | free(temp); 75 | 76 | gfx_Blit(1); 77 | 78 | gfx_Sprite(back_buff, 124, 103); 79 | free(back_buff); 80 | } 81 | 82 | static void pause_scene(void) 83 | { 84 | gfx_sprite_t *temp = gfx_MallocSprite(pause_width, pause_height); 85 | gfx_sprite_t *back_buff = gfx_MallocSprite(pause_width, pause_height); 86 | 87 | gfx_GetSprite(back_buff, 135, 88); 88 | 89 | /* Pretend this is the dog */ 90 | /* gfx_SetColor(1); // White 91 | gfx_FillRectangle(135, 88, 49, 33); */ 92 | 93 | zx7_Decompress(temp, pause_compressed); 94 | gfx_TransparentSprite(temp, 135, 88); 95 | free(temp); 96 | 97 | gfx_Blit(1); 98 | 99 | delay(60); 100 | 101 | while (!os_GetCSC()) 102 | ; 103 | 104 | delay(60); 105 | 106 | gfx_Sprite(back_buff, 135, 88); 107 | free(back_buff); 108 | } 109 | 110 | void update_scene(void) 111 | { 112 | gfx_sprite_t *temp; 113 | 114 | // Draw Bullets 115 | gfx_SetColor(2); // Black 116 | if (menu.option < 3) 117 | { 118 | gfx_FillRectangle(57, 212, 20, 7); 119 | } 120 | else 121 | { 122 | gfx_FillRectangle(57, 204, 20, 7); 123 | } 124 | 125 | temp = gfx_MallocSprite(bullet_width, bullet_height); 126 | zx7_Decompress(temp, bullet_compressed); 127 | 128 | for (int i = 0; i < player.bullets; i++) 129 | { 130 | 131 | if (menu.option < 3) 132 | { 133 | // Game A and B 134 | gfx_TransparentSprite(temp, 57 + (i * (4 + 4)), 212); 135 | } 136 | else 137 | { 138 | // Game C 139 | gfx_TransparentSprite(temp, 57 + (i * (4 + 4)), 204); 140 | } 141 | } 142 | 143 | free(temp); 144 | 145 | /* Hit Panel */ 146 | 147 | temp = gfx_MallocSprite(panel_icon_1_width, panel_icon_1_height); 148 | 149 | for (int i = 0; i < 10; i++) 150 | { 151 | if (menu.option < 3) 152 | { 153 | // Game A and B 154 | if (game.duck_hits[i] == DUCK_SHOT) 155 | { 156 | zx7_Decompress(temp, panel_icon_2_compressed); 157 | } 158 | else 159 | { 160 | zx7_Decompress(temp, panel_icon_1_compressed); 161 | } 162 | 163 | gfx_TransparentSprite(temp, 127 + (i * (panel_icon_1_width + 1)), 213); 164 | 165 | /* Blinking */ 166 | if (dog.mode != DOG_RUN_TO_CENTER && game.start == true) 167 | { 168 | if (get_hud_hits_position() == i) 169 | { 170 | if (randInt(0, 1)) 171 | { 172 | gfx_SetColor(2); 173 | gfx_FillRectangle(127 + (i * (8)), 213, 7, 7); 174 | } 175 | } 176 | } 177 | } 178 | else 179 | { 180 | 181 | if (game.duck_hits[i]) 182 | { 183 | zx7_Decompress(temp, panel_icon_4_compressed); 184 | gfx_SetColor(16); 185 | } 186 | else 187 | { 188 | zx7_Decompress(temp, panel_icon_5_compressed); 189 | gfx_SetColor(1); 190 | } 191 | 192 | gfx_TransparentSprite(temp, 127 + (i * (panel_icon_1_width + 1)), 205); 193 | 194 | if (game.start == true) 195 | { 196 | if (get_hud_hits_position() == i) 197 | { 198 | if (randInt(0, 1)) 199 | { 200 | gfx_SetColor(2); 201 | gfx_FillRectangle(127 + (i * (8)), 205, 7, 7); 202 | } 203 | } 204 | } 205 | } 206 | } 207 | 208 | free(temp); 209 | 210 | /* Advanced amount */ 211 | if (player.round >= 1 && player.round <= 10) 212 | { 213 | GAME_ADVANCE_THRESHOLD = 6; 214 | } 215 | else if (player.round >= 11 && player.round <= 12) 216 | { 217 | GAME_ADVANCE_THRESHOLD = 7; 218 | } 219 | else if (player.round >= 13 && player.round <= 14) 220 | { 221 | GAME_ADVANCE_THRESHOLD = 8; 222 | } 223 | else if (player.round >= 15 && player.round <= 19) 224 | { 225 | GAME_ADVANCE_THRESHOLD = 9; 226 | } 227 | else 228 | { 229 | GAME_ADVANCE_THRESHOLD = 10; 230 | } 231 | 232 | temp = gfx_MallocSprite(panel_icon_3_width, panel_icon_3_height); 233 | zx7_Decompress(temp, panel_icon_3_compressed); 234 | 235 | for (int i = 0; i < GAME_ADVANCE_THRESHOLD; i++) 236 | { 237 | if (menu.option < 3) 238 | { 239 | gfx_TransparentSprite(temp, 127 + (i * (panel_icon_3_width + 1)), 221); 240 | } 241 | else 242 | { 243 | gfx_TransparentSprite(temp, 127 + (i * (panel_icon_3_width + 1)), 213); 244 | } 245 | } 246 | 247 | free(temp); 248 | 249 | // Draw Score 250 | 251 | /* Fill the area up */ 252 | gfx_SetColor(2); // Black 253 | gfx_SetTextFGColor(1); // White 254 | 255 | if (menu.option < 3) 256 | { 257 | gfx_FillRectangle(223, 211, 47, 8); 258 | 259 | gfx_SetTextXY(223, 211); 260 | gfx_PrintInt(player.score, 6); 261 | } 262 | else 263 | { 264 | gfx_FillRectangle(223, 203, 47, 8); 265 | 266 | gfx_SetTextXY(223, 203); 267 | gfx_PrintInt(player.score, 6); 268 | } 269 | 270 | // Draw Round 271 | gfx_SetTextFGColor(16); // Green 272 | gfx_SetTextBGColor(2); // Black 273 | gfx_SetTextXY(253, 11); 274 | gfx_PrintString("R="); 275 | gfx_PrintInt(player.round, 0); 276 | 277 | /* Render Fly away Scene for game A and B */ 278 | if (menu.option < 3) 279 | { 280 | if (player.bullets == 0) 281 | { 282 | // Check if there are any birds on scene 283 | if (DUCK_FALLEN_AMOUNT != DUCK_AMOUNT) 284 | { 285 | flyaway_scene(); 286 | } 287 | } 288 | } 289 | 290 | if (kb_Data[1] == kb_Mode) 291 | { 292 | pause_scene(); 293 | } 294 | } 295 | 296 | static int count_digits(int number) 297 | { 298 | int count = 0; 299 | while (number > 0) 300 | { 301 | number /= 10; 302 | count++; 303 | } 304 | return count; 305 | } 306 | 307 | /** 308 | * This is used to draw the scene for the game. 309 | * It depends on the me variable (menu.option). 310 | */ 311 | void draw_scene(void) 312 | { 313 | gfx_sprite_t *temp; 314 | 315 | game.start = false; 316 | DUCK_FLYAWAY_TIMER = 0; 317 | 318 | gfx_FillScreen(2); // BLACK 319 | 320 | gfx_SetColor(1); // WHITE 321 | gfx_Rectangle(31, 7, 258, 225); 322 | 323 | // Renders Sky 324 | switch (menu.option) 325 | { 326 | case 1: 327 | gfx_SetColor(4); 328 | gfx_FillRectangle(32, 8, 256, 223); 329 | break; 330 | 331 | case 2: 332 | gfx_SetColor(5); 333 | gfx_FillRectangle(32, 8, 256, 223); 334 | break; 335 | 336 | case 3: 337 | gfx_SetColor(3); 338 | gfx_FillRectangle(32, 8, 256, 223); 339 | break; 340 | } 341 | 342 | if (menu.option < 3) 343 | { // Game A & Game B 344 | // tree 345 | temp = gfx_MallocSprite(bg_tree_width, bg_tree_height); 346 | zx7_Decompress(temp, bg_tree_compressed); 347 | gfx_TransparentSprite(temp, 44, 39); 348 | free(temp); 349 | 350 | // bush 351 | temp = gfx_MallocSprite(bg_bush_width, bg_bush_height); 352 | zx7_Decompress(temp, bg_bush_compressed); 353 | gfx_TransparentSprite(temp, 218, 132); 354 | free(temp); 355 | 356 | // ground 357 | gfx_SetColor(6); 358 | gfx_FillRectangle(32, 190, 256, 41); 359 | 360 | temp = gfx_MallocSprite(bg_ground_width, bg_ground_height); 361 | zx7_Decompress(temp, bg_ground_compressed); 362 | gfx_TransparentSprite(temp, 32, 156); 363 | free(temp); 364 | 365 | // Duplicated Last line 366 | temp = gfx_MallocSprite(1, bg_ground_height); 367 | gfx_GetSprite(temp, 286, 156); 368 | gfx_Sprite(temp, 287, 156); 369 | free(temp); 370 | 371 | // bullet board 372 | temp = gfx_MallocSprite(bullet_board_width, bullet_board_height); 373 | zx7_Decompress(temp, bullet_board_compressed); 374 | gfx_TransparentSprite(temp, 52, 209); 375 | free(temp); 376 | 377 | // kill board 378 | temp = gfx_MallocSprite(kill_board_width, kill_board_height); 379 | zx7_Decompress(temp, kill_board_compressed); 380 | gfx_TransparentSprite(temp, 92, 209); 381 | free(temp); 382 | 383 | // score board 384 | temp = gfx_MallocSprite(score_board_width, score_board_height); 385 | zx7_Decompress(temp, score_board_compressed); 386 | gfx_TransparentSprite(temp, 220, 209); 387 | free(temp); 388 | 389 | // Print Score Board Information 390 | update_scene(); 391 | 392 | // Print Round Number 393 | gfx_sprite_t *back_buff = gfx_MallocSprite(fly_away_width, fly_away_height * 2); 394 | 395 | gfx_GetSprite(back_buff, (LCD_WIDTH - fly_away_width) / 2, 103); 396 | 397 | ui_rectangle((LCD_WIDTH - fly_away_width) / 2, 103, fly_away_width, fly_away_height * 2); 398 | 399 | gfx_SetTextFGColor(1); 400 | gfx_SetTextXY((LCD_WIDTH - gfx_GetStringWidth("ROUND")) / 2, 110); 401 | gfx_PrintString("ROUND"); 402 | 403 | gfx_SetTextXY((LCD_WIDTH - (8 * count_digits(player.round))) / 2, 123); 404 | gfx_PrintInt(player.round, 0); 405 | 406 | gfx_Blit(1); 407 | 408 | delay(1000); 409 | 410 | /* Print round number back buffer */ 411 | gfx_Sprite(back_buff, (LCD_WIDTH - fly_away_width) / 2, 103); 412 | free(back_buff); 413 | 414 | // Render dog 415 | dog_SetMode(DOG_RUN_TO_CENTER); 416 | draw_dog_scene(); 417 | } 418 | else 419 | { // Game C 420 | 421 | temp = gfx_MallocSprite(c_mountain_width, c_mountain_height); 422 | zx7_Decompress(temp, c_mountain_compressed); 423 | gfx_TransparentSprite(temp, 32, 95); 424 | free(temp); 425 | 426 | temp = gfx_MallocSprite(c_ground_width, c_ground_height); 427 | zx7_Decompress(temp, c_ground_compressed); 428 | gfx_TransparentSprite(temp, 32, 140); 429 | free(temp); 430 | 431 | gfx_SetColor(16); // Green 432 | gfx_FillRectangle(32, 183, c_panel_width, c_panel_height); 433 | 434 | temp = gfx_MallocSprite(c_panel_width, c_panel_height); 435 | zx7_Decompress(temp, c_panel_compressed); 436 | gfx_TransparentSprite(temp, 32, 183); 437 | free(temp); 438 | 439 | temp = gfx_MallocSprite(1, c_panel_height + c_ground_height + c_mountain_height); 440 | gfx_GetSprite(temp, 286, 95); 441 | gfx_Sprite(temp, 287, 95); 442 | free(temp); 443 | 444 | gfx_SetColor(7); // Gray 445 | gfx_FillRectangle(32, 191, 256, 40); 446 | 447 | // bullet board 448 | temp = gfx_MallocSprite(bullet_board_width, bullet_board_height); 449 | zx7_Decompress(temp, bullet_board_compressed); 450 | gfx_TransparentSprite(temp, 52, 201); 451 | free(temp); 452 | 453 | // kill board 454 | temp = gfx_MallocSprite(kill_board_width, kill_board_height); 455 | zx7_Decompress(temp, kill_board_compressed); 456 | gfx_TransparentSprite(temp, 92, 201); 457 | free(temp); 458 | 459 | // score board 460 | temp = gfx_MallocSprite(score_board_width, score_board_height); 461 | zx7_Decompress(temp, score_board_compressed); 462 | gfx_TransparentSprite(temp, 220, 201); 463 | free(temp); 464 | 465 | // Print Score Board Information 466 | update_scene(); 467 | } 468 | 469 | game.start = true; 470 | 471 | gfx_Blit(1); 472 | } 473 | 474 | /** 475 | * This is used to innit the game and setup and variables. 476 | */ 477 | void init_duckhunt(void) 478 | { 479 | /* Initialize the player position */ 480 | player.x = 320 / 2; 481 | player.y = 240 / 2; 482 | player.score = 0; 483 | player.speed = 5; 484 | player.level = 1; 485 | player.round = 1; 486 | player.bullets = 3; 487 | 488 | /* HUD setup */ 489 | reset_hud_hits(); 490 | 491 | /* Dog setup */ 492 | dog_SetMode(DOG_HIDDEN); 493 | 494 | /* Setup the enemies */ 495 | DUCK_FALLEN_AMOUNT = 0; 496 | GAME_TOTAL_HITS = 0; 497 | 498 | switch (menu.option) 499 | { 500 | case 1: 501 | init_enemies(1); 502 | break; 503 | 504 | case 2: 505 | case 3: 506 | init_enemies(2); 507 | break; 508 | } 509 | } 510 | 511 | /* HUD UPDATING */ 512 | void reset_hud_hits(void) 513 | { 514 | for (int i = 0; i < 10; i++) 515 | game.duck_hits[i] = 0; 516 | } 517 | 518 | int get_hud_hits_position(void) 519 | { 520 | int tick = 0; 521 | 522 | for (int i = 0; i < 10; i++) 523 | { 524 | if (game.duck_hits[i] == DUCK_SHOT || game.duck_hits[i] == DUCK_FLYAWAY || game.duck_hits[i] == DUCK_FORCED_FLYAWAY) 525 | { 526 | tick++; 527 | } 528 | } 529 | 530 | return tick; 531 | } 532 | 533 | // New functions to help with rendering. 534 | void get_buffer_layer(void) 535 | { 536 | get_player_buffer_layer(); 537 | get_duck_buffer_layer(); 538 | 539 | if (dog.mode != DOG_HIDDEN) 540 | get_dog_buffer_layer(); 541 | } 542 | 543 | void draw_buffer_layer(void) 544 | { 545 | draw_player_buffer_layer(); 546 | draw_duck_buffer_layer(); 547 | 548 | if (dog.mode != DOG_HIDDEN) 549 | draw_dog_buffer_layer(); 550 | } -------------------------------------------------------------------------------- /src/ducks.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ducks.h" 3 | #include "ui.h" 4 | #include "utils.h" 5 | #include "dog.h" 6 | #include "menu.h" 7 | #include "player.h" 8 | #include "gfx/DUCKSPT.h" 9 | 10 | enum DUCK_ANGLE 11 | { 12 | DUCK_FALLING = 0, 13 | FACE_RIGHT = 1, 14 | FACE_LEFT = 2, 15 | FACE_UP_RIGHT = 3, 16 | FACE_UP_LEFT = 4 17 | }; 18 | 19 | struct enemies_t enemies[2]; 20 | 21 | /* Duck Animations */ 22 | static int Set_Goto_Y(void) 23 | { 24 | if (menu.option < 3) 25 | { 26 | if (randInt(0, 1)) 27 | { 28 | return 8; 29 | } 30 | else 31 | { 32 | return 167 - 35; 33 | } 34 | } 35 | else 36 | { 37 | // Game C 38 | return randInt(GAME_CANVAS_Y_MIN + 30, (GAME_CANVAS_Y_MIN + 30) + 10); 39 | } 40 | } 41 | 42 | static int Set_Goto_X(void) 43 | { 44 | if (menu.option < 3) 45 | { 46 | // Game A 47 | 48 | if (randInt(0, 1)) 49 | { 50 | return 33; 51 | } 52 | else 53 | { 54 | return 254; 55 | } 56 | } 57 | else 58 | { 59 | // Game C 60 | return randInt(GAME_CANVAS_X_MIN, GAME_CANVAS_X_MAX); 61 | } 62 | } 63 | 64 | static void enemies_manage_cnum(uint8_t pos) 65 | { 66 | int distance = get_distance(enemies[pos].x, enemies[pos].y, enemies[pos].gotoX, enemies[pos].gotoY); 67 | 68 | if (enemies[pos].cnum == 3 || enemies[pos].cnum == 6) 69 | { 70 | goto angle; 71 | } 72 | 73 | /* Check and updates constume numbers based on current costume */ 74 | switch (enemies[pos].cnum) 75 | { 76 | /* Duck A's happen here */ 77 | case 1: // If Costume is 1 change it at the right time to 2 78 | enemies[pos].cnum = 2; 79 | break; 80 | 81 | case 2: // If Costume is 2 change it at the right time to 3 82 | enemies[pos].cnum = 3; 83 | break; 84 | 85 | case 3: // If Costume is 3 change to 1 and update angle 86 | enemies[pos].cnum = 1; 87 | break; 88 | 89 | /* Duck B's happen here */ 90 | case 4: // If Costume is 4 change it at the right time to 5 91 | enemies[pos].cnum = 5; 92 | break; 93 | 94 | case 5: // If Costume is 5 change it at the right time to 6 95 | enemies[pos].cnum = 6; 96 | break; 97 | 98 | case 6: // If Costume is 6 change to 4 and update angle 99 | enemies[pos].cnum = 4; 100 | break; 101 | 102 | /* Duck Shot */ 103 | case 7: // If Costume is 7 (Shot) then wait 10 milsec and change to 8 104 | enemies[pos].cnum = 8; 105 | break; 106 | 107 | /* Duck Falling */ 108 | case 8: // If Costume is 8 change it at the right time to 9 109 | enemies[pos].cnum = 9; 110 | break; 111 | 112 | case 9: // If Costume is 9 change it at the right time to 8 113 | enemies[pos].cnum = 8; 114 | break; 115 | 116 | /* Duck Flying Away */ 117 | case 10: // If Costume is 10 change it at the right time to 11 118 | enemies[pos].cnum = 11; 119 | break; 120 | case 11: // If Costume is 11 change it at the right time to 12 121 | enemies[pos].cnum = 12; 122 | break; 123 | case 12: // If Costume is 12 change it at the right time to 10 124 | enemies[pos].cnum = 10; 125 | break; 126 | 127 | case 13: 128 | if (distance < 50) 129 | enemies[pos].cnum = 14; 130 | break; 131 | 132 | case 14: 133 | if (distance < 30) 134 | enemies[pos].cnum = 15; 135 | break; 136 | 137 | /* case 15: 138 | // This case is not need but here for visuals 139 | if (distance < 10) 140 | enemies[pos].cnum = 13; 141 | break; */ 142 | } 143 | 144 | return; 145 | 146 | angle: 147 | /* Checks if duck is moving left or right */ 148 | if (enemies[pos].angle == FACE_RIGHT || enemies[pos].angle == FACE_LEFT) 149 | { 150 | enemies[pos].cnum = 1; 151 | return; 152 | } 153 | 154 | /* Checks if duck is move up or down */ 155 | if (enemies[pos].angle == FACE_UP_RIGHT || enemies[pos].angle == FACE_UP_LEFT) 156 | { 157 | enemies[pos].cnum = 4; 158 | return; 159 | } 160 | 161 | /* Check duck was shot or is flying away */ 162 | if (enemies[pos].angle == DUCK_FALLING) 163 | { 164 | if (enemies[pos].shot) 165 | { 166 | enemies[pos].cnum = 7; // Set to shot sprite 167 | } 168 | else if (enemies[pos].fly_away) 169 | { 170 | enemies[pos].cnum = 10; // Set to Flying away sprite 171 | } 172 | 173 | return; 174 | } 175 | } 176 | 177 | /* Manages the animations of every duck */ 178 | static void enemies_render_sprites(uint8_t pos) 179 | { 180 | gfx_sprite_t *temp_buffer; 181 | gfx_sprite_t *sprite_buff = gfx_MallocSprite(40, 40); 182 | 183 | if (enemies[pos].animate >= TIMER_ANIMATE_MAX) 184 | { 185 | enemies_manage_cnum(pos); 186 | } 187 | 188 | /* Render ducks based on sprites */ 189 | switch (enemies[pos].cnum) 190 | { 191 | case 1: // Duck Spite A_1 192 | 193 | switch (enemies[pos].type) 194 | { // based on speeed 195 | case 1: 196 | temp_buffer = Duck_A_1; 197 | break; 198 | 199 | case 2: 200 | temp_buffer = Duckb_A_1; 201 | break; 202 | 203 | case 3: 204 | temp_buffer = Duckc_A_1; 205 | break; 206 | } 207 | 208 | if (enemies[pos].angle == FACE_LEFT) 209 | { 210 | gfx_TransparentSprite(gfx_FlipSpriteY(temp_buffer, sprite_buff), enemies[pos].x, enemies[pos].y); 211 | } 212 | else 213 | { 214 | gfx_TransparentSprite(temp_buffer, enemies[pos].x, enemies[pos].y); 215 | } 216 | 217 | break; 218 | 219 | case 2: // Duck Spite A_2 220 | 221 | switch (enemies[pos].type) 222 | { // based on speeed 223 | case 1: 224 | temp_buffer = Duck_A_2; 225 | break; 226 | 227 | case 2: 228 | temp_buffer = Duckb_A_2; 229 | break; 230 | 231 | case 3: 232 | temp_buffer = Duckc_A_2; 233 | break; 234 | } 235 | 236 | if (enemies[pos].angle == FACE_LEFT) 237 | { 238 | gfx_TransparentSprite(gfx_FlipSpriteY(temp_buffer, sprite_buff), enemies[pos].x, enemies[pos].y); 239 | } 240 | else 241 | { 242 | gfx_TransparentSprite(temp_buffer, enemies[pos].x, enemies[pos].y); 243 | } 244 | 245 | break; 246 | 247 | case 3: // Duck Spite A_3 248 | 249 | switch (enemies[pos].type) 250 | { // based on speeed 251 | case 1: 252 | temp_buffer = Duck_A_3; 253 | break; 254 | 255 | case 2: 256 | temp_buffer = Duckb_A_3; 257 | break; 258 | 259 | case 3: 260 | temp_buffer = Duckc_A_3; 261 | break; 262 | } 263 | 264 | if (enemies[pos].angle == FACE_LEFT) 265 | { 266 | gfx_TransparentSprite(gfx_FlipSpriteY(temp_buffer, sprite_buff), enemies[pos].x, enemies[pos].y); 267 | } 268 | else 269 | gfx_TransparentSprite(temp_buffer, enemies[pos].x, enemies[pos].y); 270 | break; 271 | 272 | case 4: // Duck Spite B_1 273 | 274 | switch (enemies[pos].type) 275 | { // based on speeed 276 | case 1: 277 | temp_buffer = Duck_B_1; 278 | break; 279 | 280 | case 2: 281 | temp_buffer = Duckb_B_1; 282 | break; 283 | 284 | case 3: 285 | temp_buffer = Duckc_B_1; 286 | break; 287 | } 288 | 289 | if (enemies[pos].angle == FACE_UP_LEFT) 290 | { 291 | gfx_TransparentSprite(gfx_FlipSpriteY(temp_buffer, sprite_buff), enemies[pos].x, enemies[pos].y); 292 | } 293 | else 294 | gfx_TransparentSprite(temp_buffer, enemies[pos].x, enemies[pos].y); 295 | break; 296 | 297 | case 5: // Duck Spite B_2 298 | 299 | switch (enemies[pos].type) 300 | { // based on speeed 301 | case 1: 302 | temp_buffer = Duck_B_2; 303 | break; 304 | 305 | case 2: 306 | temp_buffer = Duckb_B_2; 307 | break; 308 | 309 | case 3: 310 | temp_buffer = Duckc_B_2; 311 | break; 312 | } 313 | 314 | if (enemies[pos].angle == FACE_UP_LEFT) 315 | { 316 | gfx_TransparentSprite(gfx_FlipSpriteY(temp_buffer, sprite_buff), enemies[pos].x, enemies[pos].y); 317 | } 318 | else 319 | { 320 | gfx_TransparentSprite(temp_buffer, enemies[pos].x, enemies[pos].y); 321 | } 322 | 323 | break; 324 | 325 | case 6: // Duck Spite B_3 326 | 327 | switch (enemies[pos].type) 328 | { // based on speeed 329 | case 1: 330 | temp_buffer = Duck_B_3; 331 | break; 332 | 333 | case 2: 334 | temp_buffer = Duckb_B_3; 335 | break; 336 | 337 | case 3: 338 | temp_buffer = Duckc_B_3; 339 | break; 340 | } 341 | 342 | if (enemies[pos].angle == FACE_UP_LEFT) 343 | { 344 | gfx_TransparentSprite(gfx_FlipSpriteY(temp_buffer, sprite_buff), enemies[pos].x, enemies[pos].y); 345 | } 346 | else 347 | { 348 | gfx_TransparentSprite(temp_buffer, enemies[pos].x, enemies[pos].y); 349 | } 350 | 351 | break; 352 | 353 | /* Shot duck */ 354 | case 7: 355 | 356 | switch (enemies[pos].type) 357 | { // based on speeed 358 | case 1: 359 | temp_buffer = Duck_Shot; 360 | break; 361 | 362 | case 2: 363 | temp_buffer = Duckb_Shot; 364 | break; 365 | 366 | case 3: 367 | temp_buffer = Duckc_Shot; 368 | break; 369 | } 370 | 371 | gfx_TransparentSprite(temp_buffer, enemies[pos].x, enemies[pos].y); 372 | break; 373 | 374 | /* Ducks falling */ 375 | case 8: // Falling Duck 2 376 | 377 | switch (enemies[pos].type) 378 | { // based on speeed 379 | case 1: 380 | temp_buffer = Duck_Fall_2; 381 | break; 382 | 383 | case 2: 384 | temp_buffer = Duckb_Fall_2; 385 | break; 386 | 387 | case 3: 388 | temp_buffer = Duckc_Fall_2; 389 | break; 390 | } 391 | 392 | gfx_TransparentSprite(temp_buffer, enemies[pos].x, enemies[pos].y); 393 | break; 394 | 395 | case 9: // Falling Duck 1 396 | 397 | switch (enemies[pos].type) 398 | { // based on speeed 399 | case 1: 400 | temp_buffer = Duck_Fall_1; 401 | break; 402 | 403 | case 2: 404 | temp_buffer = Duckb_Fall_1; 405 | break; 406 | 407 | case 3: 408 | temp_buffer = Duckc_Fall_1; 409 | break; 410 | } 411 | 412 | gfx_TransparentSprite(temp_buffer, enemies[pos].x, enemies[pos].y); 413 | break; 414 | 415 | /* Ducks Flying away */ 416 | case 10: 417 | switch (enemies[pos].type) 418 | { // based on speeed 419 | case 1: 420 | temp_buffer = Duck_Flyaway_1; 421 | break; 422 | 423 | case 2: 424 | temp_buffer = Duckb_Flyaway_1; 425 | break; 426 | 427 | case 3: 428 | temp_buffer = Duckc_Flyaway_1; 429 | break; 430 | } 431 | 432 | gfx_TransparentSprite(temp_buffer, enemies[pos].x, enemies[pos].y); 433 | break; 434 | 435 | case 11: 436 | switch (enemies[pos].type) 437 | { // based on speeed 438 | case 1: 439 | temp_buffer = Duck_Flyaway_2; 440 | break; 441 | 442 | case 2: 443 | temp_buffer = Duckb_Flyaway_2; 444 | break; 445 | 446 | case 3: 447 | temp_buffer = Duckc_Flyaway_2; 448 | break; 449 | } 450 | 451 | gfx_TransparentSprite(temp_buffer, enemies[pos].x, enemies[pos].y); 452 | break; 453 | 454 | case 12: 455 | switch (enemies[pos].type) 456 | { // based on speeed 457 | case 1: 458 | temp_buffer = Duck_Flyaway_3; 459 | break; 460 | 461 | case 2: 462 | temp_buffer = Duckb_Flyaway_3; 463 | break; 464 | 465 | case 3: 466 | temp_buffer = Duckc_Flyaway_3; 467 | break; 468 | } 469 | 470 | gfx_TransparentSprite(temp_buffer, enemies[pos].x, enemies[pos].y); 471 | break; 472 | 473 | case 13: 474 | gfx_TransparentSprite(Clay_1, enemies[pos].x, enemies[pos].y); 475 | break; 476 | 477 | case 14: 478 | gfx_TransparentSprite(Clay_2, enemies[pos].x, enemies[pos].y); 479 | break; 480 | 481 | case 15: 482 | gfx_TransparentSprite(Clay_3, enemies[pos].x, enemies[pos].y); 483 | break; 484 | 485 | case 16: 486 | gfx_TransparentSprite(Clay_4, enemies[pos].x, enemies[pos].y); 487 | break; 488 | } 489 | 490 | free(sprite_buff); 491 | } 492 | 493 | static int get_active_enemies(void) 494 | { 495 | int tick = 0; 496 | for (int i = 0; i < DUCK_AMOUNT; i++) 497 | { 498 | if (enemies[i].active) 499 | { 500 | tick++; 501 | } 502 | } 503 | return tick; 504 | } 505 | 506 | static int get_inactive_enemies(void) 507 | { 508 | int tick = 0; 509 | for (int i = 0; i < DUCK_AMOUNT; i++) 510 | { 511 | if (!enemies[i].active) 512 | { 513 | tick++; 514 | } 515 | } 516 | return tick; 517 | } 518 | 519 | static int get_inactive_shot_enemies(void) 520 | { 521 | int tick = 0; 522 | for (int i = 0; i < DUCK_AMOUNT; i++) 523 | { 524 | if (!enemies[i].active && enemies[i].shot == true) 525 | { 526 | tick++; 527 | } 528 | } 529 | return tick; 530 | } 531 | 532 | void update_enemies(void) 533 | { 534 | uint8_t speed; 535 | 536 | /* Check for the current game mode */ 537 | if (menu.option < 3) 538 | { 539 | /* Check if the ducks are off screen*/ 540 | if (DUCK_FLYAWAY_TIMER == DUCK_FLYAWAY_MAX) 541 | { 542 | /* Force the dog into laugh mode */ 543 | if (dog.mode != DOG_LAUGH) 544 | { 545 | dog_SetMode(DOG_LAUGH); 546 | } 547 | 548 | /* Prepare to render the dog */ 549 | draw_dog_buffer_layer(); 550 | 551 | /* Update the dog until the dog mode is `DOG_HIDDEN` */ 552 | dog_Update(); 553 | 554 | if (dog.mode == DOG_HIDDEN) 555 | { 556 | DUCK_FLYAWAY_TIMER = 0; 557 | } 558 | } 559 | else 560 | { 561 | DUCK_FLYAWAY_TIMER++; 562 | } 563 | } 564 | 565 | for (int i = 0; i < DUCK_AMOUNT; i++) 566 | { 567 | if (enemies[i].active) 568 | { 569 | if (menu.option < 3) 570 | { 571 | // Game A and B 572 | 573 | /* Check if the player hasn't shot */ 574 | if (DUCK_FLYAWAY_TIMER == DUCK_FLYAWAY_MAX) 575 | { 576 | enemies[i].angle = DUCK_FALLING; 577 | enemies[i].gotoX = enemies[i].x; 578 | enemies[i].gotoY = -20; 579 | enemies[i].speed = 4; 580 | enemies[i].fly_away = true; 581 | 582 | if (enemies[i].cnum < 10) 583 | { 584 | game.duck_hits[get_hud_hits_position()] = DUCK_FORCED_FLYAWAY; 585 | enemies[i].cnum = 10; 586 | GAME_TOTAL_HITS++; 587 | } 588 | } 589 | 590 | /* If there zero bullets left */ 591 | if (!player.bullets) 592 | { 593 | /* Check if the duck is not shot */ 594 | if (!enemies[i].shot) 595 | { 596 | enemies[i].angle = DUCK_FALLING; 597 | enemies[i].gotoX = enemies[i].x; 598 | enemies[i].gotoY = -20; 599 | enemies[i].speed = 4; 600 | enemies[i].fly_away = true; 601 | 602 | /* Set the costume to 10 */ 603 | if (enemies[i].cnum < 10) 604 | { 605 | game.duck_hits[get_hud_hits_position()] = DUCK_FLYAWAY; 606 | enemies[i].cnum = 10; 607 | GAME_TOTAL_HITS++; 608 | } 609 | } 610 | } 611 | 612 | /* Checks if the X position of duck is at its dest point */ 613 | if (enemies[i].x != enemies[i].gotoX) 614 | { 615 | if (enemies[i].x < enemies[i].gotoX) 616 | { 617 | enemies[i].x += enemies[i].speed; 618 | if (enemies[i].angle != DUCK_FALLING) 619 | enemies[i].angle = FACE_RIGHT; 620 | } 621 | else if (enemies[i].x > enemies[i].gotoX) 622 | { 623 | enemies[i].x -= enemies[i].speed; 624 | if (enemies[i].angle != DUCK_FALLING) 625 | enemies[i].angle = FACE_LEFT; 626 | } 627 | 628 | /* Check if the positin is in the radius of dest point */ 629 | if (enemies[i].x - enemies[i].gotoX <= enemies[i].speed && enemies[i].x - enemies[i].gotoX >= -(enemies[i].speed)) 630 | { 631 | enemies[i].x = enemies[i].gotoX; 632 | } 633 | } 634 | else 635 | { 636 | /* if at it's destination then set a new got X */ 637 | if (enemies[i].angle != DUCK_FALLING) 638 | { 639 | enemies[i].gotoX = Set_Goto_X(); 640 | } 641 | } 642 | 643 | /* Checks if the Y position of duck is at its dest point */ 644 | if (enemies[i].y != enemies[i].gotoY) 645 | { 646 | /* Check is the y position is in radius of the destination postion */ 647 | if (enemies[i].y - enemies[i].gotoY <= enemies[i].speed && enemies[i].y - enemies[i].gotoY >= -(enemies[i].speed)) 648 | enemies[i].y = enemies[i].gotoY; 649 | 650 | /* if the duck is custom number is not on falling duck sprite */ 651 | if (enemies[i].cnum != 7) 652 | { 653 | /* Check if the Y position is below the dest Y position */ 654 | if (enemies[i].y < enemies[i].gotoY) 655 | { 656 | /* Update the Y position based on speed */ 657 | enemies[i].y += enemies[i].speed; 658 | 659 | /* Update angle if not equal to 0 or 2 */ 660 | if (enemies[i].angle != DUCK_FALLING && enemies[i].angle != FACE_LEFT) 661 | enemies[i].angle = 3; 662 | } 663 | else if (enemies[i].y > enemies[i].gotoY) // Check if the Y position is above the dest position 664 | { 665 | /* Update the Y position based on speed */ 666 | enemies[i].y -= enemies[i].speed; 667 | 668 | /* Update angle if not equal to 0 or 1 */ 669 | if (enemies[i].angle != DUCK_FALLING && enemies[i].angle != FACE_RIGHT) 670 | enemies[i].angle = 4; 671 | } 672 | } 673 | } 674 | else 675 | { 676 | /* Check if the bird is falling or flying away */ 677 | if (enemies[i].angle == DUCK_FALLING) 678 | { 679 | DUCK_FALLEN_ID = i; 680 | enemies[i].active = false; 681 | return; 682 | } 683 | else 684 | { 685 | enemies[i].gotoY = Set_Goto_Y(); 686 | } 687 | } 688 | } 689 | else 690 | { 691 | // Game C Updating 692 | /* Updating the X position */ 693 | if (enemies[i].x != enemies[i].gotoX) 694 | { 695 | speed = abs(enemies[i].gotoX - enemies[i].x) / (enemies[i].speed); 696 | 697 | if (enemies[i].x < enemies[i].gotoX) 698 | { 699 | enemies[i].x += speed; 700 | } 701 | else 702 | { 703 | enemies[i].x -= speed; 704 | } 705 | 706 | /* Check if the positin is in the radius of dest point */ 707 | if (abs(enemies[i].gotoX - enemies[i].x) <= (enemies[i].speed * 2)) 708 | { 709 | enemies[i].x = enemies[i].gotoX; 710 | } 711 | } 712 | else 713 | { 714 | } 715 | 716 | /* Updating the Y position */ 717 | if (enemies[i].y != enemies[i].gotoY) 718 | { 719 | 720 | speed = abs(enemies[i].gotoY - enemies[i].y) / (enemies[i].speed); 721 | 722 | if (enemies[i].y < enemies[i].gotoY) 723 | { 724 | enemies[i].y += speed; 725 | } 726 | else 727 | { 728 | enemies[i].y -= speed; 729 | } 730 | 731 | /* Check is the y position is in radius of the destination postion */ 732 | if (abs(enemies[i].gotoY - enemies[i].y) <= (enemies[i].speed * 2)) 733 | { 734 | enemies[i].y = enemies[i].gotoY; 735 | } 736 | } 737 | else 738 | { 739 | // Check if the duck has been shot if not drop 740 | if (enemies[i].x == enemies[i].gotoX) 741 | enemies[i].angle = DUCK_FALLING; 742 | 743 | // Change costume 744 | enemies[i].cnum = 16; 745 | 746 | enemies[i].speed = 1; 747 | 748 | // set new goto y 749 | enemies[i].gotoY = 128; 750 | } 751 | } 752 | 753 | /* Animation timer */ 754 | if (enemies[i].animate < TIMER_ANIMATE_MAX) 755 | { 756 | enemies[i].animate++; // Update the timer 757 | } 758 | else 759 | { 760 | enemies[i].animate = 0; // Reset the timer 761 | } 762 | } 763 | } 764 | 765 | /* Checks if the all ducks have fallen */ 766 | if (get_inactive_enemies() == DUCK_AMOUNT) 767 | { 768 | if (DUCK_FLYAWAY_TIMER == DUCK_FLYAWAY_MAX) 769 | { 770 | return; 771 | } 772 | 773 | if (menu.option < 3) 774 | { 775 | /* Check if player has ran through 10 ducks */ 776 | if (GAME_TOTAL_HITS > 9) 777 | { 778 | bubble_sort_hits_panel(); 779 | 780 | if (get_hud_hits_shot() >= GAME_ADVANCE_THRESHOLD) 781 | { 782 | /* Reset bullets and increase rounds */ 783 | player.bullets = 3; 784 | player.round++; 785 | 786 | /* Reset hit ducks on HUD */ 787 | reset_hud_hits(); 788 | 789 | /* Draw dog scene again */ 790 | draw_scene(); 791 | 792 | /* Init new ducks to fly */ 793 | GAME_TOTAL_HITS = 0; 794 | init_enemies(menu.option); 795 | return; 796 | } 797 | else 798 | { 799 | /* Temporary Game Over Screen */ 800 | gfx_End(); 801 | exit(1); 802 | } 803 | } 804 | 805 | if (get_inactive_shot_enemies() == DUCK_AMOUNT) 806 | { 807 | dog_SetMode(DOG_PEEK_UP); // Pop up 808 | draw_dog_scene(); 809 | } 810 | 811 | init_enemies(menu.option); 812 | } 813 | else 814 | { 815 | // GAME C 816 | 817 | /* Check if player has ran through 10 ducks */ 818 | if (GAME_TOTAL_HITS > 9) 819 | { 820 | bubble_sort_hits_panel(); 821 | 822 | if (get_hud_hits_position() >= GAME_ADVANCE_THRESHOLD) 823 | { 824 | /* Reset bullets and increase rounds */ 825 | player.bullets = 3; 826 | player.round++; 827 | 828 | /* Reset hit ducks on HUD */ 829 | reset_hud_hits(); 830 | 831 | /* Init new ducks to fly */ 832 | GAME_TOTAL_HITS = 0; 833 | init_enemies(menu.option); 834 | return; 835 | } 836 | else 837 | { 838 | /* Temporary Game Over Screen */ 839 | gfx_End(); 840 | exit(1); 841 | } 842 | } 843 | } 844 | 845 | player.bullets = 3; // Reset Bullets 846 | 847 | DUCK_FALLEN_AMOUNT = 0; // Reset Fallen Amount 848 | 849 | return; 850 | } 851 | } 852 | 853 | /* Draws every duck sprite based on its animation # */ 854 | void draw_enemies(void) 855 | { 856 | if (menu.option < 3 && DUCK_FLYAWAY_TIMER == DUCK_FLYAWAY_MAX) 857 | { 858 | if (dog.mode == DOG_LAUGH) 859 | { 860 | get_dog_buffer_layer(); 861 | dog_Render(); 862 | } 863 | } 864 | 865 | /* Draws and updates all the ducks */ 866 | for (int i = 0; i < DUCK_AMOUNT; i++) 867 | { 868 | /* Checks if the duck is active */ 869 | if (enemies[i].active) 870 | { 871 | 872 | /* Animate the duck sprites */ 873 | enemies_render_sprites(i); 874 | 875 | if (menu.option < 3) 876 | { 877 | // Game A and B 878 | /* Set the transparent color of the duck based on the player game mode (aka menu.option) */ 879 | switch (menu.option) 880 | { 881 | case 1: 882 | gfx_SetTransparentColor(4); 883 | break; 884 | 885 | case 2: 886 | gfx_SetTransparentColor(5); 887 | break; 888 | 889 | case 3: 890 | gfx_SetTransparentColor(3); 891 | break; 892 | } 893 | 894 | /* Render the grass block right after the duck */ 895 | if (enemies[i].back_buffer != NULL) 896 | gfx_TransparentSprite(enemies[i].back_buffer, enemies[i].x - 1, enemies[i].y - 1); 897 | 898 | /* reset transparent color */ 899 | gfx_SetTransparentColor(0); 900 | } 901 | else 902 | { 903 | // Game C 904 | gfx_SetColor(0); 905 | gfx_Line(enemies[i].x, enemies[i].y, enemies[i].gotoX, enemies[i].gotoY); 906 | } 907 | } 908 | } 909 | } 910 | 911 | void init_enemies(uint8_t amount) 912 | { 913 | uint8_t speed = 0; 914 | 915 | /* Set amount of shot ducks to zero */ 916 | DUCK_FALLEN_AMOUNT = 0; 917 | 918 | DUCK_AMOUNT = amount; 919 | 920 | for (int i = 0; i < DUCK_AMOUNT; i++) 921 | { 922 | /* bool to check if active and not shot */ 923 | enemies[i].active = true; 924 | 925 | enemies[i].back_buffer = NULL; 926 | 927 | if (menu.option < 3) 928 | { 929 | /* Setting duck speed */ 930 | if (player.round >= 1 && player.round <= 10) 931 | { 932 | speed = randInt(1, 3); 933 | } 934 | else if (player.round >= 11 && player.round <= 12) 935 | { 936 | speed = randInt(2, 5); 937 | } 938 | else if (player.round >= 13 && player.round <= 14) 939 | { 940 | speed = randInt(3, 6); 941 | } 942 | else if (player.round >= 15 && player.round <= 19) 943 | { 944 | speed = randInt(4, 7); 945 | } 946 | else 947 | { 948 | speed = randInt(5, 8); 949 | } 950 | 951 | enemies[i].speed = speed; 952 | 953 | // Game A and B 954 | /* Costume Number for animation */ 955 | enemies[i].cnum = 1; 956 | 957 | /* Set the base level y position */ 958 | enemies[i].y = 167; 959 | 960 | /* Setting the a random X position */ 961 | enemies[i].x = randInt(32, 254); 962 | 963 | /* Check if the random generaotated position going to go over canvas (xpos + width_of_sprite) */ 964 | if (enemies[i].x + 33 >= 287) 965 | enemies[i].x = 287 - (enemies[i].gotoX + 34); 966 | 967 | /* Randomly Set the fly position */ 968 | enemies[i].gotoX = Set_Goto_X(); 969 | enemies[i].gotoY = Set_Goto_Y(); 970 | 971 | /* Reset the if shot and flying angle */ 972 | enemies[i].shot = false; 973 | enemies[i].angle = FACE_RIGHT; // flying angle 974 | 975 | /* Sets the duck type */ 976 | enemies[i].type = randInt(1, 3); 977 | } 978 | else 979 | { 980 | /* Setting duck speed */ 981 | // if (player.round >= 1 && player.round <= 10) 982 | // { 983 | // speed = 2; 984 | // } 985 | // else if (player.round >= 11 && player.round <= 12) 986 | // { 987 | // speed = 3; 988 | // } 989 | // else if (player.round >= 13 && player.round <= 14) 990 | // { 991 | // speed = 4; 992 | // } 993 | // else if (player.round >= 15 && player.round <= 19) 994 | // { 995 | // speed = 5; 996 | // } 997 | // else 998 | // { 999 | // speed = 2; 1000 | // } 1001 | 1002 | speed = 2; 1003 | 1004 | enemies[i].speed = speed; 1005 | // Game C 1006 | enemies[i].type = 4; 1007 | 1008 | /* Costume Number for animation */ 1009 | enemies[i].cnum = 13; 1010 | 1011 | /* Set the base level y position */ 1012 | enemies[i].y = 167; 1013 | 1014 | /* Setting the a random X position */ 1015 | enemies[i].x = randInt(32, 254); 1016 | 1017 | /* Check if the random generaotated position going to go over canvas (xpos + width_of_sprite) */ 1018 | if (enemies[i].x + 16 >= GAME_CANVAS_X_MAX) 1019 | enemies[i].x = GAME_CANVAS_X_MAX - (enemies[i].gotoX + 16); 1020 | 1021 | /* Randomly Set the fly position */ 1022 | enemies[i].gotoX = Set_Goto_X(); 1023 | 1024 | enemies[i].gotoY = randInt(48, 91); 1025 | } 1026 | } 1027 | } 1028 | 1029 | void add_enemies(void) 1030 | { 1031 | uint8_t speed = 0; 1032 | 1033 | if (get_active_enemies() == DUCK_AMOUNT) 1034 | { 1035 | return; 1036 | } 1037 | 1038 | for (int i = get_active_enemies(); i < DUCK_AMOUNT; i++) 1039 | { 1040 | /* bool to check if active and not shot */ 1041 | enemies[i].active = true; 1042 | 1043 | /* Setting duck speed */ 1044 | if (player.round >= 1 && player.round <= 10) 1045 | { 1046 | speed = randInt(1, 3); 1047 | } 1048 | else if (player.round >= 11 && player.round <= 12) 1049 | { 1050 | speed = randInt(2, 5); 1051 | } 1052 | else if (player.round >= 13 && player.round <= 14) 1053 | { 1054 | speed = randInt(3, 6); 1055 | } 1056 | else if (player.round >= 15 && player.round <= 19) 1057 | { 1058 | speed = randInt(4, 7); 1059 | } 1060 | else 1061 | { 1062 | speed = randInt(5, 8); 1063 | } 1064 | 1065 | enemies[i].speed = speed; 1066 | 1067 | if (menu.option < 3) 1068 | { 1069 | // Game A and B 1070 | /* Costume Number for animation */ 1071 | enemies[i].cnum = 1; 1072 | 1073 | /* Set the base level y position */ 1074 | enemies[i].y = 167; 1075 | 1076 | /* Setting the a random X position */ 1077 | enemies[i].x = randInt(32, 254); 1078 | 1079 | /* Check if the random generaotated position going to go over canvas (xpos + width_of_sprite) */ 1080 | if (enemies[i].x + 33 >= 287) 1081 | enemies[i].x = 287 - (enemies[i].gotoX + 34); 1082 | 1083 | /* Randomly Set the fly position */ 1084 | enemies[i].gotoX = Set_Goto_X(); 1085 | enemies[i].gotoY = Set_Goto_Y(); 1086 | 1087 | /* Reset the if shot and flying angle */ 1088 | enemies[i].shot = false; 1089 | enemies[i].angle = FACE_RIGHT; // flying angle 1090 | 1091 | /* Sets the duck type */ 1092 | enemies[i].type = randInt(1, 3); 1093 | } 1094 | else 1095 | { 1096 | // Game C 1097 | /* Costume Number for animation */ 1098 | enemies[i].cnum = 13; 1099 | 1100 | /* Set the base level y position */ 1101 | enemies[i].y = 167; 1102 | 1103 | /* Setting the a random X position */ 1104 | enemies[i].x = randInt(32, 254); 1105 | 1106 | /* Check if the random generaotated position going to go over canvas (xpos + width_of_sprite) */ 1107 | if (enemies[i].x + 16 >= GAME_CANVAS_X_MAX) 1108 | enemies[i].x = GAME_CANVAS_X_MAX - (enemies[i].gotoX + 16); 1109 | 1110 | /* Randomly Set the fly position */ 1111 | enemies[i].gotoX = Set_Goto_X(); 1112 | 1113 | enemies[i].gotoY = randInt(48, 91); 1114 | } 1115 | } 1116 | } 1117 | 1118 | void get_duck_buffer_layer(void) 1119 | { 1120 | for (int i = 0; i < DUCK_AMOUNT; i++) 1121 | { 1122 | if (enemies[i].back_buffer == NULL) 1123 | { 1124 | enemies[i].back_buffer = gfx_MallocSprite(38, 38); 1125 | } 1126 | 1127 | gfx_GetSprite(enemies[i].back_buffer, enemies[i].x - 1, enemies[i].y - 1); 1128 | } 1129 | } 1130 | 1131 | void draw_duck_buffer_layer(void) 1132 | { 1133 | /* Draw the ducks */ 1134 | for (int i = 0; i < DUCK_AMOUNT; i++) 1135 | { 1136 | if (enemies[i].back_buffer != NULL) 1137 | { 1138 | gfx_TransparentSprite(enemies[i].back_buffer, enemies[i].x - 1, enemies[i].y - 1); 1139 | free(enemies[i].back_buffer); 1140 | } 1141 | 1142 | enemies[i].back_buffer = NULL; 1143 | } 1144 | } --------------------------------------------------------------------------------