Advertisement
microwerx

Engine Template #1

Apr 29th, 2023
793
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.71 KB | Source Code | 0 0
  1. /**
  2.  * Copyright (c) 2023 Jonathan Metzgar
  3.  *
  4.  * This software is released under the MIT License.
  5.  * https://opensource.org/licenses/MIT
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <memory.h>
  11. #include <string.h>
  12. #include <stdint.h>
  13. #include <stdbool.h>
  14.  
  15. #include "object.h"
  16.  
  17. #define SDL_MAIN_HANDLED
  18. #include <SDL2/SDL.h>
  19. #include <SDL2/SDL_opengl.h>
  20.  
  21. void LogSDLError()
  22. {
  23.     fprintf(stderr, "Error: %s\n", SDL_GetError());
  24. }
  25.  
  26. /////// Game Engine //////
  27.  
  28. typedef struct GameEngine
  29. {
  30.     Object_t self;
  31.     SDL_Window *window;
  32.     int frameCount;
  33.     double previousTime;
  34.     double currentTime;
  35.     double deltaTime;
  36.     int width;
  37.     int height;
  38.     bool finished;
  39. } GameEngine;
  40.  
  41. typedef GameEngine *GameEnginePtr;
  42.  
  43. GameEnginePtr CreateGameEngine()
  44. {
  45.     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
  46.     {
  47.         LogSDLError();
  48.         return NULL;
  49.     }
  50.  
  51.     const int windowWidth = 1280;
  52.     const int windowHeight = 720;
  53.  
  54.     // Tell SDL2 to make a window with an OpenGL context.
  55.     SDL_WindowFlags windowFlags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
  56.     SDL_Window *window = SDL_CreateWindow("Game Engine",
  57.                                           SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
  58.                                           windowWidth, windowHeight, windowFlags);
  59.     if (window == NULL)
  60.     {
  61.         LogSDLError();
  62.         return NULL;
  63.     }
  64.  
  65.     // Tell SDL2 what to have in the OpenGL context.
  66.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
  67.     // SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
  68.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
  69.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
  70.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
  71.     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  72.     SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
  73.     SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
  74.  
  75.     SDL_GLContext glContext = SDL_GL_CreateContext(window);
  76.     if (glContext == NULL)
  77.     {
  78.         LogSDLError();
  79.         return NULL;
  80.     }
  81.  
  82.     // Enable vsync on the display.
  83.     SDL_GL_SetSwapInterval(1);
  84.     SDL_GL_MakeCurrent(window, glContext);
  85.  
  86.     GameEnginePtr engine = (GameEnginePtr)allocObject(sizeof(GameEngine));
  87.  
  88.     engine->window = window;
  89.     engine->width = windowWidth;
  90.     engine->height = windowHeight;
  91.     engine->currentTime = SDL_GetTicks64() / 1000.0;
  92.  
  93.     return engine;
  94. }
  95.  
  96. void EngineStartFrame(GameEnginePtr engine)
  97. {
  98.     engine->previousTime = engine->currentTime;
  99.     engine->currentTime = SDL_GetTicks64() / 1000.0;
  100.     engine->deltaTime = engine->currentTime - engine->previousTime;
  101.     engine->frameCount++;
  102. }
  103.  
  104. void EnginePollEvents(GameEnginePtr engine)
  105. {
  106.     // Process all events for the current frame.
  107.     SDL_Event e;
  108.     while (SDL_PollEvent(&e))
  109.     {
  110.         if (e.type == SDL_KEYDOWN)
  111.         {
  112.             if (e.key.keysym.sym == SDLK_ESCAPE)
  113.                 engine->finished = true;
  114.         }
  115.  
  116.         else if (e.type == SDL_WINDOWEVENT)
  117.         {
  118.             if (e.window.event == SDL_WINDOWEVENT_RESIZED)
  119.             {
  120.                 engine->width = e.window.data1;
  121.                 engine->height = e.window.data2;
  122.             }
  123.         }
  124.  
  125.         else if (e.type == SDL_QUIT)
  126.         {
  127.             engine->finished = true;
  128.         }
  129.  
  130.         else
  131.         {
  132.             // This is an unhandled event.
  133.         }
  134.     }
  135. }
  136.  
  137. void EngineTick(GameEnginePtr engine)
  138. {
  139. }
  140.  
  141. void EngineDraw(GameEnginePtr engine)
  142. {
  143.     // Set up OpenGL drawing commands.
  144.     glViewport(0, 0, engine->width, engine->height);
  145.  
  146.     double s = sin(engine->currentTime) * 0.5 + 0.5;
  147.     glClearColor(0.1, s, 0.3, 1.0);
  148.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  149.  
  150.     glMatrixMode(GL_PROJECTION);
  151.     glLoadIdentity();
  152.     glMatrixMode(GL_MODELVIEW);
  153.     glLoadIdentity();
  154.  
  155.     glBegin(GL_TRIANGLES);
  156.     glVertex2f(-0.5f, -0.5f);
  157.     glVertex2f(0.5f, -0.5f);
  158.     glVertex2f(0.0f, 0.5f);
  159.     glEnd();
  160. }
  161.  
  162. void EngineEndFrame(GameEnginePtr engine)
  163. {
  164.     SDL_GL_SwapWindow(engine->window);
  165. }
  166.  
  167. int main(int argc, char **argv)
  168. {
  169.     GameEnginePtr engine = CreateGameEngine();
  170.     if (engine == NULL)
  171.     {
  172.         return -1;
  173.     }
  174.  
  175.     // Start the game loop.
  176.     while (!engine->finished)
  177.     {
  178.         EngineStartFrame(engine);
  179.         EnginePollEvents(engine);
  180.  
  181.         // Leave the loop if we're done.
  182.         if (engine->finished)
  183.             break;
  184.  
  185.         EngineTick(engine);
  186.         EngineDraw(engine);
  187.         EngineEndFrame(engine);
  188.     }
  189.  
  190.     releaseObject((ObjectPtr)engine);
  191.     return 0;
  192. }
  193.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement