Tuesday, October 7, 2008

SDL Window

I got SDL 1.3 to fully initialisize a window - without and use of 1.2-commands of course!
There's one problem though: The renderer seems to somehow get screwed when you user minimizes the window and then opens it again... I haven't found a decent solution yet.

If you want more information about the SDL-functions, justlook at the declaration - there's a big block of comment to tell you what it's for and how to use it.

Anyways, so far it's easy:
First, initialisize the video sub-system:
SDL_VideoInit(NULL, 0)
If the first argument is NULL then the default video driver is choosen; the second argument defines the flags to initialisize with. The only flag useable here is SDL_INIT_EVENTTHREAD, which puts the events into an own thread - but that's not supported by some OSs. If you try to initialisize with this flag, but the OS does not support it, SDL will throw an error and exit. On OSs where you have to have the events an an own thread, it's set automatically. As I use Win32 it's 0, because Windows does not support that.
To check if it is available on your platform (in the code) you can use CANT_THREAD_EVENTS in SDL_sysevents.h. So if you prefer threaded events, but also want platform independence, you just use that.

Now that we have initialisized the video sub-system, let's create a window:
mainWnd = SDL_CreateWindow("Title", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN);
The only two things worthy to mentoin here are, that SDL_WINDOW_SHOWN will automatically raise the window, and mainWnd is a variable of the type SDL_WindowID.
mainWnd will be useful if you want to do something with your created window, such as

creating a renderer:
SDL_CreateRenderer(mainWnd, -1, SDL_RENDERER_PRESENTFLIP2|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_ACCELERATED)
This -1 there picks the first driver which can handle the flags given.
The ones I gave are for having a double buffered renderer which has vertical synchonisazion and is hardware accelerated.

For now I just filled it with one color. To do that you need to select the renderer of the window first:
SDL_SelectRenderer(mainWnd)
The renderer is stored internally, so you don't need some variable to save that.

Then you can draw in it, e.g. filling the window with one color:
SDL_RenderFill(0x22, 0x22, 0xFF, SDL_ALPHA_OPAQUE, NULL)
The NULL-argument shoud be a pointer to a SDL_Rect; if it's NULL then the whole plane will be filled with the given color.

So, you will need an event-handler, which is as simple as in SDL.
So, here's my main-code, a little bit beautified:

#include "libbase.h"

#include
#include

#include "SDL.h"
#include "SDL_video.h"

using ::std::cerr;
using ::std::clog;
using ::std::endl;

static SDL_WindowID mainWnd;

static void initSDL(const Uint32& flags = 0);
static void quit(const int& exitVal);
static void render(void);
static void createWindow(void);
inline static void error(const string_t& msg = _T(""), const int& exitVal = ERROR);

int main(int, char**) {
bool done = false;
SDL_Event event;
Uint32 mainWndFlags;

initSDL(); //SDL_INIT_EVENTTHREAD
createWindow();

while (!done) {
/*if(SDL_WaitEvent(&event) == 0) {
clog <<>
continue;
}*/
while(SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYUP:
switch(event.key.keysym.sym) {
case SDLK_ESCAPE:
SDL_Event quit;
quit.type = SDL_QUIT;
SDL_PushEvent(&quit);
break;

default:
break;
}
break;

case SDL_WINDOWEVENT:
switch(event.window.event) {
case SDL_WINDOWEVENT_CLOSE:
SDL_Event quit;
quit.type = SDL_QUIT;
SDL_PushEvent(&quit);
break;

case SDL_WINDOWEVENT_EXPOSED:
render();

default:
break;
}
break;

case SDL_QUIT:
done = true;
break;

default:
break;
}
}
mainWndFlags = SDL_GetWindowFlags(mainWnd);
if(!(mainWndFlags & SDL_WINDOW_INPUT_FOCUS))
SDL_Delay(200);
}
quit(NORMAL);
#if defined(_DEBUG)
return 0;
#endif
}

void quit(const int& exitVal) {
if(mainWnd)
SDL_DestroyWindow(mainWnd);

clog <<>

SDL_Quit();
exit(exitVal);
}

static void initSDL(const Uint32& flags) {
//if(SDL_Init(flags) <>
// error(_T("Unable to init SDL: "));
if(SDL_VideoInit(NULL, flags) <>
error(_T("Unable to init video"));
}

static void createWindow(void) {
/*
Uint32 bpp = SDL_VideoModeOK(800, 600, 32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_HWACCEL); //SDL_RESIZABLE; SDL_HWACCEL; SDL_PREALLOC
if(!bpp)
error(_T("Mode not available"));
else if(bpp != 32)
cerr <<>
*/

/*
SDL_DisplayMode mode;
mode.format = 32;
mode.h = 800;
mode.w = 600;
*/
//if (SDL_SetDisplayMode(NULL) <>
// error(_T("Couldn't set display mode: "));

mainWnd = SDL_CreateWindow("hi!", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN); //SDL_WINDOW_FULLSCREEN
if(!mainWnd)
error(_T("Could not create window"));
if(SDL_CreateRenderer(mainWnd, -1, SDL_RENDERER_PRESENTFLIP2|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_ACCELERATED) <>
error(_T("Could not create renderer"));

    if(SDL_SelectRenderer(mainWnd)<0)
error(_T("Could not select main-renderer"));
}

static void render(void) {
    if(SDL_RenderFill(0xFF, 0x22, 0xFF, SDL_ALPHA_OPAQUE, NULL)<0)
error(_T("Could not draw in main-renderer"));

SDL_RenderPresent();
}

static void error(const std::string& msg, const int& exitVal) {
std::string err(SDL_GetError());

cerr <<>

if(err.empty()) {
cerr <<>
quit(FATAL);
} else
cerr <<>

quit(exitVal);
}

I used some stuff defined in libbase.h; I think you can imagine what. I know the streams are not made for _T yet. And the codingstyle is not final at all; it's just something right now, close to what I normally use (for private code). I need to discuss with Ionenbombe how we will format our code.

EDIT: Blogger fucked of the formatation somehow. I wanted to give the code a different font... oh well, you have to live with that. It also fucked with the streaming-operators.. no big deal though.

Sunday, October 5, 2008

SDL 1.3 (SVN)

About three month ago I downloaded the newest version of SDL - not 1.2.* but the newest subversion.
I wasn't so happy about hearing that they gave up on SDL 2 but instead were implementing the features to 1.2. Well, what shall one do; at least they are still caring about it, since it is their sparetime.

I searched for a tutorial or atleast a documentation, but there was none. 1.3 has a backwards compatiblity to 1.2.* through SDL_compat.c, but I want to do it the clean way.
So I searched around the library untill I got a OpenGL backedned window opened.
But I didn't code any further, because of the drawback on OpenGL 3. I dropped the thing until now:
I decided to make a little engine (probably just for learning-purposes) with DirectX. While searching for tutorials I found a piece of code which allowed you to use SDL with DirectX. So what I'm (hopefully) gonna do, is write an interface so you can use both, OpenGL and DirectX.

But there still is no decent documentation or tutorial for SDL 1.3, so I'm going to look further into the library and experiment with my code untill I got stuff working as they should. As I don't have any other site to report my progress and code (yes, I'll tell you how to do stuff if I can find it out), I'll just blog about it.
Maybe I'm gonna get a GameDev-account. I don't know yet - at first I'm going to hack my way through SDL 1.3 again.

Stay tuned for updates on SDL 1.3 as well as for information about my engine. I'm thinking about OpenSourceing it.