polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

game.c (6682B)


      1 
      2 #include "mat_util.h"
      3 #include "game.h"
      4 #include "ply.h"
      5 #include "model.h"
      6 #include "terrain.h"
      7 #include "render.h"
      8 #include "util.h"
      9 #include "update.h"
     10 #include "entity.h"
     11 #include "texture.h"
     12 #include "stb_image.h"
     13 #include "skybox.h"
     14 #include "quickhull.h"
     15 #include "poisson.h"
     16 #include "procmesh.h"
     17 #include "util.h"
     18 
     19 #include <assert.h>
     20 
     21 mat4 *cam_init = (float[16]){
     22   0.955761, 0.228018, -0.185425, 0.000000,
     23   -0.293528, 0.779583, -0.552437, 0.000000,
     24   0.018780, 0.580299, 0.802257, 0.000000,
     25   -71.766136, -47.881512, -44.216671, 1.000000
     26 };
     27 
     28 bool was_key_pressed_this_frame(struct game *game, int scancode)
     29 {
     30     return is_key_down_on_frame(&game->input, scancode, game->frame);
     31 }
     32 
     33 bool was_button_pressed_this_frame(struct game *game, SDL_GameControllerButton button)
     34 {
     35     return is_button_down_on_frame(&game->input, button, game->frame);
     36 }
     37 
     38 static void camera_update(struct node *node) {
     39   mat4 *persp = (float*)node->custom_update_data;
     40   mat4 *mat = (float*)node->mat;
     41 
     42   mat4_inverse(mat, mat);
     43   mat4_multiply(persp, mat, mat);
     44 }
     45 
     46 struct entity *get_player(struct resources *res) {
     47     struct entity *player = get_entity(&res->player_id);
     48     assert(player);
     49     return player;
     50 }
     51 
     52 struct entity *get_terrain_entity(struct terrain *t) {
     53     struct entity *ent = get_entity(&t->entity_id);
     54     assert(ent);
     55     return ent;
     56 }
     57 
     58 
     59 static void init_user_settings(struct user_settings *settings) {
     60     SDL_SetRelativeMouseMode(SDL_TRUE);
     61     settings->mouse_sens = 0.1;
     62 }
     63 
     64 
     65 static void init_sdl(SDL_Window **window, int width, int height)
     66 {
     67     SDL_Init( SDL_INIT_JOYSTICK );
     68 
     69     /* SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); */
     70 
     71     *window = SDL_CreateWindow("SDL2/OpenGL Demo", 0, 0, width, height,
     72                                           SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
     73 
     74     SDL_GL_CreateContext(*window);
     75 }
     76 
     77 void quit_game(struct game *game)
     78 {
     79     game->quit = 1;
     80 }
     81 
     82 // TODO: cleanup
     83 void init_misc(struct game *game, int width, int height) {
     84     struct resources *res = &game->test_resources;
     85     mat4 *mvp = res->test_mvp;
     86 
     87     init_id(&res->root_id);
     88     init_id(&res->sun_camera_id);
     89     init_id(&res->free_camera_id);
     90 
     91     struct node *root = new_node(&res->root_id);
     92     struct node *sun_camera = new_node(&res->sun_camera_id);
     93 
     94     struct terrain *terrain = &game->terrain;
     95     struct entity *player;
     96 
     97     assert(root->parent_id.generation == 0);
     98     assert(root);
     99     assert(sun_camera);
    100 
    101     mat4 *light_dir = res->light_dir;
    102 
    103     game->quit = 0;
    104     game->frame = 0;
    105 
    106     const double size = 5000.0;
    107     double scale = 0.03;
    108 
    109     terrain->settings = (struct perlin_settings){
    110         .depth = 1,
    111         .freq  = scale * 0.08,
    112         .o1 = 2.0, .o1s = 0.5,
    113         .o2 = 4.0, .o2s = 0.25,
    114         .amplitude  = 70.0,
    115         .ox = 0,
    116         .oy = 0,
    117         .exp = 5.3,
    118         .scale = scale
    119     };
    120 
    121     create_ui(&game->ui, width, height, &res->programs[UI_PROGRAM]);
    122 
    123     check_gl();
    124 
    125     init_terrain(terrain, size);
    126     int seed;
    127     /* terrain->samples = load_samples(&seed, &terrain->n_samples); */
    128     terrain->n_samples = 0;
    129     create_terrain(terrain, size, game->seed);
    130     /* update_terrain(terrain, terrain->cell_size); */
    131 
    132     /* get_entity(&terrain->entity_id)->flags |= ENT_INVISIBLE; */
    133 
    134     create_skybox(&res->skybox, &res->programs[SKYBOX_PROGRAM]);
    135     /* node_translate(&res->skybox.node, V3(-100.0, -100.0, 0.0)); */
    136     /* node_scale(&res->skybox.node, size/4.0); */
    137 
    138     mat4_id(mvp);
    139 
    140     res->time = 0;
    141     res->light_intensity = 0.8;
    142 
    143     light_dir[0] = 0.8;
    144     light_dir[1] = 0.8;
    145     light_dir[2] = 0.8;
    146 
    147     res->sun_color[0] = 1.0;
    148     res->sun_color[1] = 0.9;
    149     res->sun_color[2] = 0.8;
    150 
    151     res->sun_color[0] = 0.5;
    152     res->sun_color[1] = 0.6;
    153     res->sun_color[2] = 0.7;
    154 
    155     game->test_resources.fog_on = 0;
    156     game->test_resources.diffuse_on = 0;
    157 
    158     node_init(root);
    159     node_init(sun_camera);
    160     new_orbit(&res->orbit_camera);
    161 
    162     node_set_label(root, "root");
    163 
    164     // ENTITIES
    165 
    166     // player entity
    167     init_id(&res->player_id);
    168     player = &static_entities()[entity_player];
    169     player->flags |= ENT_CASTS_SHADOWS;
    170     struct node *pnode = &static_nodes()[node_player];
    171     assert(pnode);
    172     res->player_id = make_static_id(entity_player);
    173     assert(res->player_id.index == entity_player);
    174 
    175     struct model *pmodel;
    176     player->model_id = get_static_model(model_pirate_officer, &pmodel);
    177 
    178     node_set_label(pnode, "player");
    179     /* node_rotate(pnode, V3(-5.0,0,0)); */
    180     node_attach(&player->node_id, &res->root_id);
    181     assert(ideq(&pnode->parent_id, &res->root_id));
    182 
    183     node_translate(pnode, V3(terrain->size/2.,terrain->size/2.,0.0));
    184 
    185     // orbit camera
    186     res->orbit_camera.coords.azimuth = -quat_yaw(pnode->orientation) - RAD(90.0);
    187     res->orbit_camera.coords.inclination = RAD(60);
    188     res->orbit_camera.coords.radius = 5.0;
    189     res->camera_node_id = res->orbit_camera.node_id;
    190 
    191     // free camera
    192     struct node *freecam = new_node(&res->free_camera_id);
    193     node_set_label(freecam, "freecam");
    194     node_attach(&res->free_camera_id, &player->node_id);
    195     quat_axis_angle(V3(1,0,0), -45, freecam->orientation);
    196     node_rotate(freecam, V3(100, 0, 0));
    197     node_translate(freecam, V3(0,-40,20));
    198 
    199     // FBO STUFF
    200     init_fbo(&res->shadow_buffer);
    201     resize_fbos(player, &res->shadow_buffer, res->proj_ortho, width, height);
    202     // FBO STUFF END
    203 
    204     // TEXTURES
    205     // END TEXTURES
    206 }
    207 
    208 void init_controller(struct input *input) {
    209     SDL_GameControllerAddMappingsFromFile("data/gamecontrollerdb.txt");
    210 
    211     int joysticks = SDL_NumJoysticks();
    212     SDL_GameController *controller = NULL;
    213 
    214     printf("Found %d joysticks\n", joysticks);
    215 
    216     for (int i = 0; i < joysticks; i++) {
    217         if (SDL_IsGameController(i)) {
    218             controller = SDL_GameControllerOpen(i);
    219             if (controller) {
    220                 printf("Found a game controller\n");
    221                 input->controller = controller;
    222                 break;
    223             }
    224         } else {
    225             printf("Could not open game controller %d: %s\n", i, SDL_GetError());
    226         }
    227     }
    228 }
    229 
    230 void init_resources(struct resources *res)
    231 {
    232     memset(res, 0, sizeof(*res));
    233 }
    234 
    235 void game_init(struct game *game, int width, int height) {
    236     init_resources(&game->test_resources);
    237     init_sdl(&game->window, width, height);
    238     init_gl(&game->test_resources, width, height);
    239     init_entity_system();
    240     init_geometry_manager();
    241     init_model_manager();
    242     init_node_manager();
    243     init_user_settings(&game->user_settings);
    244 
    245     check_gl();
    246 
    247     game->wireframe = 0;
    248 
    249     init_input(&game->input);
    250     init_controller(&game->input);
    251     init_misc(game, width, height);
    252 }