#ifndef __GAME_H__
#define __GAME_H__
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include <SDL2/SDL_mixer.h>
#include <stdbool.h>
#define MAX_AUDIOS 10
#define MAX_TEXTURES 100
#define MAX_WIDGETS_PER_LAYER 10
#define MAX_ENTITIES 128
#define MAX_TILES 64
#define MAX_BULLETS 32
#define BULLET_WIDTH 8
#define MENU_LAYER 0
#define GAME_LAYER 1
#define MOUSE_BUTTON 0
#define MOUSE_MOTION 1
#define POSITION_CENTERED -1
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
enum GameStates
{
QUIT = 0,
RUNNING = 1,
MENU = 2
};
struct Entity
{
float x, y;
float dx, dy; // Velocity
float d2x, d2y; // Acceleration
int w, h;
bool collidable;
bool mirror;
bool fixed;
bool use_src_rect;
int i, j;
SDL_Rect src_rect;
SDL_Texture *texture;
char *name;
void (*on_collision)(struct Entity *this, struct Entity *other);
};
struct Camera
{
SDL_Rect rect;
};
struct Color
{
unsigned char r, g, b;
};
struct Widget
{
bool use_src_rect;
SDL_Rect rect, src_rect;
SDL_Texture *texture;
struct Color color;
struct Color on_hover_color;
struct Color default_color;
bool is_hover;
bool is_focus;
bool is_blended;
int initial_x;
int initial_y;
void (*callback)(struct Widget *);
};
enum GunType
{
REVOLVER = 0,
RIFLE = 1,
SHOTGUN = 2
};
struct Gun
{
unsigned char type;
float angle;
unsigned char projectiles_per_shot;
bool ready;
float cooldown;
float cooldown_elapsed;
unsigned char damage;
unsigned char bullets;
unsigned char max_bullets;
Mix_Chunk *sound_effect;
};
struct PlayerKeys
{
unsigned char jump;
unsigned char left, right;
unsigned char fire, reload;
unsigned char weaponds[3];
};
struct Player
{
struct Entity entity;
unsigned char current_gun;
struct Gun guns[3];
bool facing_left;
bool on_ground;
bool reloading;
char life;
char score;
float reload_time;
char name[16];
struct PlayerKeys keys;
struct Widget *hearts[3];
struct Widget *gun;
int counter;
};
struct Bullet
{
struct Entity entity;
struct Player *owner;
struct Bullet *next;
unsigned char index;
unsigned char damage;
};
struct Layer
{
//int num_entities;
//struct Entity *entities[MAX_ENTITIES_PER_LAYER];
int num_widgets;
struct Widget widgets[MAX_WIDGETS_PER_LAYER];
};
struct Menu
{
struct Widget *play_button;
struct Widget *quit_button;
};
struct TextureContainer
{
char name[16];
SDL_Texture *texture;
};
struct Resources
{
int num_textures;
SDL_Texture *textures[MAX_TEXTURES];
int num_stored_textures;
struct TextureContainer contained_textures[MAX_TEXTURES];
int num_audios;
Mix_Chunk *audios[MAX_AUDIOS];
TTF_Font *font;
};
struct MainGame
{
SDL_Window *window;
SDL_Renderer *renderer;
int width, height;
unsigned char state;
int gravity;
int num_players;
struct Player players[2];
// 0 -> game, 1 -> menu
struct Layer layers[2];
unsigned char current_layer;
struct Resources resources;
struct Menu menu;
const Uint8 *keys;
unsigned int bullets_left;
SDL_Texture *bullet_texture;
struct Bullet *bullets[MAX_BULLETS];
int num_entities;
struct Entity *entities[MAX_ENTITIES];
int num_tiles;
struct Entity tiles[MAX_TILES];
float frame_time;
SDL_Texture *guns[3];
Mix_Chunk *revolver_sound, *rifle_sound;
struct Widget *score;
struct Camera camera;
};
extern struct MainGame *game;
/* Util */
SDL_Texture *load_texture(const char *name);
Mix_Chunk *load_sound(const char *name);
void die(const char *error, ...) __attribute__ ((noreturn));
/* GUI */
struct Widget *add_button(unsigned char layer,
const char *label,
int x, int y,
void (*callback)(struct Widget *));
struct Widget *add_image(unsigned char layer, SDL_Texture *image,
int x, int y, int w, int h);
void process_widget_events(unsigned char type, int x, int y);
void set_color(struct Widget *w, struct Color color);
void set_text(struct Widget *w, const char *text);
struct Widget *add_label(unsigned char layer,
const char *text,
struct Color color,
int x, int y);
/* Renderer */
void render_begin(void);
void render_entities(void);
void render_flush(void);
/* Bullets */
void init_bullets(void);
void shoot_bullet(struct Player *owner);
void update_bullets(void);
/* Players */
void init_player(struct Player *p, struct PlayerKeys *keys,
float x, float y, const char *name);
void update_player(struct Player *p);
void update_score(void);
/* Collisions */
void check_collisions(void);
void load_config(const char *config);
#endif