170 lines
3.5 KiB
C++
170 lines
3.5 KiB
C++
|
|
#include "Video.h"
|
|
#include "anaglym.h"
|
|
#include "Engine.h"
|
|
#include "SDL.h"
|
|
#include <stdlib.h> /* exit() */
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <queue>
|
|
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 lastDrawCompleted;
|
|
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 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))
|
|
{
|
|
for (;;)
|
|
{
|
|
SDL_mutexP(event_mutex);
|
|
SDL_CondWait(event_condition, event_mutex);
|
|
}
|
|
}
|
|
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();
|
|
}
|
|
|
|
lastDrawCompleted = 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 (lastDrawCompleted)
|
|
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)
|
|
{
|
|
update();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
RET:
|
|
;
|
|
}
|
|
|
|
static void update()
|
|
{
|
|
Event update_event;
|
|
update_event.type = EVENT_UPDATE;
|
|
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);
|
|
}
|