forked from mirrors/0ad
Initial revision
This was SVN commit r5.
This commit is contained in:
Executable
+164
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* input layer (dispatch events to multiple handlers; record/playback events)
|
||||
*
|
||||
* Copyright (c) 2002 Jan Wassenberg
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* Contact info:
|
||||
* Jan.Wassenberg@stud.uni-karlsruhe.de
|
||||
* http://www.stud.uni-karlsruhe.de/~urkt/
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "input.h"
|
||||
|
||||
|
||||
#define MAX_HANDLERS 4
|
||||
|
||||
static IN_HANDLER handler_stack[MAX_HANDLERS];
|
||||
static int handler_stack_top = 0;
|
||||
|
||||
|
||||
int in_add_handler(IN_HANDLER handler)
|
||||
{
|
||||
if(handler_stack_top >= MAX_HANDLERS || !handler)
|
||||
return -1;
|
||||
|
||||
handler_stack[handler_stack_top++] = handler;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* send event to each handler (newest first) until one returns true */
|
||||
static void dispatch_event(const SDL_Event& event)
|
||||
{
|
||||
for(int i = handler_stack_top-1; i >= 0; i--)
|
||||
if(handler_stack[i](event))
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static enum
|
||||
{
|
||||
INIT, /* first call to in_record() or in_playback(): register cleanup routine */
|
||||
IDLE,
|
||||
RECORD,
|
||||
PLAYBACK
|
||||
}
|
||||
state = INIT;
|
||||
|
||||
static FILE* f;
|
||||
|
||||
extern u32 game_ticks;
|
||||
|
||||
static u32 time_adjust = 0;
|
||||
static u32 next_event_time;
|
||||
|
||||
|
||||
void in_stop()
|
||||
{
|
||||
if(f)
|
||||
{
|
||||
fclose(f);
|
||||
f = 0;
|
||||
}
|
||||
|
||||
state = IDLE;
|
||||
}
|
||||
|
||||
|
||||
int in_record(const char* fn)
|
||||
{
|
||||
if(state == INIT)
|
||||
atexit(in_stop);
|
||||
|
||||
in_stop();
|
||||
|
||||
f = fopen(fn, "wb");
|
||||
if(!f)
|
||||
return -1;
|
||||
|
||||
fwrite(&game_ticks, sizeof(u32), 1, f);
|
||||
|
||||
state = RECORD;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int in_playback(const char* fn)
|
||||
{
|
||||
if(state == INIT)
|
||||
atexit(in_stop);
|
||||
|
||||
in_stop();
|
||||
|
||||
f = fopen(fn, "rb");
|
||||
if(!f)
|
||||
return -1;
|
||||
|
||||
u32 rec_start_time;
|
||||
fread(&rec_start_time, sizeof(u32), 1, f);
|
||||
time_adjust = game_ticks-rec_start_time;
|
||||
|
||||
fread(&next_event_time, sizeof(u32), 1, f);
|
||||
next_event_time += time_adjust;
|
||||
|
||||
state = PLAYBACK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void in_get_events()
|
||||
{
|
||||
SDL_Event event;
|
||||
|
||||
while(state == PLAYBACK && next_event_time <= game_ticks)
|
||||
{
|
||||
fread(&event, sizeof(SDL_Event), 1, f);
|
||||
|
||||
/*
|
||||
* do this before dispatch_event(),
|
||||
* in case a handler calls in_stop() (setting f to 0)
|
||||
*/
|
||||
if(!fread(&next_event_time, sizeof(u32), 1, f))
|
||||
{
|
||||
in_stop();
|
||||
exit(0x73c07d);
|
||||
// TODO: 'disconnect'?
|
||||
}
|
||||
next_event_time += time_adjust;
|
||||
|
||||
dispatch_event(event);
|
||||
}
|
||||
|
||||
/* get new events */
|
||||
while(SDL_PollEvent(&event))
|
||||
{
|
||||
if(state == RECORD)
|
||||
{
|
||||
fwrite(&game_ticks, sizeof(u32), 1, f);
|
||||
fwrite(&event, sizeof(SDL_Event), 1, f);
|
||||
}
|
||||
|
||||
if(state == PLAYBACK)
|
||||
if(event.type == SDL_KEYDOWN)
|
||||
in_stop();
|
||||
|
||||
dispatch_event(event);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user