Skip to content

Instantly share code, notes, and snippets.

@Twinklebear
Created July 30, 2012 14:43
Show Gist options
  • Select an option

  • Save Twinklebear/3207441 to your computer and use it in GitHub Desktop.

Select an option

Save Twinklebear/3207441 to your computer and use it in GitHub Desktop.
#include <thread>
#include <mutex>
#include <condition_variable>
#include "SDL.h"
#include "window.h"
SDL_Texture *img = nullptr;
int x = 0, y = 0;
int xVel = 0, yVel = 0;
//For syncing the FPS delay across threads
std::condition_variable condVar;
bool quit = false;
void RenderThread(){
while (!quit){
Window::Clear();
Window::Draw(x, y, img);
Window::Flip();
//Notify that we've updated window
condVar.notify_all();
}
}
void PhysicsThread(){
std::mutex m;
while (!quit){
x += xVel;
y += yVel;
//Wait for notification
std::unique_lock<std::mutex> lock(m);
condVar.wait(lock);
}
}
int main(int argc, char** argv){
Window::Init();
img = Window::LoadTexture("player.png");
std::thread tRend(RenderThread);
std::thread tPhys(PhysicsThread);
//We can detach b/c threads read from a global exit condition
tRend.detach();
tPhys.detach();
std::mutex m2;
SDL_Event e;
while (!quit){
while (SDL_PollEvent(&e)){
if (e.type == SDL_QUIT || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE))
quit = true;
if (e.type == SDL_KEYDOWN){
switch(e.key.keysym.sym){
case SDLK_w:
yVel = -5;
break;
case SDLK_s:
yVel = 5;
break;
case SDLK_a:
xVel = -5;
break;
case SDLK_d:
xVel = 5;
break;
default:
break;
}
}
if (e.type == SDL_KEYUP){
switch(e.key.keysym.sym){
case SDLK_w:
yVel = 0;
break;
case SDLK_s:
yVel = 0;
break;
case SDLK_a:
xVel = 0;
break;
case SDLK_d:
xVel = 0;
break;
default:
break;
}
}
}
std::unique_lock<std::mutex> lock(m2);
condVar.wait(lock);
}
Window::Quit();
return 0;
}
#include <string>
#include <stdexcept>
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
#include "window.h"
SDL_Window* Window::mWindow;
SDL_Renderer* Window::mRenderer;
SDL_Rect Window::mBox;
int Window::SCREEN_WIDTH;
int Window::SCREEN_HEIGHT;
void Window::Init(std::string title){
//initialize all SDL subsystems
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
throw std::runtime_error("SDL Init Failed");
if (TTF_Init() == -1)
throw std::runtime_error("TTF Init Failed");
//Start up window
SCREEN_WIDTH = 1280;
SCREEN_HEIGHT = 720;
mWindow = nullptr;
mWindow = SDL_CreateWindow(title.c_str(), 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
if (mWindow == nullptr)
throw std::runtime_error("Failed to open window");
//Start up the renderer
mRenderer = nullptr;
mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (mRenderer == nullptr)
throw std::runtime_error("Failed to start renderer");
//initialize the window box
mBox.x = 0;
mBox.y = 0;
mBox.w = SCREEN_WIDTH;
mBox.h = SCREEN_HEIGHT;
}
void Window::Quit(){
SDL_DestroyRenderer(mRenderer);
SDL_DestroyWindow(mWindow);
TTF_Quit();
SDL_Quit();
}
void Window::Draw(int x, int y, SDL_Texture *tex, SDL_Rect *clip){
SDL_Rect dstRect;
dstRect.x = x;
dstRect.y = y;
//Query the texture width and height
SDL_QueryTexture(tex, NULL, NULL, &dstRect.w, &dstRect.h);
//Draw the texture
SDL_RenderCopy(mRenderer, tex, clip, &dstRect);
}
SDL_Texture* Window::LoadTexture(std::string file){
SDL_Texture* tex = nullptr;
tex = IMG_LoadTexture(mRenderer, file.c_str());
if (tex == nullptr)
throw std::runtime_error("Failed to load image: " + file);
return tex;
}
void Window::Clear(){
SDL_RenderClear(mRenderer);
}
void Window::Flip(){
SDL_RenderPresent(mRenderer);
}
void Window::HandleEvents(SDL_Event &e){
}
SDL_Rect Window::Box(){
//Update the box to match the current window w/h
SDL_GetWindowSize(mWindow, &mBox.w, &mBox.h);
return mBox;
}
#include <string>
#include <stdexcept>
#include "SDL.h"
/*
* Window management class, provides a simple wrapper around
* the SDL_Window and SDL_Renderer functionalities
*/
class Window{
public:
/*
* Initialize SDL, setup the window and renderer
* @param title: the window title
*/
static void Init(std::string title = "Window");
/*
* Quit SDL and destroy the window and renderer
*/
static void Quit();
/*
* Draw a texture to the screen, with no scaling applied
* @param x: The x coordinate to draw too
* @param y: The y coordinate to draw too
* @param tex: The SDL_Texture* to draw
* @param clip: The clip rect to apply to the texture, if desired
*/
static void Draw(int x, int y, SDL_Texture *tex, SDL_Rect *clip = NULL);
/*
* Load an image file into an SDL_Texture and return it
* @param file: the image file to load
* @return SDL_Texture* of the texture loaded
*/
static SDL_Texture* LoadTexture(std::string file);
/*
* Clear the renderer
*/
static void Clear();
/*
* Render the renderer to window
*/
static void Flip();
/*
* Handle window events
*/
static void HandleEvents(SDL_Event &e);
/*
* Return the window box
*/
static SDL_Rect Box();
private:
static SDL_Window *mWindow;
static SDL_Renderer *mRenderer;
//TODO: Replace with Rect<int>
static SDL_Rect mBox;
static int SCREEN_WIDTH;
static int SCREEN_HEIGHT;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment