anaglym/anaglym.cc
Josh Holtrop e7d5e6eed1 supposed to be swapping buffers now but only getting a black screen... not a good sign
git-svn-id: svn://anubis/anaglym/trunk@82 99a6e188-d820-4881-8870-2d33a10e2619
2009-10-14 02:44:45 +00:00

213 lines
5.0 KiB
C++

#include "Video.h"
#include "anaglym.h"
#include "Engine.h"
#include "SDL.h"
#include <stdlib.h> /* exit() */
#include <iostream>
#include <string>
#include <queue>
#include <GL/gl.h>
#include <GL/glu.h>
using namespace std;
enum EventType { EVENT_UPDATE };
typedef struct
{
EventType type;
} Event;
static void usage();
static void mainloop();
static void update();
static void addEvent(const Event & event);
static Uint32 updateCallback(Uint32 interval, void * param);
static bool lastUpdateCompleted;
static bool engine_running;
static SDL_Event userEvent;
static SDL_cond * event_condition;
static SDL_mutex * event_mutex;
static SDL_mutex * event_queue_mutex;
static SDL_mutex * engine_thread_ready_mutex;
static queue<Event> event_queue;
Uint32 g_ticks;
static void usage()
{
cerr << "Usage: anaglym [options] program.lua[c]" << endl;
exit(42);
}
static int engine_thread(void * param)
{
const char * program = (const char *) param;
if (g_engine->load(program))
{
SDL_mutexV(engine_thread_ready_mutex);
for (;;)
{
Event event;
bool moreEvents = false;
SDL_mutexP(event_queue_mutex);
if (event_queue.size() > 0)
moreEvents = true;
SDL_mutexV(event_queue_mutex);
if (!moreEvents)
{
/* wait for an event to be ready */
SDL_mutexP(event_mutex);
SDL_CondWait(event_condition, event_mutex);
}
moreEvents = true;
while (moreEvents)
{
SDL_mutexP(event_queue_mutex);
if (event_queue.size() < 1)
moreEvents = false;
else
{
event = event_queue.front();
event_queue.pop();
}
SDL_mutexV(event_queue_mutex);
if (moreEvents)
{
/* process the event */
switch (event.type)
{
case EVENT_UPDATE:
g_engine->update();
GLUquadric * quad = gluNewQuadric();
gluSphere(quad, 4.0, 16, 8);
lastUpdateCompleted = true;
break;
}
}
}
}
}
engine_running = false;
return 0;
}
int main(int argc, char * argv[])
{
const char * program = NULL;
for (int i = 1; i < argc; i++)
{
if (argv[i][0] != '-')
{
if (program == NULL)
{
program = argv[i];
}
else
{
cerr << "Warning: argument " << argv[i] << " ignored!" << endl;
usage();
}
}
else
{
cerr << "Warning: Unrecognized option '" << argv[i]+1
<< "'" << endl;
usage();
}
}
if (program == NULL)
{
usage();
}
lastUpdateCompleted = true;
engine_running = true;
/* setup SDL update event */
userEvent.type = SDL_USEREVENT;
userEvent.user.code = 0;
event_condition = SDL_CreateCond();
event_mutex = SDL_CreateMutex();
event_queue_mutex = SDL_CreateMutex();
Video video;
#if 0
/* start in windowed mode for debugging */
video.start(0, 0, false, false);
#else
video.start();
#endif
g_engine = new Engine(argv[0]);
SDL_CreateThread(engine_thread, (void *) program);
mainloop();
SDL_DestroyCond(event_condition);
delete g_engine;
video.stop();
return 0;
}
/* called by SDL when the update timer expires */
static Uint32 updateCallback(Uint32 interval, void * param)
{
if (lastUpdateCompleted)
SDL_PushEvent(&userEvent);
return interval;
}
static void mainloop()
{
SDL_Event event;
/* register a screen redrawing SDL event */
SDL_AddTimer(25, &updateCallback, NULL);
while (SDL_WaitEvent(&event))
{
if (!engine_running)
goto RET;
switch (event.type)
{
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
{
goto RET;
}
break;
case SDL_QUIT:
goto RET;
break;
case SDL_USEREVENT:
if (event.user.code == 0)
{
if (lastUpdateCompleted)
SDL_GL_SwapBuffers();
update();
}
break;
}
}
RET:
;
}
static void update()
{
Event update_event;
update_event.type = EVENT_UPDATE;
lastUpdateCompleted = false;
addEvent(update_event);
}
static void addEvent(const Event & event)
{
SDL_mutexP(event_queue_mutex);
event_queue.push(event);
SDL_mutexV(event_queue_mutex);
SDL_CondSignal(event_condition);
}