My ultra simple 2D game Caventure depends on sdl-2 and sdl-ttf.
When compiled, the directory looks like
Caventure.exe
libfreetype-6.dll
notomono-regular.ttf
SDL2.dll
SDL2_ttf.dll
zlib1.dll
I'm using Microsoft Visual Studio 2015. I've been following Lazy Foo's tutorials on building with Windows and even after following the steps, it doesn't work. Here's what I've done:
- Linked the compiler to include and library directories in x64.
- Linked the libraries.
- Copied the libraries to
C:\Windows\SysWOW64
. - Included
<Windows.h>
. - Used compatibility mode.
- Tested it in the Visual Studio IDE, including with the debugger.
When I open it, it immediately closes, it doesn't return any error.
Here's the main source file:
#include <stdio.h>
#include <stdexcept>
#include <Windows.h>
#include <SDL.h>
#include <SDL_ttf.h>
#include "TextMenu.h"
#include "TextBox.h"
#include "Graphics.h"
#include "Event.h"
// Screen dimensions, constants
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
// 600 for ground, 280 for output, 20 for input
Graphics Global;
Event Loop;
void Init(Graphics& Global)
{
if (SDL_Init(SDL_INIT_VIDEO) > 0)
{
throw(::std::runtime_error("SDL failed to initialise! ERROR: "));
}
Global.Window = SDL_CreateWindow("Caventure",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
if (Global.Window == NULL)
{
throw(::std::runtime_error("Window failed to initialise! ERROR: "));
}
Global.ScreenSurface = SDL_GetWindowSurface(Global.Window);
if (Global.ScreenSurface == NULL)
{
throw(::std::runtime_error("Surface failed to initialise! ERROR: "));
}
Global.Renderer = SDL_CreateRenderer(Global.Window, -1, 0);
if (Global.Renderer == NULL)
{
throw(::std::runtime_error("Renderer could not be initialised! ERROR: "));
}
if (TTF_Init() > 0)
{
throw(::std::runtime_error("TTF could not be initialised! ERROR: "));
}
}
void UpdateMedia(Graphics& Global)
{
SDL_GetWindowSize(Global.Window, &Global.width, &Global.height);
// Set geomtry dimensions, apart from rcTextInput.
Global.rcGround = { 0, 0, Global.width, (Global.height / 3) * 2 };
Global.rcTextOutput = { 0, (Global.height / 3) * 2, Global.width, Global.height - 40 };
Global.rcTextOutputGrd = { 0, (Global.height / 3) * 2, Global.width, Global.height - 40 };
Global.SpriteDefaultX = Global.width / 2;
Global.SpriteDefaultY = Global.height / 2;
};
void LoadMedia(Graphics& Global)
{
UpdateMedia(Global);
Global.rcSprite = { Global.SpriteDefaultX, Global.SpriteDefaultY, 4, 4 };
Global.Font = TTF_OpenFont("src/graphics/resources/notomono-regular.ttf", 14);
if (Global.Font == NULL)
{
throw(::std::runtime_error("Font failed to load! ERROR: "));
}
SDL_SetTextInputRect(&Global.rcTextInput);
}
void InputLoop(Graphics& Global, Event& Loop)
{
if (Loop.event.type == SDL_QUIT)
{
Loop.bQuit = true;
}
else if (Loop.event.type == SDL_KEYDOWN)
{
// Sprite movement
switch (Loop.event.key.keysym.sym)
{
case SDLK_UP:
Global.rcSprite.y -= 5;
break;
case SDLK_DOWN:
Global.rcSprite.y += 5;
break;
case SDLK_LEFT:
Global.rcSprite.x -= 5;
break;
case SDLK_RIGHT:
Global.rcSprite.x += 5;
break;
}
// Backspace handler
if (Loop.event.key.keysym.sym == SDLK_BACKSPACE && Loop.InputText.length() > 0)
{
Loop.InputText.pop_back();
if (Loop.InputText.length() == 0)
{
Loop.InputText = " ";
}
}
// Creates new line of text
else if (Loop.event.key.keysym.sym == SDLK_RETURN && Loop.InputText.length() != 0 && Loop.InputText != " ")
{
Global.Menu.NewBox(Loop.InputText);
Loop.bRenderText = true;
Loop.InputText = " ";
}
}
else if (Loop.event.type == SDL_TEXTINPUT)
{
Loop.InputText += Loop.event.text.text;
}
}
void RenderLoop(Graphics& Global, Event& Loop)
{
UpdateMedia(Global);
// Renders sprite movement
if (Global.rcSprite.x < 0 || Global.rcSprite.y < 0 || Global.rcSprite.y > Global.rcGround.h || Global.rcSprite.x > Global.rcGround.w)
{
Global.rcSprite.x = Global.SpriteDefaultX;
Global.rcSprite.y = Global.SpriteDefaultY;
}
// Sets background to black
SDL_SetRenderDrawColor(Global.Renderer, 0x00, 0x00, 0x00, 0x00);
SDL_RenderClear(Global.Renderer);
// Renders background of sprite to black
SDL_RenderFillRect(Global.Renderer, &Global.rcGround);
SDL_BlitSurface(Global.CurrentSurface, NULL, Global.ScreenSurface, &Global.rcGround);
// Renders background of text box to grey
SDL_SetRenderDrawColor(Global.Renderer, 0x40, 0x40, 0x40, 0x40);
SDL_RenderFillRect(Global.Renderer, &Global.rcTextOutputGrd);
SDL_BlitSurface(Global.CurrentSurface, NULL, Global.ScreenSurface, &Global.rcTextOutputGrd);
SDL_SetRenderDrawColor(Global.Renderer, 0x00, 0x00, 0x00, 0x00);
// Renders text input
Global.TextInput.Render(Global.Renderer, Global.Font, Loop.InputText.c_str(), Global.TextColor);
Global.rcTextInput = { 0, Global.height - 20, Global.TextInput.GetWidth(), Global.TextInput.GetHeight() };
SDL_RenderCopy(Global.Renderer, Global.TextInput.GetTexture(), NULL, &Global.rcTextInput);
// Renders text output
if (Loop.bRenderText)
{
Global.Menu.Update(Global.Renderer, Global.Font, Global.TextColor, Global.rcTextOutput);
}
SDL_RenderSetClipRect(Global.Renderer, NULL);
// Renders text box background edges white
SDL_SetRenderDrawColor(Global.Renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderDrawLine(Global.Renderer, 0, (Global.height / 3) * 2, Global.width, (Global.height / 3) * 2);
SDL_RenderDrawLine(Global.Renderer, 0, Global.height - 20, Global.width, Global.height - 20);
// Renders sprite
SDL_RenderFillRect(Global.Renderer, &Global.rcSprite);
SDL_BlitSurface(Global.CurrentSurface, NULL, Global.ScreenSurface, &Global.rcSprite);
// Presents render
SDL_RenderPresent(Global.Renderer);
}
void Quit(Graphics& Global)
{
// Deallocate memory
SDL_DestroyWindow(Global.Window);
SDL_DestroyRenderer(Global.Renderer);
TTF_CloseFont(Global.Font);
Global.Window = NULL;
Global.Renderer = NULL;
Global.Font = NULL;
// Quit SDL subsystems
TTF_Quit();
SDL_Quit();
}
int main(int argc, char *argv[])
{
try
{
Init(Global);
LoadMedia(Global);
SDL_StartTextInput();
while (!Loop.bQuit)
{
while (SDL_PollEvent(&Loop.event) != 0)
{
InputLoop(Global, Loop);
RenderLoop(Global, Loop);
}
}
SDL_StopTextInput();
}
catch (std::runtime_error const& msg)
{
printf("%s", msg.what());
if (SDL_GetError() != NULL)
{
printf("%s", SDL_GetError());
}
else if (TTF_GetError() != NULL)
{
printf("%s", TTF_GetError());
}
else
{
printf("%s", "NULL");
}
Quit(Global);
return EXIT_FAILURE;
}
Quit(Global);
return EXIT_SUCCESS;
}