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;
}
 
     
    