move source files to "src" subdirectory

This commit is contained in:
Josh Holtrop committed 2011-05-17 16:11:55 -04:00
1 parent 0579235c93
commit cd1e26318a
14 files changed
+3 -7

No files matched your search

+369
View File
@@ -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;
}
+102
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff
+382
View File
@@ -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
+553
View File
@@ -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
View File
@@ -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
+2022
View File
File diff suppressed because it is too large. Load diff
+137
View File
@@ -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
View File
@@ -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
+8
View File
@@ -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
View File
@@ -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;
}
+7
View File
@@ -0,0 +1,7 @@
#ifndef ANAGLYM_H
#define ANAGLYM_H
#define FILENAME_SAFE_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.:"
#endif
+7
View File
@@ -0,0 +1,7 @@
#ifndef SDL_KEYMAP_H
#define SDL_KEYMAP_H
extern char * sdl_keymap[SDLK_LAST+1];
#endif