move source files to "src" subdirectory
This commit is contained in:
1 parent
0579235c93
commit
cd1e26318a
14 files changed
+3
-7
No files matched your search
@@ -0,0 +1,369 @@
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL_sound.h>
|
||||
#include <math.h>
|
||||
#include <limits.h> /* INT_MAX */
|
||||
#include <stdint.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "AV.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define SOUND_RATE 44100
|
||||
#define CALLBACK_SAMPLES 4096
|
||||
#define CHANNELS 2
|
||||
#define BYTES_PER_SAMPLE 2
|
||||
#if AV_SOUND_FORMAT == AUDIO_S16SYS
|
||||
# define SAMPLE_MIN SHRT_MIN
|
||||
# define SAMPLE_MAX SHRT_MAX
|
||||
#elif AV_SOUND_FORMAT == AUDIO_U16SYS
|
||||
# define SAMPLE_MIN 0
|
||||
# define SAMPLE_MAX USHRT_MAX
|
||||
#else
|
||||
# error Unknown AV_SOUND_FORMAT
|
||||
#endif
|
||||
|
||||
void AV_sound_callback(void * userdata, Uint8 * stream, int len)
|
||||
{
|
||||
((AV *)userdata)->playCallback(stream, len);
|
||||
}
|
||||
|
||||
AV::AV()
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))
|
||||
{
|
||||
cerr << "SDL_Init() returned error!" << endl;
|
||||
exit(3);
|
||||
}
|
||||
|
||||
const SDL_VideoInfo * vidInfo = SDL_GetVideoInfo();
|
||||
if (vidInfo != NULL)
|
||||
{
|
||||
m_defaultWidth = vidInfo->current_w;
|
||||
m_defaultHeight = vidInfo->current_h;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Warning: SDL_GetVideoInfo() returned NULL!" << endl;
|
||||
m_defaultWidth = 1024;
|
||||
m_defaultHeight = 768;
|
||||
}
|
||||
|
||||
m_surface = NULL;
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
|
||||
Sound_Init();
|
||||
SDL_AudioSpec desired;
|
||||
desired.freq = SOUND_RATE;
|
||||
desired.format = AUDIO_S16SYS;
|
||||
desired.channels = CHANNELS;
|
||||
desired.samples = CALLBACK_SAMPLES;
|
||||
desired.callback = AV_sound_callback;
|
||||
desired.userdata = this;
|
||||
desired.silence = 0;
|
||||
if (SDL_OpenAudio(&desired, NULL) < 0)
|
||||
{
|
||||
cerr << "SDL_OpenAudio() error." << endl;
|
||||
exit(3);
|
||||
}
|
||||
m_sound_buffer = new sample_t[CALLBACK_SAMPLES * CHANNELS];
|
||||
|
||||
m_active_sounds_mutex = SDL_CreateMutex();
|
||||
}
|
||||
|
||||
AV::~AV()
|
||||
{
|
||||
SDL_PauseAudio(1);
|
||||
SDL_DestroyMutex(m_active_sounds_mutex);
|
||||
SDL_CloseAudio();
|
||||
Sound_Quit();
|
||||
SDL_Quit();
|
||||
delete[] m_sound_buffer;
|
||||
}
|
||||
|
||||
bool AV::start(int width, int height, bool fullscreen, bool grab_input,
|
||||
int samples)
|
||||
{
|
||||
if (m_surface == NULL)
|
||||
{
|
||||
if (width == 0)
|
||||
width = m_defaultWidth;
|
||||
if (height == 0)
|
||||
height = m_defaultHeight;
|
||||
int flags = SDL_HWSURFACE | SDL_OPENGL;
|
||||
if (fullscreen)
|
||||
flags |= SDL_FULLSCREEN;
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
if (samples > 1)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples);
|
||||
}
|
||||
m_surface = SDL_SetVideoMode(width, height, 32, flags);
|
||||
if (m_surface == NULL)
|
||||
{
|
||||
if (samples > 1)
|
||||
{
|
||||
cerr << "Error setting video mode, trying again without multisampling" << endl;
|
||||
/* failed to set SDL video mode with multisampling, try without */
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
||||
m_surface = SDL_SetVideoMode(width, height, 32, flags);
|
||||
if (m_surface != NULL)
|
||||
{
|
||||
cerr << "Successfully set video mode without multisampling" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_surface == NULL)
|
||||
{
|
||||
cerr << "Error setting SDL video mode." << endl;
|
||||
cerr << "Parameters:" << endl;
|
||||
cerr << " width = " << width << endl;
|
||||
cerr << " height = " << height << endl;
|
||||
cerr << " fullscreen = " << fullscreen << endl;
|
||||
cerr << " input grab = " << grab_input << endl;
|
||||
return false;
|
||||
}
|
||||
if (grab_input)
|
||||
{
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
SDL_WM_GrabInput(SDL_GRAB_ON);
|
||||
}
|
||||
SDL_WM_SetCaption("Anaglym", "Anaglym");
|
||||
m_fullscreen = fullscreen;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60.0, (double) width / (double) height, 0.01, 10000.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AV::stop()
|
||||
{
|
||||
if (m_surface != NULL)
|
||||
{
|
||||
SDL_FreeSurface(m_surface);
|
||||
m_surface = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
refptr<AV::Sound> AV::createSound()
|
||||
{
|
||||
refptr<Sound> s = new Sound(*this);
|
||||
#if 0
|
||||
m_sounds.insert(s);
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
void AV::playSound(AV::Sound * s)
|
||||
{
|
||||
SDL_mutexP(m_active_sounds_mutex);
|
||||
m_active_sounds.insert(s);
|
||||
SDL_mutexV(m_active_sounds_mutex);
|
||||
SDL_PauseAudio(0);
|
||||
}
|
||||
|
||||
void AV::stopSound(AV::Sound * s)
|
||||
{
|
||||
SDL_mutexP(m_active_sounds_mutex);
|
||||
m_active_sounds.erase(s);
|
||||
int sz = m_active_sounds.size();
|
||||
SDL_mutexV(m_active_sounds_mutex);
|
||||
if (sz == 0)
|
||||
{
|
||||
SDL_PauseAudio(1);
|
||||
}
|
||||
}
|
||||
|
||||
void AV::playCallback(Uint8 * stream, int len)
|
||||
{
|
||||
sample_t * stream16 = (sample_t *) stream;
|
||||
memset(stream, 0, len);
|
||||
SDL_mutexP(m_active_sounds_mutex);
|
||||
#ifdef DEBUG
|
||||
if (len > CALLBACK_SAMPLES * CHANNELS * BYTES_PER_SAMPLE)
|
||||
{
|
||||
cerr << "anaglym bug: callback buffer length = " << len
|
||||
<< ", sound buffer size = "
|
||||
<< CALLBACK_SAMPLES * CHANNELS * BYTES_PER_SAMPLE << endl;
|
||||
exit(38);
|
||||
}
|
||||
#endif
|
||||
for (std::set<Sound *>::iterator it = m_active_sounds.begin();
|
||||
it != m_active_sounds.end();
|
||||
it++)
|
||||
{
|
||||
int bytes_decoded = (*it)->decode((Uint8 *)m_sound_buffer, len);
|
||||
if (bytes_decoded == 0)
|
||||
{
|
||||
m_active_sounds.erase(it);
|
||||
}
|
||||
float volume = (*it)->getVolume();
|
||||
for (int i = 0, samples_decoded = bytes_decoded / BYTES_PER_SAMPLE;
|
||||
i < samples_decoded;
|
||||
i++)
|
||||
{
|
||||
int sample_val = stream16[i] + (int)(volume * m_sound_buffer[i]);
|
||||
stream16[i] = min(SAMPLE_MAX, max(SAMPLE_MIN, sample_val));
|
||||
}
|
||||
}
|
||||
int sz = m_active_sounds.size();
|
||||
SDL_mutexV(m_active_sounds_mutex);
|
||||
if (sz == 0)
|
||||
{
|
||||
SDL_PauseAudio(1);
|
||||
}
|
||||
}
|
||||
|
||||
/******************** AV::Sound ********************/
|
||||
|
||||
AV::Sound::Sound(AV & av)
|
||||
: m_av(av),
|
||||
m_buff(1)
|
||||
{
|
||||
m_rwops = NULL;
|
||||
m_ss = NULL;
|
||||
m_buff_bytes_left = 0;
|
||||
m_volume = 1.0f;
|
||||
}
|
||||
|
||||
AV::Sound::~Sound()
|
||||
{
|
||||
if (m_ss != NULL)
|
||||
{
|
||||
Sound_FreeSample(m_ss);
|
||||
}
|
||||
}
|
||||
|
||||
bool AV::Sound::load(FileLoader & fileLoader, const FileLoader::Path & path)
|
||||
{
|
||||
m_buff = fileLoader.load(path);
|
||||
if (m_buff.size > 0)
|
||||
{
|
||||
m_rwops = SDL_RWFromMem(m_buff.data, m_buff.size);
|
||||
Sound_AudioInfo desired;
|
||||
desired.channels = CHANNELS;
|
||||
desired.format = AUDIO_S16SYS;
|
||||
desired.rate = SOUND_RATE;
|
||||
m_ss = Sound_NewSample(m_rwops, NULL, &desired,
|
||||
CALLBACK_SAMPLES * BYTES_PER_SAMPLE);
|
||||
if (m_ss != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Error loading sound " << path.toString() << ": "
|
||||
<< Sound_GetError() << endl;
|
||||
m_rwops = NULL;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AV::Sound::play()
|
||||
{
|
||||
loop(1);
|
||||
}
|
||||
|
||||
void AV::Sound::resume()
|
||||
{
|
||||
if (m_ss != NULL)
|
||||
{
|
||||
m_av.playSound(this);
|
||||
}
|
||||
}
|
||||
|
||||
void AV::Sound::stop()
|
||||
{
|
||||
if (m_ss != NULL)
|
||||
{
|
||||
m_av.stopSound(this);
|
||||
}
|
||||
}
|
||||
|
||||
void AV::Sound::loop(int times)
|
||||
{
|
||||
if (m_ss != NULL)
|
||||
{
|
||||
m_loop_count = times;
|
||||
rewind();
|
||||
m_av.playSound(this);
|
||||
}
|
||||
}
|
||||
|
||||
void AV::Sound::rewind()
|
||||
{
|
||||
if (m_ss != NULL)
|
||||
{
|
||||
Sound_Rewind(m_ss);
|
||||
}
|
||||
}
|
||||
|
||||
int AV::Sound::decode(Uint8 * stream, int len)
|
||||
{
|
||||
int len_decoded = 0;
|
||||
int bytes_decoded_this_pass;
|
||||
if (m_buff_bytes_left > 0)
|
||||
{
|
||||
int len_to_copy = min(len, m_buff_bytes_left);
|
||||
int buff_offset = m_ss->buffer_size - m_buff_bytes_left;
|
||||
memcpy(stream, ((int8_t *)m_ss->buffer) + buff_offset, len_to_copy);
|
||||
m_buff_bytes_left -= len_to_copy;
|
||||
len_decoded += len_to_copy;
|
||||
}
|
||||
while (len_decoded < len)
|
||||
{
|
||||
bytes_decoded_this_pass = Sound_Decode(m_ss);
|
||||
if (bytes_decoded_this_pass == 0)
|
||||
{
|
||||
if (m_loop_count < INT_MAX)
|
||||
{
|
||||
m_loop_count--;
|
||||
}
|
||||
if (m_loop_count > 0)
|
||||
{
|
||||
Sound_Rewind(m_ss);
|
||||
bytes_decoded_this_pass = Sound_Decode(m_ss);
|
||||
}
|
||||
}
|
||||
if (bytes_decoded_this_pass <= 0)
|
||||
{
|
||||
return len_decoded;
|
||||
}
|
||||
int len_to_copy = min(bytes_decoded_this_pass, len - len_decoded);
|
||||
memcpy(stream + len_decoded, m_ss->buffer, len_to_copy);
|
||||
len_decoded += len_to_copy;
|
||||
m_buff_bytes_left = bytes_decoded_this_pass - len_to_copy;
|
||||
}
|
||||
return len_decoded;
|
||||
}
|
||||
|
||||
void AV::Sound::setVolume(float v)
|
||||
{
|
||||
m_volume = v;
|
||||
if (m_volume > 1.0f)
|
||||
m_volume = 1.0f;
|
||||
else if (m_volume < 0.0f)
|
||||
m_volume = 0.0f;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
|
||||
#ifndef VIDEO_H
|
||||
#define VIDEO_H
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_sound.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "FileLoader/FileLoader.h"
|
||||
#include "refptr/refptr.h"
|
||||
|
||||
#define AV_SOUND_FORMAT AUDIO_S16SYS
|
||||
|
||||
class AV
|
||||
{
|
||||
public:
|
||||
#if AV_SOUND_FORMAT == AUDIO_S16SYS
|
||||
typedef int16_t sample_t;
|
||||
#elif AV_SOUND_FORMAT == AUDIO_U16SYS
|
||||
typedef uint16_t sample_t;
|
||||
#else
|
||||
# error Unknown AV_SOUND_FORMAT
|
||||
#endif
|
||||
class Sound
|
||||
{
|
||||
public:
|
||||
Sound(AV & av);
|
||||
~Sound();
|
||||
bool load(FileLoader & fileLoader,
|
||||
const FileLoader::Path & path);
|
||||
void play();
|
||||
void resume();
|
||||
void stop();
|
||||
void loop(int times);
|
||||
void rewind();
|
||||
int decode(Uint8 * stream, int len);
|
||||
float getVolume() { return m_volume; }
|
||||
void setVolume(float v);
|
||||
protected:
|
||||
AV & m_av;
|
||||
SDL_RWops * m_rwops;
|
||||
Sound_Sample * m_ss;
|
||||
FileLoader::Buffer m_buff;
|
||||
int m_loop_count;
|
||||
int m_buff_bytes_left;
|
||||
float m_volume;
|
||||
};
|
||||
|
||||
AV();
|
||||
~AV();
|
||||
bool start(int width = 0, int height = 0,
|
||||
bool fullscreen = true, bool grab_input = true,
|
||||
int samples = 4);
|
||||
void stop();
|
||||
int getDefaultWidth() { return m_defaultWidth; }
|
||||
int getDefaultHeight() { return m_defaultHeight; }
|
||||
void toggleFullScreen() { SDL_WM_ToggleFullScreen(m_surface); }
|
||||
int getWidth() { return m_width; }
|
||||
int getHeight() { return m_height; }
|
||||
SDL_Surface * getSurface() { return m_surface; }
|
||||
void setCursorVisible(bool visible)
|
||||
{
|
||||
SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
|
||||
}
|
||||
bool getCursorVisible()
|
||||
{
|
||||
return SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE;
|
||||
}
|
||||
void setInputGrabbed(bool grabbed)
|
||||
{
|
||||
SDL_WM_GrabInput(grabbed ? SDL_GRAB_ON : SDL_GRAB_OFF);
|
||||
}
|
||||
bool getInputGrabbed()
|
||||
{
|
||||
return SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON;
|
||||
}
|
||||
refptr<Sound> createSound();
|
||||
void playSound(Sound * s);
|
||||
void stopSound(Sound * s);
|
||||
|
||||
friend void AV_sound_callback(void * userdata, Uint8 * stream, int len);
|
||||
|
||||
protected:
|
||||
void playCallback(Uint8 * stream, int len);
|
||||
|
||||
int m_defaultWidth;
|
||||
int m_defaultHeight;
|
||||
int m_width;
|
||||
int m_height;
|
||||
SDL_Surface * m_surface;
|
||||
bool m_fullscreen;
|
||||
#if 0
|
||||
std::set< refptr<Sound> > m_sounds;
|
||||
#endif
|
||||
std::set< Sound * > m_active_sounds;
|
||||
SDL_mutex * m_active_sounds_mutex;
|
||||
sample_t * m_sound_buffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
+1420
File diff suppressed because it is too large.
Load diff
+382
@@ -0,0 +1,382 @@
|
||||
|
||||
#ifndef ENGINE_H
|
||||
#define ENGINE_H
|
||||
|
||||
#include <string>
|
||||
#include <lua.hpp>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <SDL.h>
|
||||
#include "OdeWorld/OdeWorld.h"
|
||||
#include "TextureCache/TextureCache.h"
|
||||
#include "FileLoader/FileLoader.h"
|
||||
#include "WFObj/WFObj.h"
|
||||
#include "AV.h"
|
||||
#include "refptr/refptr.h"
|
||||
#include "ftgl.h"
|
||||
#include "PhyObj/PhyObj.h"
|
||||
#include "IDSet.h"
|
||||
|
||||
class Engine
|
||||
{
|
||||
public:
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
Object(bool is_static, bool is_reference, bool enable_blending,
|
||||
OdeWorld & world, WFObj * wfobj,
|
||||
float scale = 1.0f);
|
||||
Object(bool is_static, bool is_reference, bool enable_blending,
|
||||
OdeWorld & world, OdeWorld::GeomType geom_type,
|
||||
refptr< std::vector<float> > args);
|
||||
Object(const Object & orig);
|
||||
~Object();
|
||||
|
||||
void setPosition(double x, double y, double z);
|
||||
void getPosition(double * x, double * y, double * z);
|
||||
void loadPhy(FileLoader * fl, const FileLoader::Path & path);
|
||||
void instantiatePhy();
|
||||
void setVisible(bool visible) { m_is_visible = visible; }
|
||||
bool getVisible() { return m_is_visible; }
|
||||
void addForce(dReal fx, dReal fy, dReal fz)
|
||||
{
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->addForce(fx, fy, fz);
|
||||
}
|
||||
void addForceRel(dReal fx, dReal fy, dReal fz)
|
||||
{
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->addForceRel(fx, fy, fz);
|
||||
}
|
||||
void addTorque(dReal fx, dReal fy, dReal fz)
|
||||
{
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->addTorque(fx, fy, fz);
|
||||
}
|
||||
void addTorqueRel(dReal fx, dReal fy, dReal fz)
|
||||
{
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->addTorqueRel(fx, fy, fz);
|
||||
}
|
||||
void setRotation(dReal x, dReal y, dReal z)
|
||||
{
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->setRotation(x, y, z);
|
||||
}
|
||||
void setColor(float r, float g, float b)
|
||||
{
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
render();
|
||||
}
|
||||
void setTransparency(float t)
|
||||
{
|
||||
m_color[3] = 1.0f - t;
|
||||
render();
|
||||
}
|
||||
void setTexture(GLuint tex);
|
||||
void setTextureScale(float scale)
|
||||
{
|
||||
m_texture_scale = scale;
|
||||
render();
|
||||
}
|
||||
void draw();
|
||||
dReal getMass() const;
|
||||
void setMass(dReal mass);
|
||||
const float * getAABB() { return m_aabb; }
|
||||
dBodyID getBody()
|
||||
{
|
||||
return (m_ode_object != NULL) ? m_ode_object->getBody() : 0;
|
||||
}
|
||||
void setGravityMode(bool enabled)
|
||||
{
|
||||
m_gravity_mode = enabled;
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->setGravityMode(enabled);
|
||||
}
|
||||
void setID(int id) { m_id = id; }
|
||||
int getID() { return m_id; }
|
||||
OdeWorld::Object *getOdeWorldObject() { return m_ode_object; }
|
||||
|
||||
protected:
|
||||
void createManagedObject();
|
||||
void render();
|
||||
|
||||
OdeWorld::Object * m_ode_object;
|
||||
GLuint m_display_list;
|
||||
bool m_is_visible;
|
||||
float m_scale;
|
||||
bool m_is_scaled;
|
||||
bool m_is_managed;
|
||||
bool m_is_reference;
|
||||
bool m_is_static;
|
||||
float m_aabb[6];
|
||||
OdeWorld & m_world;
|
||||
refptr<PhyObj> m_phy;
|
||||
dReal m_mass;
|
||||
bool m_mass_is_set;
|
||||
bool m_gravity_mode;
|
||||
int m_id;
|
||||
bool m_enable_blending;
|
||||
|
||||
/* for "pre-loaded" objects */
|
||||
int * m_display_list_refcnt;
|
||||
|
||||
/* for "managed" objects */
|
||||
OdeWorld::GeomType m_geom_type;
|
||||
refptr< std::vector<float> > m_args;
|
||||
float m_color[4];
|
||||
GLuint m_texture;
|
||||
float m_texture_scale;
|
||||
};
|
||||
|
||||
class EngineFileLoader : public FileLoader
|
||||
{
|
||||
public:
|
||||
EngineFileLoader(Engine * engine);
|
||||
virtual int getSize(const Path & path);
|
||||
virtual Buffer load(const Path & path);
|
||||
protected:
|
||||
std::string resolvePath(const Path & path);
|
||||
Engine * m_engine;
|
||||
};
|
||||
|
||||
class PickedObject
|
||||
{
|
||||
public:
|
||||
int id;
|
||||
float dist;
|
||||
float pos[3];
|
||||
float normal[3];
|
||||
|
||||
PickedObject(OdeWorld::PickedObjectRef por);
|
||||
};
|
||||
typedef refptr<PickedObject> PickedObjectRef;
|
||||
|
||||
class Quad
|
||||
{
|
||||
public:
|
||||
Quad(float cx, float cy, float cz,
|
||||
float v1x, float v1y, float v1z,
|
||||
float v2x, float v2y, float v2z);
|
||||
~Quad();
|
||||
int render();
|
||||
void setVisible(bool v) { m_visible = v; }
|
||||
void draw()
|
||||
{
|
||||
if (m_visible)
|
||||
glCallList(m_dl);
|
||||
}
|
||||
void setOffset(float f)
|
||||
{
|
||||
m_offset = f;
|
||||
render();
|
||||
}
|
||||
void setPosition(float x, float y, float z)
|
||||
{
|
||||
m_position[0] = x;
|
||||
m_position[1] = y;
|
||||
m_position[2] = z;
|
||||
render();
|
||||
}
|
||||
void setTexture(int t)
|
||||
{
|
||||
m_texture = t;
|
||||
render();
|
||||
}
|
||||
void setBlending(bool b)
|
||||
{
|
||||
m_enable_blending = b;
|
||||
render();
|
||||
}
|
||||
void setColor(float r, float g, float b, float a)
|
||||
{
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
m_color[3] = a;
|
||||
render();
|
||||
}
|
||||
protected:
|
||||
dVector3 m_center;
|
||||
dVector3 m_v1, m_v2, m_normal;
|
||||
int m_dl;
|
||||
bool m_visible;
|
||||
float m_offset;
|
||||
int m_texture;
|
||||
bool m_enable_blending;
|
||||
float m_color[4];
|
||||
float m_position[3];
|
||||
};
|
||||
|
||||
Engine(const std::string & path, AV & av);
|
||||
~Engine();
|
||||
|
||||
std::string locateResource(const std::string & shortname);
|
||||
bool load(const char * program);
|
||||
void run();
|
||||
void reportErrors(int status);
|
||||
OdeWorld & getWorld() { return m_world; }
|
||||
int addObject(WFObj * obj, bool is_static, bool is_reference,
|
||||
bool enable_blending, float scale = 1.0f);
|
||||
int addObject(bool is_static, bool is_reference, bool enable_blending,
|
||||
OdeWorld::GeomType geom_type,
|
||||
refptr< std::vector<float> > args);
|
||||
int addQuad(float cx, float cy, float cz,
|
||||
float v1x, float v1y, float v1z,
|
||||
float v2x, float v2y, float v2z);
|
||||
int addSound(refptr<AV::Sound> avs);
|
||||
int addAMotor(Object * o1, Object * o2);
|
||||
int addHinge(Object * o1, Object * o2,
|
||||
dReal anchor_x, dReal anchor_y, dReal anchor_z,
|
||||
dReal axis_x, dReal axis_y, dReal axis_z);
|
||||
void setAMotorAxis(int jid, int anum, int rel,
|
||||
dReal x, dReal y, dReal z);
|
||||
void setAMotorNumAxes(int jid, int num_axes);
|
||||
void setAMotorAngle(int jid, int anum, dReal val);
|
||||
void setAMotorLoStop(int jid, dReal val);
|
||||
void setAMotorHiStop(int jid, dReal val);
|
||||
void setAMotorVel(int jid, dReal val);
|
||||
void setAMotorFMax(int jid, dReal val);
|
||||
void setAMotorBounce(int jid, dReal val);
|
||||
void removeObject(int id);
|
||||
int cloneObject(const Object * obj);
|
||||
Object * getObject(int id);
|
||||
Quad * getQuad(int id);
|
||||
refptr<AV::Sound> getSound(int id);
|
||||
void doPhysics();
|
||||
void drawObjects();
|
||||
void setAutoPhysics(bool val) { m_autoPhysics = val; }
|
||||
bool getAutoPhysics() { return m_autoPhysics; }
|
||||
void setAutoStartFrame(bool val) { m_autoStartFrame = val; }
|
||||
bool getAutoStartFrame() { return m_autoStartFrame; }
|
||||
void setAutoEndFrame(bool val) { m_autoEndFrame = val; }
|
||||
bool getAutoEndFrame() { return m_autoEndFrame; }
|
||||
void setAutoDrawObjects(bool val) { m_autoDrawObjects = val; }
|
||||
bool getAutoDrawObjects() { return m_autoDrawObjects; }
|
||||
void startFrame();
|
||||
void endFrame();
|
||||
int loadModel(const std::string & name, bool is_static,
|
||||
bool is_reference, bool enable_blending, float scale = 1.0f);
|
||||
int loadSound(const std::string & name);
|
||||
bool isKeyDown(const std::string & key);
|
||||
void exit();
|
||||
bool import(const char * name);
|
||||
bool importFullPath(const char * path);
|
||||
GLuint loadTexture(const char * name);
|
||||
void debug_hook(lua_Debug * debug);
|
||||
void setGravity(float gx, float gy, float gz)
|
||||
{
|
||||
m_world.setGravity(gx, gy, gz);
|
||||
}
|
||||
GLuint startList();
|
||||
void endList();
|
||||
void drawList(GLuint list);
|
||||
void callList(GLuint list);
|
||||
void clearWorld();
|
||||
void setScriptCursorVisible(bool visible)
|
||||
{
|
||||
m_script_cursor_visible = visible;
|
||||
updateCursorVisibility();
|
||||
}
|
||||
bool getScriptCursorVisible() { return m_script_cursor_visible; }
|
||||
refptr< std::vector<PickedObjectRef> > pickObjects(int x, int y);
|
||||
PickedObjectRef pickOne(int x, int y, Object *obj);
|
||||
|
||||
void getScreenSize(int * width, int * height);
|
||||
void drawText(const char * text, GLfloat r, GLfloat g, GLfloat b,
|
||||
int ptsize, float x, float y);
|
||||
void getTextSize(const char * text, int ptsize,
|
||||
float * width, float * height);
|
||||
void drawLine(float r, float g, float b,
|
||||
float x1, float y1, float x2, float y2, float width = 1.0f);
|
||||
void drawRect(float r, float g, float b,
|
||||
float width, float height, float x, float y, float rot = 0.0f);
|
||||
void fillRect(float r, float g, float b,
|
||||
float width, float height, float x, float y, float rot = 0.0f);
|
||||
void drawImage(float width, float height, float x, float y,
|
||||
int tex, float rot = 0.0f);
|
||||
void fillArc(float r, float g, float b, float x, float y,
|
||||
float radius, float a1, float a2);
|
||||
void drawArc(float r, float g, float b, float x, float y,
|
||||
float radius, float a1, float a2);
|
||||
void drawPoint(float size, float r, float g, float b,
|
||||
float x, float y, float z);
|
||||
|
||||
/* lua services */
|
||||
int setCamera(lua_State * L);
|
||||
int getCamera(lua_State * L);
|
||||
int registerEventHandler(lua_State * L);
|
||||
int clearEventHandler(lua_State * L);
|
||||
|
||||
protected:
|
||||
static Uint32 updateCallback(Uint32 interval, void * param);
|
||||
|
||||
Uint32 updateCallback(Uint32 interval);
|
||||
void registerLibraries();
|
||||
bool fileExists(const std::string & path);
|
||||
void update_event();
|
||||
void update_overlay_event();
|
||||
void key_down_event(int keysym);
|
||||
void key_up_event(int keysym);
|
||||
void mousebutton_down_event(int button, int x, int y);
|
||||
void mousebutton_up_event(int button, int x, int y);
|
||||
void mouse_motion_event(int x, int y, int xrel, int yrel);
|
||||
void checkForFunctionFull(const std::string & lua_fn_name,
|
||||
const std::string & event_name, bool & presentFlag);
|
||||
void doRegisterHandlerFull(int index,
|
||||
const std::string & event_name, bool & presentFlag);
|
||||
void reloadProgram();
|
||||
void checkForAllHandlerFunctions();
|
||||
void updateCursorVisibility()
|
||||
{
|
||||
m_av.setCursorVisible(
|
||||
m_engine_cursor_visible || m_script_cursor_visible);
|
||||
}
|
||||
bool validatePath(std::string & path);
|
||||
|
||||
AV & m_av;
|
||||
bool m_engine_cursor_visible;
|
||||
bool m_script_cursor_visible;
|
||||
bool m_input_grabbed;
|
||||
TextureCache m_textureCache;
|
||||
EngineFileLoader * m_fileLoader;
|
||||
lua_State * m_luaState;
|
||||
std::string m_program_path;
|
||||
std::string m_program_directory;
|
||||
std::string m_engine_path;
|
||||
OdeWorld m_world;
|
||||
IDSet<Object *> m_objects;
|
||||
IDSet<Quad *> m_quads;
|
||||
IDSet< refptr<AV::Sound> > m_sounds;
|
||||
IDSet<dJointID> m_joints;
|
||||
GLdouble m_eye[3];
|
||||
GLdouble m_center[3];
|
||||
GLdouble m_up[3];
|
||||
bool m_drawing;
|
||||
bool m_autoPhysics;
|
||||
bool m_autoStartFrame;
|
||||
bool m_autoEndFrame;
|
||||
bool m_autoDrawObjects;
|
||||
std::map<std::string, bool> m_keysDown;
|
||||
SDL_Event m_updateEvent;
|
||||
SDL_Event m_exitEvent;
|
||||
Uint32 m_event_time;
|
||||
FTFont * m_font;
|
||||
double m_screen_dist;
|
||||
|
||||
bool m_event_init_present;
|
||||
bool m_event_reinit_present;
|
||||
bool m_event_update_present;
|
||||
bool m_event_update_overlay_present;
|
||||
bool m_event_key_down_present;
|
||||
bool m_event_key_up_present;
|
||||
bool m_event_mousebutton_down_present;
|
||||
bool m_event_mousebutton_up_present;
|
||||
bool m_event_mouse_motion_present;
|
||||
};
|
||||
|
||||
extern Engine * g_engine;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,553 @@
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "SDL.h"
|
||||
|
||||
#include "Engine.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef DEBUG_GL_ERROR
|
||||
#define checkGLError() checkGLErrorLine(__FUNCTION__, __LINE__)
|
||||
static void checkGLErrorLine(const char * function, int line)
|
||||
{
|
||||
GLenum err = glGetError();
|
||||
if (err != 0)
|
||||
{
|
||||
std::cerr << "gl error in " << function
|
||||
<< ": " << err << " (0x" << std::hex << err << ") at line "
|
||||
<< std::dec << line << std::endl;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define checkGLError()
|
||||
#endif
|
||||
|
||||
#define FP_EQ(a,b) (fabsf(a - b) < 0.0001)
|
||||
|
||||
/* used for objects loaded directly from model files */
|
||||
Engine::Object::Object(bool is_static, bool is_reference, bool enable_blending,
|
||||
OdeWorld & world, WFObj * obj, float scale)
|
||||
: m_world(world)
|
||||
{
|
||||
m_is_reference = is_reference;
|
||||
if (m_is_reference)
|
||||
{
|
||||
m_ode_object = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ode_object = world.createObject(is_static, scale);
|
||||
m_ode_object->setUserData(this);
|
||||
}
|
||||
m_is_static = is_static;
|
||||
m_enable_blending = enable_blending;
|
||||
m_display_list = obj->render(true, enable_blending);
|
||||
const float * obj_aabb = obj->getAABB();
|
||||
for (int i = 0; i < 6; i++)
|
||||
m_aabb[i] = scale * obj_aabb[i];
|
||||
m_display_list_refcnt = new int;
|
||||
*m_display_list_refcnt = 1;
|
||||
m_is_visible = true;
|
||||
m_scale = scale;
|
||||
m_is_scaled = ! (fabs(scale - 1.0) < 0.0001);
|
||||
m_is_managed = false;
|
||||
m_mass = 0.0;
|
||||
m_mass_is_set = false;
|
||||
m_gravity_mode = true;
|
||||
}
|
||||
|
||||
/* used for "managed" objects with one geom */
|
||||
Engine::Object::Object(bool is_static, bool is_reference, bool enable_blending,
|
||||
OdeWorld & world, OdeWorld::GeomType geom_type,
|
||||
refptr< std::vector<float> > args)
|
||||
: m_world(world)
|
||||
{
|
||||
m_is_reference = is_reference;
|
||||
m_enable_blending = enable_blending;
|
||||
m_is_static = geom_type == OdeWorld::PLANE ? false : is_static;
|
||||
m_is_visible = true;
|
||||
m_scale = 1.0f;
|
||||
m_is_scaled = false;
|
||||
m_display_list = 0;
|
||||
m_display_list_refcnt = NULL;
|
||||
if (m_is_reference)
|
||||
{
|
||||
m_ode_object = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ode_object = world.createObject(m_is_static, m_scale);
|
||||
m_ode_object->setUserData(this);
|
||||
}
|
||||
m_is_managed = true;
|
||||
m_geom_type = geom_type;
|
||||
m_args = args;
|
||||
for (int i = 0; i < 4; i++)
|
||||
m_color[i] = 1.0f;
|
||||
m_texture = 0;
|
||||
m_texture_scale = 1.0f;
|
||||
createManagedObject();
|
||||
render();
|
||||
m_mass = 0.0;
|
||||
m_mass_is_set = false;
|
||||
m_gravity_mode = true;
|
||||
}
|
||||
|
||||
/* used to clone objects */
|
||||
Engine::Object::Object(const Engine::Object & orig)
|
||||
: m_world(orig.m_world)
|
||||
{
|
||||
m_is_reference = false;
|
||||
m_is_visible = orig.m_is_visible;
|
||||
m_is_static = orig.m_is_static;
|
||||
m_enable_blending = orig.m_enable_blending;
|
||||
m_scale = orig.m_scale;
|
||||
m_is_scaled = orig.m_is_scaled;
|
||||
m_phy = orig.m_phy;
|
||||
m_is_managed = orig.m_is_managed;
|
||||
if (m_is_managed)
|
||||
m_display_list = 0;
|
||||
else
|
||||
m_display_list = orig.m_display_list;
|
||||
m_display_list_refcnt = orig.m_display_list_refcnt;
|
||||
if (m_display_list_refcnt != NULL)
|
||||
(*m_display_list_refcnt)++;
|
||||
m_geom_type = orig.m_geom_type;
|
||||
m_args = orig.m_args;
|
||||
for (int i = 0; i < 4; i++)
|
||||
m_color[i] = orig.m_color[i];
|
||||
m_texture = orig.m_texture;
|
||||
m_texture_scale = orig.m_texture_scale;
|
||||
if (orig.m_is_reference)
|
||||
{
|
||||
m_ode_object = m_world.createObject(m_is_static, m_scale);
|
||||
instantiatePhy();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ode_object = new OdeWorld::Object(*orig.m_ode_object);
|
||||
}
|
||||
m_ode_object->setUserData(this);
|
||||
if (m_is_managed)
|
||||
{
|
||||
createManagedObject();
|
||||
render();
|
||||
}
|
||||
m_mass = orig.m_mass;
|
||||
m_mass_is_set = orig.m_mass_is_set;
|
||||
if (m_mass_is_set)
|
||||
{
|
||||
setMass(orig.getMass());
|
||||
}
|
||||
m_gravity_mode = orig.m_gravity_mode;
|
||||
setGravityMode(m_gravity_mode);
|
||||
}
|
||||
|
||||
Engine::Object::~Object()
|
||||
{
|
||||
if (m_ode_object != NULL)
|
||||
delete m_ode_object;
|
||||
if (m_display_list_refcnt != NULL)
|
||||
{
|
||||
(*m_display_list_refcnt)--;
|
||||
if (*m_display_list_refcnt < 1)
|
||||
{
|
||||
/* we hold the last reference to the OpenGL display list */
|
||||
delete m_display_list_refcnt;
|
||||
glDeleteLists(m_display_list, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glDeleteLists(m_display_list, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::Object::createManagedObject()
|
||||
{
|
||||
switch (m_geom_type)
|
||||
{
|
||||
case OdeWorld::BOX: {
|
||||
while (m_args->size() < 9)
|
||||
m_args->push_back(0);
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->addBox(m_args);
|
||||
float aabb[6] = {-(*m_args)[0], -(*m_args)[1], -(*m_args)[2],
|
||||
(*m_args)[0], (*m_args)[1], (*m_args)[2]};
|
||||
for (int i = 0; i < 6; i++)
|
||||
aabb[i] /= 2.0f;
|
||||
memcpy(m_aabb, aabb, sizeof(m_aabb));
|
||||
break;
|
||||
}
|
||||
case OdeWorld::SPHERE: {
|
||||
while (m_args->size() < 4)
|
||||
m_args->push_back(0);
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->addSphere(m_args);
|
||||
float aabb[6] = {-(*m_args)[0], -(*m_args)[0], -(*m_args)[0],
|
||||
(*m_args)[0], (*m_args)[0], (*m_args)[0]};
|
||||
memcpy(m_aabb, aabb, sizeof(m_aabb));
|
||||
break;
|
||||
}
|
||||
case OdeWorld::PLANE: {
|
||||
while (m_args->size() < 4 || m_args->size() == 5)
|
||||
m_args->push_back(0);
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->addPlane(m_args);
|
||||
for (int i = 0; i < 6; i++)
|
||||
m_aabb[i] = 0.0f;
|
||||
break;
|
||||
}
|
||||
case OdeWorld::CYLINDER: {
|
||||
while (m_args->size() < 8)
|
||||
m_args->push_back(0);
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->addCylinder(m_args);
|
||||
float aabb[6] = {-(*m_args)[0], -(*m_args)[0], -(*m_args)[1],
|
||||
(*m_args)[0], (*m_args)[0], (*m_args)[1]};
|
||||
memcpy(m_aabb, aabb, sizeof(m_aabb));
|
||||
break;
|
||||
}
|
||||
case OdeWorld::CAPSULE: {
|
||||
while (m_args->size() < 8)
|
||||
m_args->push_back(0);
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->addCapsule(m_args);
|
||||
float aabb[6] = {-(*m_args)[0], -(*m_args)[0], -(*m_args)[1],
|
||||
(*m_args)[0], (*m_args)[0], (*m_args)[1]};
|
||||
memcpy(m_aabb, aabb, sizeof(m_aabb));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_ode_object != NULL)
|
||||
{
|
||||
m_ode_object->finalize();
|
||||
}
|
||||
if (!m_is_reference)
|
||||
{
|
||||
render();
|
||||
}
|
||||
}
|
||||
|
||||
/* render a managed object */
|
||||
/* prerequisite: m_args->size() is big enough */
|
||||
void Engine::Object::render()
|
||||
{
|
||||
if (!m_is_managed || m_is_reference)
|
||||
return;
|
||||
GLUquadric * quad = gluNewQuadric();
|
||||
if (m_display_list <= 0)
|
||||
{
|
||||
m_display_list = glGenLists(1);
|
||||
}
|
||||
checkGLError();
|
||||
glNewList(m_display_list, GL_COMPILE);
|
||||
int attrib_flags = GL_ENABLE_BIT;
|
||||
if (m_enable_blending)
|
||||
{
|
||||
attrib_flags |= GL_COLOR_BUFFER_BIT | GL_TEXTURE_BIT;
|
||||
}
|
||||
glPushAttrib(attrib_flags);
|
||||
if (m_enable_blending)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
}
|
||||
if (m_texture != 0)
|
||||
{
|
||||
gluQuadricTexture(quad, 1);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, m_color);
|
||||
}
|
||||
switch (m_geom_type)
|
||||
{
|
||||
case OdeWorld::BOX: {
|
||||
const static struct {
|
||||
float norm[3];
|
||||
float verts[4][3];
|
||||
} sides[] = {
|
||||
{ {1, 0, 0}, /* right */
|
||||
{{1, -1, -1}, {1, 1, -1}, {1, 1, 1}, {1, -1, 1}} },
|
||||
{ {-1, 0, 0}, /* left */
|
||||
{{-1, 1, -1}, {-1, -1, -1}, {-1, -1, 1}, {-1, 1, 1}} },
|
||||
{ {0, 1, 0}, /* back */
|
||||
{{1, 1, -1}, {-1, 1, -1}, {-1, 1, 1}, {1, 1, 1}} },
|
||||
{ {0, -1, 0}, /* front */
|
||||
{{-1, -1, -1}, {1, -1, -1}, {1, -1, 1}, {-1, -1, 1}} },
|
||||
{ {0, 0, 1}, /* top */
|
||||
{{-1, -1, 1}, {1, -1, 1}, {1, 1, 1}, {-1, 1, 1}} },
|
||||
{ {0, 0, -1}, /* bottom */
|
||||
{{1, -1, -1}, {-1, -1, -1}, {-1, 1, -1}, {1, 1, -1}} }
|
||||
};
|
||||
const float tex_coords[4][2] = {
|
||||
{0, 0}, {1, 0}, {1, 1}, {0, 1}
|
||||
};
|
||||
glBegin(GL_QUADS);
|
||||
float width = (*m_args)[0];
|
||||
float depth = (*m_args)[1];
|
||||
float height = (*m_args)[2];
|
||||
for (unsigned int s = 0;
|
||||
s < (sizeof(sides)/sizeof(sides[0]));
|
||||
s++)
|
||||
{
|
||||
glNormal3fv(sides[s].norm);
|
||||
for (int v = 0; v < 4; v++)
|
||||
{
|
||||
if (m_texture != 0)
|
||||
{
|
||||
glTexCoord2f(tex_coords[v][0] * m_texture_scale,
|
||||
tex_coords[v][1] * m_texture_scale);
|
||||
}
|
||||
glVertex3f(sides[s].verts[v][0] * width / 2.0,
|
||||
sides[s].verts[v][1] * depth / 2.0,
|
||||
sides[s].verts[v][2] * height / 2.0);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
break;
|
||||
case OdeWorld::SPHERE:
|
||||
gluSphere(quad, (*m_args)[0], 16, 8);
|
||||
break;
|
||||
case OdeWorld::PLANE: {
|
||||
dVector3 normal;
|
||||
dVector3 rotated_x;
|
||||
dVector3 rotated_y;
|
||||
float x_o, y_o, z_o;
|
||||
if (m_args->size() == 6)
|
||||
{
|
||||
dMatrix3 r;
|
||||
dRFromEulerAngles(r, (*m_args)[3], (*m_args)[4], (*m_args)[5]);
|
||||
dVector3 default_plane_direction = {0, 0, 1, 0};
|
||||
dVector3 default_x = {1, 0, 0, 0};
|
||||
dVector3 default_y = {0, 1, 0, 0};
|
||||
dMultiply0(normal, r, default_plane_direction, 3, 3, 1);
|
||||
dMultiply0(rotated_x, r, default_x, 3, 3, 1);
|
||||
dMultiply0(rotated_y, r, default_y, 3, 3, 1);
|
||||
x_o = (*m_args)[0];
|
||||
y_o = (*m_args)[1];
|
||||
z_o = (*m_args)[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
normal[0] = (*m_args)[0];
|
||||
normal[1] = (*m_args)[1];
|
||||
normal[2] = (*m_args)[2];
|
||||
float d = (*m_args)[3];
|
||||
float len = normal[0] * normal[0]
|
||||
+ normal[1] * normal[1]
|
||||
+ normal[2] * normal[2];
|
||||
if (! FP_EQ(len, 1.0)) /* normalize if necessary */
|
||||
{
|
||||
len = sqrtf(len);
|
||||
normal[0] /= len;
|
||||
normal[1] /= len;
|
||||
normal[2] /= len;
|
||||
d /= len;
|
||||
}
|
||||
int min_component = 0;
|
||||
float comp = 10000.0f;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (normal[i] < comp)
|
||||
{
|
||||
min_component = i;
|
||||
comp = normal[i];
|
||||
}
|
||||
}
|
||||
dVector3 cross_vec;
|
||||
for (int i = 0; i < 3; i++)
|
||||
cross_vec[i] = (i == min_component) ? 1 : 0;
|
||||
dCROSS(rotated_x, =, normal, cross_vec);
|
||||
dCROSS(rotated_y, =, normal, rotated_x);
|
||||
x_o = normal[0] * d;
|
||||
y_o = normal[1] * d;
|
||||
z_o = normal[2] * d;
|
||||
}
|
||||
|
||||
/* plane equation: ax + by + cz = d, plane normal: (a, b, c) */
|
||||
|
||||
const int num_sections = 10;
|
||||
const float section_size = 100.0f;
|
||||
#ifdef dSINGLE
|
||||
glNormal3fv(normal);
|
||||
#else
|
||||
glNormal3dv(normal);
|
||||
#endif
|
||||
for (int x = 0; x < num_sections; x++)
|
||||
{
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (int y = 0; y <= num_sections; y++)
|
||||
{
|
||||
float half_span = num_sections * section_size / 2.0;
|
||||
float x_c = x * section_size - half_span;
|
||||
float y_c = y * section_size - half_span;
|
||||
glTexCoord2f(0.0, y * m_texture_scale);
|
||||
glVertex3f(x_o + rotated_x[0] * x_c + rotated_y[0] * y_c,
|
||||
y_o + rotated_x[1] * x_c + rotated_y[1] * y_c,
|
||||
z_o + rotated_x[2] * x_c + rotated_y[2] * y_c);
|
||||
x_c += section_size;
|
||||
glTexCoord2f(1.0, y * m_texture_scale);
|
||||
glVertex3f(x_o + rotated_x[0] * x_c + rotated_y[0] * y_c,
|
||||
y_o + rotated_x[1] * x_c + rotated_y[1] * y_c,
|
||||
z_o + rotated_x[2] * x_c + rotated_y[2] * y_c);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OdeWorld::CYLINDER: {
|
||||
glPushMatrix();
|
||||
float half_span = (*m_args)[1] / 2.0;
|
||||
glTranslatef(0, 0, -half_span);
|
||||
gluCylinder(quad, (*m_args)[0], (*m_args)[0], (*m_args)[1], 12, 1);
|
||||
gluDisk(quad, 0.0, (*m_args)[0], 12, 4);
|
||||
glTranslatef(0, 0, 2 * half_span);
|
||||
gluDisk(quad, 0.0, (*m_args)[0], 12, 4);
|
||||
glPopMatrix();
|
||||
}
|
||||
break;
|
||||
case OdeWorld::CAPSULE: {
|
||||
glPushAttrib(GL_TRANSFORM_BIT); /* save current clip planes */
|
||||
double halfheight = (*m_args)[1] / 2.0;
|
||||
glPushMatrix();
|
||||
glTranslatef(0, 0, -halfheight);
|
||||
gluCylinder(quad, (*m_args)[0], (*m_args)[0], (*m_args)[1], 12, 1);
|
||||
|
||||
double clip_plane[] = {0, 0, -1, halfheight};
|
||||
glClipPlane(GL_CLIP_PLANE0, clip_plane);
|
||||
glEnable(GL_CLIP_PLANE0);
|
||||
gluSphere(quad, (*m_args)[0], 12, 8);
|
||||
glTranslatef(0, 0, 2*halfheight);
|
||||
clip_plane[2] = 1.0;
|
||||
glClipPlane(GL_CLIP_PLANE0, clip_plane);
|
||||
gluSphere(quad, (*m_args)[0], 12, 8);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
break;
|
||||
}
|
||||
gluDeleteQuadric(quad);
|
||||
glPopAttrib();
|
||||
glEndList();
|
||||
checkGLError();
|
||||
}
|
||||
|
||||
void Engine::Object::setPosition(double x, double y, double z)
|
||||
{
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->setPosition(x, y, z);
|
||||
}
|
||||
|
||||
void Engine::Object::getPosition(double * x, double * y, double * z)
|
||||
{
|
||||
if (m_ode_object != NULL)
|
||||
m_ode_object->getPosition(x, y, z);
|
||||
else
|
||||
*x = *y = *z = 0.0;
|
||||
}
|
||||
|
||||
void Engine::Object::loadPhy(FileLoader * fl, const FileLoader::Path & path)
|
||||
{
|
||||
m_phy = new PhyObj();
|
||||
m_phy->load(fl, path);
|
||||
if (!m_is_managed)
|
||||
instantiatePhy();
|
||||
}
|
||||
|
||||
void Engine::Object::instantiatePhy()
|
||||
{
|
||||
if (m_ode_object != NULL && !m_is_managed && !m_phy.isNull())
|
||||
{
|
||||
for (int i = 0, sz = m_phy->getNumGeoms(); i < sz; i++)
|
||||
{
|
||||
refptr<PhyObj::Geom> geom = m_phy->getGeom(i);
|
||||
refptr< vector<float> > args = geom->getArgs();
|
||||
switch (geom->getType())
|
||||
{
|
||||
case PhyObj::BOX:
|
||||
m_ode_object->addBox(args);
|
||||
break;
|
||||
case PhyObj::SPHERE:
|
||||
m_ode_object->addSphere(args);
|
||||
break;
|
||||
case PhyObj::CAPSULE:
|
||||
m_ode_object->addCapsule(args);
|
||||
break;
|
||||
case PhyObj::PLANE:
|
||||
m_ode_object->addPlane(args);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_ode_object->finalize();
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::Object::setTexture(GLuint tex)
|
||||
{
|
||||
if (m_is_managed)
|
||||
{
|
||||
m_texture = tex;
|
||||
render();
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::Object::draw()
|
||||
{
|
||||
if (!m_is_reference && m_is_visible)
|
||||
{
|
||||
checkGLError();
|
||||
const dReal * pos = m_ode_object->getPosition();
|
||||
const dReal * rot = m_ode_object->getRotation();
|
||||
bool transform = (pos != NULL && rot != NULL);
|
||||
|
||||
if (transform)
|
||||
OdeWorld::pushTransform(pos, rot);
|
||||
|
||||
if (m_is_scaled)
|
||||
{
|
||||
glPushAttrib(GL_TRANSFORM_BIT);
|
||||
glEnable(GL_NORMALIZE);
|
||||
glPushMatrix();
|
||||
glScalef(m_scale, m_scale, m_scale);
|
||||
}
|
||||
|
||||
checkGLError();
|
||||
glCallList(m_display_list);
|
||||
checkGLError();
|
||||
|
||||
if (m_is_scaled)
|
||||
{
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
if (transform)
|
||||
glPopMatrix();
|
||||
checkGLError();
|
||||
}
|
||||
}
|
||||
|
||||
dReal Engine::Object::getMass() const
|
||||
{
|
||||
return (m_ode_object != NULL) ? m_ode_object->getMass() : m_mass;
|
||||
}
|
||||
|
||||
void Engine::Object::setMass(dReal mass)
|
||||
{
|
||||
m_mass = mass;
|
||||
m_mass_is_set = true;
|
||||
if (m_ode_object != NULL)
|
||||
{
|
||||
m_ode_object->setMass(mass);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
|
||||
#ifndef IDSET_H
|
||||
#define IDSET_H
|
||||
|
||||
#include <map>
|
||||
|
||||
template <class T>
|
||||
class IDSet
|
||||
{
|
||||
public:
|
||||
IDSet() { m_next_index = 1; }
|
||||
int add(const T & o)
|
||||
{
|
||||
int id = m_next_index++;
|
||||
m_data[id] = o;
|
||||
return id;
|
||||
}
|
||||
void erase(int id)
|
||||
{
|
||||
m_data.erase(id);
|
||||
}
|
||||
T & operator[](int id)
|
||||
{
|
||||
return m_data[id];
|
||||
}
|
||||
bool contains(int id)
|
||||
{
|
||||
return m_data.find(id) != m_data.end();
|
||||
}
|
||||
bool empty() { return m_data.empty(); }
|
||||
typename std::map<int, T>::iterator begin() { return m_data.begin(); }
|
||||
typename std::map<int, T>::iterator end() { return m_data.end(); }
|
||||
protected:
|
||||
std::map<int, T> m_data;
|
||||
int m_next_index;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,137 @@
|
||||
|
||||
#ifndef AG_H
|
||||
#define AG_H
|
||||
|
||||
#include <lua.hpp>
|
||||
|
||||
#include "Engine.h"
|
||||
#include "AV.h"
|
||||
|
||||
namespace ag
|
||||
{
|
||||
void register_functions(lua_State * L);
|
||||
|
||||
/* Lua interfaces */
|
||||
int callList(lua_State * L);
|
||||
int clearEventHandler(lua_State * L);
|
||||
int createQuad(lua_State * L);
|
||||
int doPhysics(lua_State * L);
|
||||
int drawObjects(lua_State * L);
|
||||
int elapsedTime(lua_State * L);
|
||||
int endFrame(lua_State * L);
|
||||
int endList(lua_State * L);
|
||||
int exit(lua_State * L);
|
||||
int getCamera(lua_State * L);
|
||||
int getCursorVisible(lua_State * L);
|
||||
int getScreenSize(lua_State * L);
|
||||
int import(lua_State * L);
|
||||
int isKeyDown(lua_State * L);
|
||||
int loadModelSpecify(lua_State * L);
|
||||
int loadSound(lua_State * L);
|
||||
int loadTexture(lua_State * L);
|
||||
int next(lua_State * L);
|
||||
int pickObjects(lua_State * L);
|
||||
int pickOne(lua_State * L);
|
||||
int print(lua_State * L);
|
||||
int println(lua_State * L);
|
||||
int registerEventHandler(lua_State * L);
|
||||
int setAutoDrawObjects(lua_State * L);
|
||||
int setAutoEndFrame(lua_State * L);
|
||||
int setAutoPhysics(lua_State * L);
|
||||
int setAutoStartFrame(lua_State * L);
|
||||
int setCamera(lua_State * L);
|
||||
int setCursorVisible(lua_State * L);
|
||||
int setGravity(lua_State * L);
|
||||
int sleep(lua_State * L);
|
||||
int startFrame(lua_State * L);
|
||||
int startList(lua_State * L);
|
||||
int type(lua_State * L);
|
||||
int clearWorld(lua_State * L);
|
||||
|
||||
int _createAMotor(lua_State * L);
|
||||
int _createHinge(lua_State * L);
|
||||
|
||||
/* 2D overlay functions */
|
||||
int drawArc(lua_State * L);
|
||||
int drawCircle(lua_State * L);
|
||||
int drawImage(lua_State * L);
|
||||
int drawLine(lua_State * L);
|
||||
int drawPoint(lua_State * L);
|
||||
int drawRect(lua_State * L);
|
||||
int drawText(lua_State * L);
|
||||
int fillArc(lua_State * L);
|
||||
int fillCircle(lua_State * L);
|
||||
int fillRect(lua_State * L);
|
||||
int getTextSize(lua_State * L);
|
||||
|
||||
/* managed object creation functions */
|
||||
int createBoxSpecify(lua_State * L);
|
||||
int createCapsuleSpecify(lua_State * L);
|
||||
int createCylinderSpecify(lua_State * L);
|
||||
int createPlaneSpecify(lua_State * L);
|
||||
int createSphereSpecify(lua_State * L);
|
||||
|
||||
namespace object
|
||||
{
|
||||
Engine::Object * getObject(lua_State * L, int index);
|
||||
|
||||
int draw(lua_State * L);
|
||||
int setPosition(lua_State * L);
|
||||
int getPosition(lua_State * L);
|
||||
int setRotation(lua_State * L);
|
||||
int clone(lua_State * L);
|
||||
int destroy(lua_State * L);
|
||||
int setVisible(lua_State * L);
|
||||
int addForce(lua_State * L);
|
||||
int addForceRel(lua_State * L);
|
||||
int addTorque(lua_State * L);
|
||||
int addTorqueRel(lua_State * L);
|
||||
int setColor(lua_State * L);
|
||||
int setGravityMode(lua_State * L);
|
||||
int setTexture(lua_State * L);
|
||||
int setTextureScale(lua_State * L);
|
||||
int setTransparency(lua_State * L);
|
||||
int getMass(lua_State * L);
|
||||
int setMass(lua_State * L);
|
||||
int getAABB(lua_State * L);
|
||||
int getSize(lua_State * L);
|
||||
}
|
||||
|
||||
namespace quad
|
||||
{
|
||||
Engine::Quad * getQuad(lua_State * L, int index);
|
||||
|
||||
int setBlending(lua_State * L);
|
||||
int setColor(lua_State * L);
|
||||
int setOffset(lua_State * L);
|
||||
int setPosition(lua_State * L);
|
||||
int setTexture(lua_State * L);
|
||||
int setVisible(lua_State * L);
|
||||
}
|
||||
|
||||
namespace joint
|
||||
{
|
||||
int setAMotorAxis(lua_State * L);
|
||||
int setAMotorNumAxes(lua_State * L);
|
||||
int setAMotorAngle(lua_State * L);
|
||||
int setAMotorLoStop(lua_State * L);
|
||||
int setAMotorHiStop(lua_State * L);
|
||||
int setAMotorVel(lua_State * L);
|
||||
int setAMotorFMax(lua_State * L);
|
||||
int setAMotorBounce(lua_State * L);
|
||||
}
|
||||
|
||||
namespace sound
|
||||
{
|
||||
refptr<AV::Sound> getSound(lua_State * L, int index);
|
||||
int play(lua_State * L);
|
||||
int resume(lua_State * L);
|
||||
int stop(lua_State * L);
|
||||
int loop(lua_State * L);
|
||||
int loopForever(lua_State * L);
|
||||
int getVolume(lua_State * L);
|
||||
int setVolume(lua_State * L);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
next = ag.next
|
||||
type = ag.type
|
||||
ag._objects = {}
|
||||
|
||||
pairs = function(table)
|
||||
return next, table, nil
|
||||
end
|
||||
|
||||
ipairs = function(table)
|
||||
local iter_func = function(t, i)
|
||||
i = i + 1
|
||||
if t[i] == nil then
|
||||
return nil
|
||||
else
|
||||
return i, t[i]
|
||||
end
|
||||
end
|
||||
return iter_func, table, 0
|
||||
end
|
||||
|
||||
ag.createAMotor = function(obj1, obj2, axis0, axis1, axis2)
|
||||
local function setAMotorAxis(amotor, anum, axis)
|
||||
local rel, x, y, z = 0, 1, 0, 0
|
||||
for k, v in pairs(axis) do
|
||||
if (k == "rel") then
|
||||
rel = v
|
||||
elseif (k == "x") then
|
||||
x = v
|
||||
elseif (k == "y") then
|
||||
y = v
|
||||
elseif (k == "z") then
|
||||
z = v
|
||||
elseif (k == "angle") then
|
||||
amotor:setAngle(anum, v)
|
||||
elseif (k == "lo_stop") then
|
||||
amotor:setLoStop(v)
|
||||
elseif (k == "hi_stop") then
|
||||
amotor:setHiStop(v)
|
||||
elseif (k == "vel") then
|
||||
amotor:setVel(v)
|
||||
elseif (k == "fmax") then
|
||||
amotor:setFMax(v)
|
||||
elseif (k == "bounce") then
|
||||
amotor:setBounce(v)
|
||||
end
|
||||
end
|
||||
amotor:setAxis(anum, rel, x, y, z)
|
||||
end
|
||||
|
||||
local o1 = obj1
|
||||
local o2 = obj2
|
||||
local num_axes = 0
|
||||
|
||||
if (type(obj1) == "number") then
|
||||
if (obj1 == 0) then
|
||||
o1 = { id = 0 }
|
||||
end
|
||||
end
|
||||
|
||||
if (type(obj2) == "number") then
|
||||
if (obj2 == 0) then
|
||||
o2 = { id = 0 }
|
||||
end
|
||||
end
|
||||
|
||||
local amotor = ag._createAMotor(o1, o2)
|
||||
|
||||
if (amotor ~= nil) then
|
||||
if (axis0 ~= nil) then
|
||||
setAMotorAxis(amotor, 0, axis0)
|
||||
num_axes = 1
|
||||
if (axis1 ~= nil) then
|
||||
setAMotorAxis(amotor, 1, axis1)
|
||||
num_axes = 1
|
||||
if (axis2 ~= nil) then
|
||||
setAMotorAxis(amotor, 2, axis2)
|
||||
num_axes = 2
|
||||
end
|
||||
end
|
||||
end
|
||||
amotor:setNumAxes(num_axes)
|
||||
else
|
||||
ag.println("Error creating AMotor!")
|
||||
end
|
||||
|
||||
return amotor
|
||||
end
|
||||
|
||||
ag.createHinge = function(obj1, obj2, anchor, axis)
|
||||
local o1 = obj1
|
||||
local o2 = obj2
|
||||
|
||||
if (type(obj1) == "number") then
|
||||
if (obj1 == 0) then
|
||||
o1 = { id = 0 }
|
||||
end
|
||||
end
|
||||
|
||||
if (type(obj2) == "number") then
|
||||
if (obj2 == 0) then
|
||||
o2 = { id = 0 }
|
||||
end
|
||||
end
|
||||
|
||||
return ag._createHinge(o1, o2,
|
||||
anchor[1], anchor[2], anchor[3],
|
||||
axis[1], axis[2], axis[3])
|
||||
end
|
||||
|
||||
ag.loadModel = function(name, args)
|
||||
local scale = 1.0
|
||||
local static = false
|
||||
local reference = false
|
||||
local blending = false
|
||||
if (type(args) == "table") then
|
||||
if (type(args.scale) == "number") then
|
||||
scale = args.scale
|
||||
end
|
||||
if (type(args.static) == "boolean") then
|
||||
static = args.static
|
||||
end
|
||||
if (type(args.reference) == "boolean") then
|
||||
reference = args.reference
|
||||
end
|
||||
if (type(args.enable_blending) == "boolean") then
|
||||
blending = args.enable_blending
|
||||
end
|
||||
end
|
||||
return ag.loadModelSpecify(name, scale, static, reference, blending)
|
||||
end
|
||||
|
||||
ag.createBox = function(x, y, z, args)
|
||||
local static = false
|
||||
local reference = false
|
||||
local blending = false
|
||||
if (type(args) == "table") then
|
||||
if (type(args.static) == "boolean") then
|
||||
static = args.static
|
||||
end
|
||||
if (type(args.reference) == "boolean") then
|
||||
reference = args.reference
|
||||
end
|
||||
if (type(args.enable_blending) == "boolean") then
|
||||
blending = args.enable_blending
|
||||
end
|
||||
end
|
||||
return ag.createBoxSpecify(x, y, z, static, reference, blending)
|
||||
end
|
||||
|
||||
ag.createSphere = function(radius, args)
|
||||
local static = false
|
||||
local reference = false
|
||||
local blending = false
|
||||
if (type(args) == "table") then
|
||||
if (type(args.static) == "boolean") then
|
||||
static = args.static
|
||||
end
|
||||
if (type(args.reference) == "boolean") then
|
||||
reference = args.reference
|
||||
end
|
||||
if (type(args.enable_blending) == "boolean") then
|
||||
blending = args.enable_blending
|
||||
end
|
||||
end
|
||||
return ag.createSphereSpecify(radius, static, reference, blending)
|
||||
end
|
||||
|
||||
ag.createPlane = function(a, b, c, d, x, y, z)
|
||||
local t = nil
|
||||
if (type(x) == "table") then
|
||||
t = x
|
||||
end
|
||||
if (type(z) == "table") then
|
||||
t = z
|
||||
end
|
||||
local reference = false
|
||||
local blending = false
|
||||
if (type(t) == "table") then
|
||||
if (type(t.reference) == "boolean") then
|
||||
reference = t.reference
|
||||
end
|
||||
if (type(args.enable_blending) == "boolean") then
|
||||
blending = args.enable_blending
|
||||
end
|
||||
end
|
||||
if (type(y) == "nil") then
|
||||
return ag.createPlaneSpecify(a, b, c, d, reference, blending)
|
||||
else
|
||||
return ag.createPlaneSpecify(a, b, c, d, x, y, reference, blending)
|
||||
end
|
||||
end
|
||||
|
||||
ag.createCapsule = function(radius, length, args)
|
||||
local static = false
|
||||
local reference = false
|
||||
local blending = false
|
||||
if (type(args) == "table") then
|
||||
if (type(args.static) == "boolean") then
|
||||
static = args.static
|
||||
end
|
||||
if (type(args.reference) == "boolean") then
|
||||
reference = args.reference
|
||||
end
|
||||
if (type(args.enable_blending) == "boolean") then
|
||||
blending = args.enable_blending
|
||||
end
|
||||
end
|
||||
return ag.createCapsuleSpecify(radius, length, static, reference, blending)
|
||||
end
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
#ifndef AG_LUA_H
|
||||
#define AG_LUA_H
|
||||
|
||||
extern unsigned char ag_lua[];
|
||||
extern unsigned int ag_lua_len;
|
||||
|
||||
#endif
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
|
||||
#include "AV.h"
|
||||
#include "anaglym.h"
|
||||
#include "Engine.h"
|
||||
#include "SDL.h"
|
||||
#include <stdlib.h> /* exit(), srand() */
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
static void usage();
|
||||
|
||||
static void usage()
|
||||
{
|
||||
cerr << "Usage: anaglym [options] program.lua[c]" << endl;
|
||||
cerr << "Options:" << endl;
|
||||
cerr << " -w<width> : set window width" << endl;
|
||||
cerr << " -h<height> : set window height" << endl;
|
||||
cerr << " -f : do not fullscreen" << endl;
|
||||
cerr << " -g : do not grab mouse input" << endl;
|
||||
cerr << " -s<samples>: set multisample level (default 4)" << endl;
|
||||
exit(42);
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
bool fullscreen = true;
|
||||
bool grab_input = true;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int samples = 4;
|
||||
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
|
||||
{
|
||||
if (!strcmp(argv[i], "-f"))
|
||||
{
|
||||
fullscreen = false;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-g"))
|
||||
{
|
||||
grab_input = false;
|
||||
}
|
||||
else if (!strncmp(argv[i], "-w", 2))
|
||||
{
|
||||
width = atoi((strlen(argv[i]) == 2) ? argv[++i] : argv[i] + 2);
|
||||
}
|
||||
else if (!strncmp(argv[i], "-h", 2))
|
||||
{
|
||||
height = atoi((strlen(argv[i]) == 2) ? argv[++i] : argv[i] + 2);
|
||||
}
|
||||
else if (!strncmp(argv[i], "-s", 2))
|
||||
{
|
||||
samples = atoi((strlen(argv[i]) == 2) ? argv[++i] : argv[i] + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Warning: Unrecognized option '" << argv[i]+1
|
||||
<< "'" << endl;
|
||||
usage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (program == NULL)
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
AV av;
|
||||
if (!av.start(width, height, fullscreen, grab_input, samples))
|
||||
{
|
||||
cerr << "anaglym: exiting." << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find the full path to the program */
|
||||
string engine_path = argv[0];
|
||||
#ifdef PLATFORM_LINUX
|
||||
/* get the full path to the process using /proc/self/exe */
|
||||
char * buff = new char[10000];
|
||||
ssize_t bytes_read = readlink("/proc/self/exe", buff, 9999);
|
||||
if (bytes_read > 0)
|
||||
{
|
||||
buff[bytes_read] = '\0';
|
||||
engine_path = buff;
|
||||
}
|
||||
delete[] buff;
|
||||
#endif
|
||||
|
||||
dInitODE();
|
||||
g_engine = new Engine(engine_path, av);
|
||||
if (g_engine->load(program))
|
||||
g_engine->run();
|
||||
delete g_engine;
|
||||
av.stop();
|
||||
dCloseODE();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
#ifndef ANAGLYM_H
|
||||
#define ANAGLYM_H
|
||||
|
||||
#define FILENAME_SAFE_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.:"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
#ifndef SDL_KEYMAP_H
|
||||
#define SDL_KEYMAP_H
|
||||
|
||||
extern char * sdl_keymap[SDLK_LAST+1];
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user