Reputation: 617
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:
C:\Windows\SysWOW64
.<Windows.h>
.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;
}
Upvotes: 0
Views: 92
Reputation: 617
I inserted SDL_Log()
after every successful initialisation to find the error. I used gdb to monitor the log.
It turned out that
Global.Font = TTF_OpenFont("src/graphics/resources/notomono-regular.ttf", 14);
was faulty.
Replacing it with a simple
Global.Font = TTF_OpenFont("notomono-regular.ttf", 14);
corrected the error.
Upvotes: 1
Reputation: 213298
When an error occurs, the program
Prints a message to the console, but there is no console, so the message goes nowhere, then
Immediately quits so that even if there were a console, it disappear in a flash.
If you want to actually report an error from a GUI Windows program, you have to wait around long enough for the user to see the error. With SDL, the SDL_ShowSimpleMessageBox is a good choice for doing that.
Upvotes: 1
Reputation: 11910
Four suggestions:
Upvotes: 1