commit d0e0fcc3ac6bf1574a63b9e7fde6a708211a2f09 Author: zhongjin Date: Sat Oct 15 14:31:14 2022 +0800 new diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ee28272 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.DS_Store + diff --git a/bin/crashpad_handler b/bin/crashpad_handler new file mode 100755 index 0000000..4eac0be Binary files /dev/null and b/bin/crashpad_handler differ diff --git a/include/plib/fnt.h b/include/plib/fnt.h new file mode 100644 index 0000000..22da92b --- /dev/null +++ b/include/plib/fnt.h @@ -0,0 +1,361 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: fnt.h 1923 2004-04-06 12:53:17Z sjbaker $ +*/ + + +#ifndef _FNT_H_ +#define _FNT_H_ 1 + +#include +#include "sg.h" + +#ifdef UL_MAC_OSX +# include +#else +# include +#endif + + +#define FNTMAX_CHAR 256 +#define FNT_TRUE 1 +#define FNT_FALSE 0 + + +class fntFont +{ +public: + fntFont () ; + + virtual ~fntFont () ; + + virtual void getBBox ( const char *s, float pointsize, float italic, + float *left, float *right, + float *bot , float *top ) = 0 ; + virtual void putch ( sgVec3 curpos, float pointsize, float italic, char c ) = 0 ; + virtual void puts ( sgVec3 curpos, float pointsize, float italic, const char *s ) = 0 ; + virtual void begin () = 0 ; + virtual void end () = 0 ; + + virtual int load ( const char *fname, GLenum mag = GL_NEAREST, + GLenum min = GL_LINEAR_MIPMAP_LINEAR ) = 0 ; + + virtual void setFixedPitch ( int fix ) = 0 ; + virtual int isFixedPitch () const = 0 ; + + virtual void setWidth ( float w ) = 0 ; + virtual void setGap ( float g ) = 0 ; + + virtual float getWidth () const = 0 ; + virtual float getGap () const = 0 ; + + virtual int hasGlyph ( char c ) const = 0 ; +} ; + + +class fntTexFont : public fntFont +{ +private: + GLuint texture ; + int bound ; + int fixed_pitch ; + + float width ; /* The width of a character in fixed-width mode */ + float gap ; /* Set the gap between characters */ + + int exists [ FNTMAX_CHAR ] ; /* TRUE if character exists in tex-map */ + + /* + The quadrilaterals that describe the characters + in the font are drawn with the following texture + and spatial coordinates. The texture coordinates + are in (S,T) space, with (0,0) at the bottom left + of the image and (1,1) at the top-right. + + The spatial coordinates are relative to the current + 'cursor' position. They should be scaled such that + 1.0 represent the height of a capital letter. Hence, + characters like 'y' which have a descender will be + given a negative v_bot. Most capitals will have + v_bot==0.0 and v_top==1.0. + */ + + /* Nominal baseline widths */ + + float widths [ FNTMAX_CHAR ] ; + + /* Texture coordinates */ + + float t_top [ FNTMAX_CHAR ] ; /* Top edge of each character [0..1] */ + float t_bot [ FNTMAX_CHAR ] ; /* Bottom edge of each character [0..1] */ + float t_left [ FNTMAX_CHAR ] ; /* Left edge of each character [0..1] */ + float t_right [ FNTMAX_CHAR ] ; /* Right edge of each character [0..1] */ + + /* Vertex coordinates. */ + + float v_top [ FNTMAX_CHAR ] ; + float v_bot [ FNTMAX_CHAR ] ; + float v_left [ FNTMAX_CHAR ] ; + float v_right [ FNTMAX_CHAR ] ; + + void bind_texture () + { + glEnable ( GL_TEXTURE_2D ) ; +#ifdef GL_VERSION_1_1 + glBindTexture ( GL_TEXTURE_2D, texture ) ; +#else + /* For ancient SGI machines */ + glBindTextureEXT ( GL_TEXTURE_2D, texture ) ; +#endif + } + + float low_putch ( sgVec3 curpos, float pointsize, float italic, char c ) ; + + int loadTXF ( const char *fname, GLenum mag = GL_NEAREST, + GLenum min = GL_LINEAR_MIPMAP_LINEAR ) ; +public: + + fntTexFont () + { + bound = FNT_FALSE ; + fixed_pitch = FNT_TRUE ; + texture = 0 ; + width = 1.0f ; + gap = 0.1f ; + + memset ( exists, FNT_FALSE, FNTMAX_CHAR * sizeof(int) ) ; + } + + fntTexFont ( const char *fname, GLenum mag = GL_NEAREST, + GLenum min = GL_LINEAR_MIPMAP_LINEAR ) : fntFont () + { + bound = FNT_FALSE ; + fixed_pitch = FNT_TRUE ; + texture = 0 ; + width = 1.0f ; + gap = 0.1f ; + + memset ( exists, FNT_FALSE, FNTMAX_CHAR * sizeof(int) ) ; + load ( fname, mag, min ) ; + } + + ~fntTexFont () + { + if ( texture != 0 ) + { +#ifdef GL_VERSION_1_1 + glDeleteTextures ( 1, &texture ) ; +#else + /* For ancient SGI machines */ + glDeleteTexturesEXT ( 1, &texture ) ; +#endif + } + } + + int load ( const char *fname, GLenum mag = GL_NEAREST, + GLenum min = GL_LINEAR_MIPMAP_LINEAR ) ; + + void setFixedPitch ( int fix ) { fixed_pitch = fix ; } + int isFixedPitch () const { return fixed_pitch ; } + + void setWidth ( float w ) { width = w ; } + void setGap ( float g ) { gap = g ; } + + float getWidth () const { return width ; } + float getGap () const { return gap ; } + + + void setGlyph ( char c, float wid, + float tex_left, float tex_right, + float tex_bot , float tex_top , + float vtx_left, float vtx_right, + float vtx_bot , float vtx_top ) ; + void setGlyph ( char c, + float tex_left, float tex_right, + float tex_bot , float tex_top , + float vtx_left, float vtx_right, + float vtx_bot , float vtx_top ) /* deprecated */ + { + setGlyph ( c, vtx_right, + tex_left, tex_right, tex_bot, tex_top, + vtx_left, vtx_right, vtx_bot, vtx_top ) ; + } + + int getGlyph ( char c, float* wid, + float *tex_left = NULL, float *tex_right = NULL, + float *tex_bot = NULL, float *tex_top = NULL, + float *vtx_left = NULL, float *vtx_right = NULL, + float *vtx_bot = NULL, float *vtx_top = NULL) ; + int getGlyph ( char c, + float *tex_left = NULL, float *tex_right = NULL, + float *tex_bot = NULL, float *tex_top = NULL, + float *vtx_left = NULL, float *vtx_right = NULL, + float *vtx_bot = NULL, float *vtx_top = NULL) /* deprecated */ + { + return getGlyph ( c, NULL, + tex_left, tex_right, tex_bot, tex_top, + vtx_left, vtx_right, vtx_bot, vtx_top ) ; + } + + int hasGlyph ( char c ) const { return exists[ (GLubyte) c ] ; } + + void getBBox ( const char *s, float pointsize, float italic, + float *left, float *right, + float *bot , float *top ) ; + + void begin () + { + bind_texture () ; + bound = FNT_TRUE ; + } + + void end () + { + bound = FNT_FALSE ; + } + + void puts ( sgVec3 curpos, float pointsize, float italic, const char *s ) ; + + void putch ( sgVec3 curpos, float pointsize, float italic, char c ) + { + if ( ! bound ) + bind_texture () ; + + low_putch ( curpos, pointsize, italic, c ) ; + } + +} ; + + + +class fntBitmapFont : public fntFont +{ + protected: + + const GLubyte **data; + int first; + int count; + int height; + float xorig, yorig; + int fix; + float wid, gap; + + public: + + // data is a null-terminated list of glyph images: + // data[i][0] - image width + // data[i][1..n] - packed bitmap + + fntBitmapFont ( const GLubyte **data, int first, int height, + float xorig, float yorig ) ; + + virtual ~fntBitmapFont () ; + + virtual void getBBox ( const char *s, float pointsize, float italic, + float *left, float *right, + float *bot , float *top ) ; + + virtual void putch ( sgVec3 curpos, float pointsize, float italic, char c ) ; + virtual void puts ( sgVec3 curpos, float pointsize, float italic, const char *s ) ; + + virtual void begin () ; + virtual void end () ; + + virtual int load ( const char *fname, GLenum mag, GLenum min ) { return -1; } + + virtual void setFixedPitch ( int f ) { fix = f; } + virtual int isFixedPitch () const { return fix; } + + virtual void setWidth ( float w ) { wid = w; } + virtual void setGap ( float g ) { gap = g; } + + virtual float getWidth () const { return wid; } + virtual float getGap () const { return gap; } + + virtual int hasGlyph ( char c ) const ; +}; + + +/* Builtin Bitmap Fonts */ + +#define FNT_BITMAP_8_BY_13 0 +#define FNT_BITMAP_9_BY_15 1 +#define FNT_BITMAP_HELVETICA_10 2 +#define FNT_BITMAP_HELVETICA_12 3 +#define FNT_BITMAP_HELVETICA_18 4 +#define FNT_BITMAP_TIMES_ROMAN_10 5 +#define FNT_BITMAP_TIMES_ROMAN_24 6 + +fntBitmapFont *fntGetBitmapFont(int id); + + + +class fntRenderer +{ + fntFont *font ; + + sgVec3 curpos ; + + float pointsize ; + float italic ; + +public: + fntRenderer () + { + start2f ( 0.0f, 0.0f ) ; + font = NULL ; + pointsize = 10 ; + italic = 0 ; + } + + void start3fv ( sgVec3 pos ) { sgCopyVec3 ( curpos, pos ) ; } + void start2fv ( sgVec2 pos ) { sgCopyVec2 ( curpos, pos ) ; curpos[2]=0.0f ; } + void start2f ( float x, float y ) { sgSetVec3 ( curpos, x, y, 0.0f ) ; } + void start3f ( float x, float y, float z ) { sgSetVec3 ( curpos, x, y, z ) ; } + + void getCursor ( float *x, float *y, float *z ) const + { + if ( x != NULL ) *x = curpos [ 0 ] ; + if ( y != NULL ) *y = curpos [ 1 ] ; + if ( z != NULL ) *z = curpos [ 2 ] ; + } + + void setFont ( fntFont *f ) { font = f ; } + fntFont *getFont () const { return font ; } + + void setSlant ( float i ) { italic = i ; } + void setPointSize ( float p ) { pointsize = p ; } + + float getSlant () const { return italic ; } + float getPointSize () const { return pointsize ; } + + void begin () { font->begin () ; } + void end () { font->end () ; } + + void putch ( char c ) { font->putch ( curpos, pointsize, italic, c ) ; } + void puts ( const char *s ) { font->puts ( curpos, pointsize, italic, s ) ; } +} ; + + +void fntInit () ; + +#endif + diff --git a/include/plib/js.h b/include/plib/js.h new file mode 100644 index 0000000..2962b24 --- /dev/null +++ b/include/plib/js.h @@ -0,0 +1,98 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: js.h 2067 2006-01-30 07:36:01Z bram $ +*/ + +#ifndef __INCLUDED_JS_H__ +#define __INCLUDED_JS_H__ 1 +#define JS_NEW + +#include "ul.h" + +#include +#include +#include // -dw- for memcpy + +#define _JS_MAX_AXES 16 +#define _JS_MAX_BUTTONS 32 +#define _JS_MAX_HATS 4 + +#define JS_TRUE 1 +#define JS_FALSE 0 + + +class jsJoystick +{ + int id ; +protected: + struct os_specific_s *os ; + friend struct os_specific_s ; + int error ; + char name [ 128 ] ; + int num_axes ; + int num_buttons ; + + float dead_band [ _JS_MAX_AXES ] ; + float saturate [ _JS_MAX_AXES ] ; + float center [ _JS_MAX_AXES ] ; + float max [ _JS_MAX_AXES ] ; + float min [ _JS_MAX_AXES ] ; + + void open () ; + void close () ; + + float fudge_axis ( float value, int axis ) const ; + +public: + + jsJoystick ( int ident = 0 ) ; + ~jsJoystick () { close () ; } + + const char* getName () const { return name ; } + int getNumAxes () const { return num_axes ; } + int getNumButtons () const { return num_buttons; } + int notWorking () const { return error ; } + void setError () { error = JS_TRUE ; } + + float getDeadBand ( int axis ) const { return dead_band [ axis ] ; } + void setDeadBand ( int axis, float db ) { dead_band [ axis ] = db ; } + + float getSaturation ( int axis ) const { return saturate [ axis ] ; } + void setSaturation ( int axis, float st ) { saturate [ axis ] = st ; } + + void setMinRange ( float *axes ) { memcpy ( min , axes, num_axes * sizeof(float) ) ; } + void setMaxRange ( float *axes ) { memcpy ( max , axes, num_axes * sizeof(float) ) ; } + void setCenter ( float *axes ) { memcpy ( center, axes, num_axes * sizeof(float) ) ; } + + void getMinRange ( float *axes ) const { memcpy ( axes, min , num_axes * sizeof(float) ) ; } + void getMaxRange ( float *axes ) const { memcpy ( axes, max , num_axes * sizeof(float) ) ; } + void getCenter ( float *axes ) const { memcpy ( axes, center, num_axes * sizeof(float) ) ; } + + void read ( int *buttons, float *axes ) ; + void rawRead ( int *buttons, float *axes ) ; + // bool SetForceFeedBack ( int axe, float force ); +} ; + +extern void jsInit () ; + +#endif + + diff --git a/include/plib/net.h b/include/plib/net.h new file mode 100644 index 0000000..e7b0c90 --- /dev/null +++ b/include/plib/net.h @@ -0,0 +1,12 @@ +#ifndef __PLIB_NET_H__ +#define __PLIB_NET_H__ 1 + +#include +#include +#include +#include +#include +#include + +#endif + diff --git a/include/plib/netBuffer.h b/include/plib/netBuffer.h new file mode 100644 index 0000000..c5ff59b --- /dev/null +++ b/include/plib/netBuffer.h @@ -0,0 +1,234 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: netBuffer.h 1901 2004-03-21 18:19:11Z sjbaker $ +*/ + +/**** +* NAME +* netBuffer - network buffer class +* +* DESCRIPTION +* Clients and servers built on top of netBufferChannel +* automatically support pipelining. +* +* Pipelining refers to a protocol capability. Normally, +* a conversation with a server has a back-and-forth +* quality to it. The client sends a command, and +* waits for the response. If a client needs to send +* many commands over a high-latency connection, +* waiting for each response can take a long time. +* +* For example, when sending a mail message to many recipients +* with SMTP, the client will send a series of RCPT commands, one +* for each recipient. For each of these commands, the server will +* send back a reply indicating whether the mailbox specified is +* valid. If you want to send a message to several hundred recipients, +* this can be rather tedious if the round-trip time for each command +* is long. You'd like to be able to send a bunch of RCPT commands +* in one batch, and then count off the responses to them as they come. +* +* I have a favorite visual when explaining the advantages of +* pipelining. Imagine each request to the server is a boxcar on a train. +* The client is in Los Angeles, and the server is in New York. +* Pipelining lets you hook all your cars in one long chain; send +* them to New York, where they are filled and sent back to you. +* Without pipelining you have to send one car at a time. +* +* Not all protocols allow pipelining. Not all servers support it; +* Sendmail, for example, does not support pipelining because it tends +* to fork unpredictably, leaving buffered data in a questionable state. +* A recent extension to the SMTP protocol allows a server to specify +* whether it supports pipelining. HTTP/1.1 explicitly requires that +* a server support pipelining. +* +* NOTES +* When a user passes in a buffer object, it belongs to +* the user. When the library gives a buffer to the user, +* the user should copy it. +* +* AUTHORS +* Sam Rushing - original version for Medusa +* Dave McClurg - modified for use in PLIB +* +* CREATION DATE +* Dec-2000 +* +****/ + +#ifndef NET_BUFFER_H +#define NET_BUFFER_H + +#include "netChannel.h" + + +// =========================================================================== +// netName +// =========================================================================== + +enum { NET_MAX_NAME = 31 } ; +//eg. char name [ NET_MAX_NAME+1 ] ; + + +inline char* netCopyName ( char* dst, const char* src ) +{ + if ( src != NULL ) + { + strncpy ( dst, src, NET_MAX_NAME ) ; + dst [ NET_MAX_NAME ] = 0 ; + } + else + *dst = 0 ; + return dst ; +} + + +// =========================================================================== +// netBuffer +// =========================================================================== + +class netBuffer +{ +protected: + int length ; + int max_length ; + char* data ; + +public: + netBuffer ( int _max_length ) + { + length = 0 ; + max_length = _max_length ; + data = new char [ max_length+1 ] ; //for null terminator + } + + ~netBuffer () + { + delete[] data ; + } + + int getLength() const { return length ; } + int getMaxLength() const { return max_length ; } + + /* + ** getData() returns a pointer to the data + ** Note: a zero (0) byte is appended for convenience + ** but the data may have internal zero (0) bytes already + */ + char* getData() { data [length] = 0 ; return data ; } + const char* getData() const { ((char*)data) [length] = 0 ; return data ; } + + void remove () + { + length = 0 ; + } + + void remove (int pos, int n) + { + assert (pos>=0 && pos=0 && pos - original version for Medusa +* Dave McClurg - modified for use in PLIB +* +* CREATION DATE +* Dec-2000 +* +****/ + +#ifndef NET_CHANNEL_H +#define NET_CHANNEL_H + +#include "netSocket.h" + +class netChannel : public netSocket +{ + bool closed, connected, accepting, write_blocked, should_delete ; + netChannel* next_channel ; + + friend bool netPoll (unsigned int timeout); + +public: + + netChannel () ; + virtual ~netChannel () ; + + void setHandle (int s, bool is_connected = true); + bool isConnected () const { return connected; } + bool isClosed () const { return closed; } + void shouldDelete () { should_delete = true ; } + + // -------------------------------------------------- + // socket methods + // -------------------------------------------------- + + bool open ( void ) ; + void close ( void ) ; + int listen ( int backlog ) ; + int connect ( const char* host, int port ) ; + int send ( const void * buf, int size, int flags = 0 ) ; + int recv ( void * buf, int size, int flags = 0 ) ; + + // poll() eligibility predicates + virtual bool readable (void) { return (connected || accepting); } + virtual bool writable (void) { return (!connected || write_blocked); } + + // -------------------------------------------------- + // event handlers + // -------------------------------------------------- + + void handleReadEvent (void); + void handleWriteEvent (void); + + // These are meant to be overridden. + virtual void handleClose (void) { + //ulSetError(UL_WARNING,"Network: %d: unhandled close",getHandle()); + } + virtual void handleRead (void) { + ulSetError(UL_WARNING,"Network: %d: unhandled read",getHandle()); + } + virtual void handleWrite (void) { + ulSetError(UL_WARNING,"Network: %d: unhandled write",getHandle()); + } + virtual void handleAccept (void) { + ulSetError(UL_WARNING,"Network: %d: unhandled accept",getHandle()); + } + virtual void handleError (int error) { + ulSetError(UL_WARNING,"Network: %d: errno: %s(%d)",getHandle(),strerror(errno),errno); + } + + static bool poll (unsigned int timeout = 0 ) ; + static void loop (unsigned int timeout = 0 ) ; +}; + +#endif // NET_CHANNEL_H diff --git a/include/plib/netChat.h b/include/plib/netChat.h new file mode 100644 index 0000000..db56e47 --- /dev/null +++ b/include/plib/netChat.h @@ -0,0 +1,86 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: netChat.h 1568 2002-09-02 06:05:49Z sjbaker $ +*/ + +/**** +* NAME +* netChat - network chat class +* +* DESCRIPTION +* This class adds support for 'chat' style protocols - +* where one side sends a 'command', and the other sends +* a response (examples would be the common internet +* protocols - smtp, nntp, ftp, etc..). +* +* The handle_buffer_read() method looks at the input +* stream for the current 'terminator' (usually '\r\n' +* for single-line responses, '\r\n.\r\n' for multi-line +* output), calling found_terminator() on its receipt. +* +* EXAMPLE +* Say you build an nntp client using this class. +* At the start of the connection, you'll have +* terminator set to '\r\n', in order to process +* the single-line greeting. Just before issuing a +* 'LIST' command you'll set it to '\r\n.\r\n'. +* The output of the LIST command will be accumulated +* (using your own 'collect_incoming_data' method) +* up to the terminator, and then control will be +* returned to you - by calling your found_terminator() +* +* AUTHORS +* Sam Rushing - original version for Medusa +* Dave McClurg - modified for use in PLIB +* +* CREATION DATE +* Dec-2000 +* +****/ + +#ifndef NET_CHAT_H +#define NET_CHAT_H + +#include "netBuffer.h" + +class netChat : public netBufferChannel +{ + char* terminator; + + virtual void handleBufferRead (netBuffer& buffer) ; + +public: + + netChat () : terminator (0) {} + + void setTerminator (const char* t); + const char* getTerminator (void); + + bool push (const char* s) + { + return bufferSend ( s, strlen(s) ) ; + } + + virtual void collectIncomingData (const char* s, int n) {} + virtual void foundTerminator (void) {} +}; + +#endif // NET_CHAT_H diff --git a/include/plib/netMessage.h b/include/plib/netMessage.h new file mode 100644 index 0000000..57a4a89 --- /dev/null +++ b/include/plib/netMessage.h @@ -0,0 +1,294 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: netMessage.h 2112 2006-12-12 18:45:28Z fayjf $ +*/ + +/**** +* NAME +* netMessage - message buffer and channel classes +* +* DESCRIPTION +* messages are a binary format for sending buffers over a channel. +* message headers contain a type field and length. +* +* AUTHOR +* Dave McClurg +* +* CREATION DATE +* Dec-2000 +****/ + +#ifndef __NET_MESSAGE__ +#define __NET_MESSAGE__ + + +#include "netBuffer.h" + +// ntohs() etc prototypes +#ifdef UL_MSVC +#include +#else +#include +#endif + +#ifdef __FreeBSD__ +#include +#endif + + +class netGuid //Globally Unique IDentifier +{ +public: + unsigned char data [ 16 ] ; + + netGuid () {} + + netGuid ( unsigned int l, + unsigned short w1, unsigned short w2, + unsigned char b1, unsigned char b2, + unsigned char b3, unsigned char b4, + unsigned char b5, unsigned char b6, + unsigned char b7, unsigned char b8 ) + { + //store in network format (big-endian) + + data[ 0] = (unsigned char)(l>>24) ; + data[ 1] = (unsigned char)(l>>16) ; + data[ 2] = (unsigned char)(l>> 8) ; + data[ 3] = (unsigned char)(l ) ; + data[ 4] = (unsigned char)(w1>>8) ; + data[ 5] = (unsigned char)(w1 ) ; + data[ 6] = (unsigned char)(w2>>8) ; + data[ 7] = (unsigned char)(w2 ) ; + + data[ 8] = b1 ; + data[ 9] = b2 ; + data[10] = b3 ; + data[11] = b4 ; + data[12] = b5 ; + data[13] = b6 ; + data[14] = b7 ; + data[15] = b8 ; + } + + bool operator ==( const netGuid& guid ) const + { + return memcmp ( data, guid.data, sizeof(data) ) == 0 ; + } + + bool operator !=( const netGuid& guid ) const + { + return memcmp ( data, guid.data, sizeof(data) ) != 0 ; + } +} ; + + +class netMessage : public netBuffer +{ + int pos ; + + void seek ( int new_pos ) const + { + if ( new_pos < 0 ) + new_pos = 0 ; + else + if ( new_pos > length ) + new_pos = length ; + + //logical const-ness + + ((netMessage*)this) -> pos = new_pos ; + } + + void skip ( int off ) const + { + seek(pos+off); + } + +public: + + // incoming message; header is already there + netMessage ( const char* s, int n ) : netBuffer(n) + { + assert ( n >= 5 ) ; + append(s,n); + pos = 5 ; // seek past header + } + + // outgoing message + netMessage ( int type, int to_id, int from_id=0, int n=256 ) : netBuffer(n) + { + // output header + putw ( 0 ) ; //msg_len + putbyte ( type ) ; + putbyte ( to_id ) ; + putbyte ( from_id ) ; + } + + int getType () const { return ( (unsigned char*)data )[ 2 ] ; } + int getToID () const { return ( (unsigned char*)data )[ 3 ] ; } + int getFromID () const { return ( (unsigned char*)data )[ 4 ] ; } + void setFromID ( int from_id ) { ( (unsigned char*)data )[ 4 ] = (unsigned char)from_id; } + + void geta ( void* a, int n ) const + { + assert (pos>=0 && pos=0 && pospos++; + if (ch==0) + break; + } + *dst = 0 ; + } + void puts ( const char* s ) + { + puta(s,strlen(s)+1); + } + + void print ( FILE *fd = stderr ) const + { + fprintf ( fd, "netMessage: %p, length=%d\n", this, length ) ; + fprintf ( fd, " header (type,to,from) = (%d,%d,%d)\n", + getType(), getToID(), getFromID() ) ; + fprintf ( fd, " data = " ) ; + for ( int i=0; i - original version for Medusa +* Dave McClurg - modified for use in PLIB +* +* CREATION DATE +* Dec-2000 +* +****/ + +#ifndef NET_MONITOR_H +#define NET_MONITOR_H + +#include "netChat.h" + + +class netMonitorServer : private netChannel +{ + char* name ; + char* password ; + char* prompt ; + void (*cmdfunc)(const char*) ; + class netMonitorChannel* active ; + + friend class netMonitorChannel ; + + virtual bool writable (void) { return false ; } + virtual void handleAccept (void) ; + +public: + + netMonitorServer( const char* _name, int port ) + { + name = ulStrDup(_name); + password = ulStrDup("") ; + prompt = ulStrDup(">>> "); + cmdfunc = 0 ; + active = 0 ; + + open () ; + bind ("", port); + listen (1); + + ulSetError(UL_DEBUG, "Monitor \"%s\" started on port %d",name,port); + } + + ~netMonitorServer() + { + delete[] name ; + delete[] password ; + delete[] prompt ; + } + + const char* getPassword () const { return password; } + void setPassword ( const char* string ) + { + delete[] password ; + password = ulStrDup ( string?string:"" ) ; + } + + void setPrompt ( const char* string ) + { + delete[] prompt ; + prompt = ulStrDup ( string?string:"" ) ; + } + + void setCommandFunc ( void (*func)(const char*) ) + { + cmdfunc = func ; + } + + bool push (const char* s) ; +} ; + +#endif // NET_MONITOR_H diff --git a/include/plib/netSocket.h b/include/plib/netSocket.h new file mode 100644 index 0000000..80e65da --- /dev/null +++ b/include/plib/netSocket.h @@ -0,0 +1,128 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: netSocket.h 2135 2008-11-10 15:40:28Z fayjf $ +*/ + +/**** +* NAME +* netSocket - network sockets +* +* DESCRIPTION +* netSocket is a thin C++ wrapper over bsd sockets to +* facilitate porting to other platforms +* +* AUTHOR +* Dave McClurg +* +* CREATION DATE +* Dec-2000 +* +****/ + +#ifndef NET_SOCKET_H +#define NET_SOCKET_H + +#include "ul.h" +#include + +#if defined(UL_MAC_OSX) +# include +#endif + +/* + * Socket address, internet style. + */ +class netAddress +{ + /* DANGER!!! This MUST match 'struct sockaddr_in' exactly! */ +#ifdef UL_MAC_OSX +// This member is added since OS X 10.5.2 ... I'm wondering how to handle this... + __uint8_t sin_len; + __uint8_t sin_family; + in_port_t sin_port; + in_addr_t sin_addr; + char sin_zero[8]; +#else + short sin_family ; + unsigned short sin_port ; + unsigned int sin_addr ; + char sin_zero [ 8 ] ; +#endif + +public: + netAddress () {} + netAddress ( const char* host, int port ) ; + + void set ( const char* host, int port ) ; + const char* getHost () const ; + unsigned int getPort() const ; + unsigned int getIP () const ; + unsigned int getFamily () const ; + static const char* getLocalHost () ; + + bool getBroadcast () const ; +}; + + +/* + * Socket type + */ +class netSocket +{ + int handle ; + +public: + + netSocket () ; + virtual ~netSocket () ; + + int getHandle () const { return handle; } + void setHandle (int handle) ; + + bool open ( bool stream=true ) ; + void close ( void ) ; + int bind ( const char* host, int port ) ; + int listen ( int backlog ) ; + int accept ( netAddress* addr ) ; + int connect ( const char* host, int port ) ; + int send ( const void * buffer, int size, int flags = 0 ) ; + int sendto ( const void * buffer, int size, int flags, const netAddress* to ) ; + int recv ( void * buffer, int size, int flags = 0 ) ; + int recvfrom ( void * buffer, int size, int flags, netAddress* from ) ; + + void setBlocking ( bool blocking ) ; + void setBroadcast ( bool broadcast ) ; + + static bool isNonBlockingError () ; + static int select ( netSocket** reads, netSocket** writes, int timeout ) ; +} ; + + +int netInit ( int* argc, char** argv = NULL ) ; /* Legacy */ + +int netInit () ; + + +const char* netFormat ( const char* fmt, ... ) ; + + +#endif // NET_SOCKET_H + diff --git a/include/plib/pu.h b/include/plib/pu.h new file mode 100644 index 0000000..ba81a9e --- /dev/null +++ b/include/plib/pu.h @@ -0,0 +1,1615 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: pu.h 2160 2010-02-27 03:48:23Z fayjf $ +*/ + +#ifndef _PU_H_ +#define _PU_H_ 1 + +#include +#include "fnt.h" +#include "ulRTTI.h" + +/* + Configuration +*/ + +#define PU_NOBUTTON -1 +#define PU_LEFT_BUTTON 0 +#define PU_MIDDLE_BUTTON 1 +#define PU_RIGHT_BUTTON 2 +#define PU_SCROLL_UP_BUTTON 3 +#define PU_SCROLL_DOWN_BUTTON 4 +#define PU_DOWN 0 +#define PU_UP 1 + +class puFont +{ +protected: + fntFont * fnt_font_handle ; + float pointsize ; + float slant ; + +public: + + puFont () ; + + puFont ( fntFont *tfh, float ps = 13, float sl = 0 ) + { + initialize ( tfh, ps, sl ) ; + } + + void initialize ( fntFont *tfh, float ps, float sl = 0 ) + { + fnt_font_handle = tfh ; + pointsize = ps ; + slant = sl ; + } + + float getPointSize ( ) const { return pointsize; } + + int getStringDescender ( void ) const ; + int getStringHeight ( const char *str ) const ; + int getStringHeight ( void ) const { return getStringHeight ( "" ) ; } + + float getFloatStringWidth ( const char *str ) const ; + int getStringWidth ( const char *str ) const /* Deprecated ? */ + { + return (int) getFloatStringWidth ( str ) ; + } + + void drawString ( const char *str, int x, int y ) ; +} ; + + +extern puFont PUFONT_8_BY_13 ; +extern puFont PUFONT_9_BY_15 ; +extern puFont PUFONT_TIMES_ROMAN_10 ; +extern puFont PUFONT_TIMES_ROMAN_24 ; +extern puFont PUFONT_HELVETICA_10 ; +extern puFont PUFONT_HELVETICA_12 ; +extern puFont PUFONT_HELVETICA_18 ; + +#define PU_UP_AND_DOWN 254 +#define PU_DRAG 255 +#define PU_CONTINUAL PU_DRAG + +/* + WARNING: These have to be the same as PW_KEY_whatever and also + the same as (GLUT_KEY_whatever+256) +*/ + +#define PU_KEY_GLUT_SPECIAL_OFFSET 256 + +#define PU_KEY_F1 (1 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_F2 (2 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_F3 (3 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_F4 (4 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_F5 (5 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_F6 (6 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_F7 (7 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_F8 (8 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_F9 (9 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_F10 (10 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_F11 (11 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_F12 (12 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_LEFT (100 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_UP (101 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_RIGHT (102 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_DOWN (103 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_PAGE_UP (104 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_PAGE_DOWN (105 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_HOME (106 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_END (107 + PU_KEY_GLUT_SPECIAL_OFFSET) +#define PU_KEY_INSERT (108 + PU_KEY_GLUT_SPECIAL_OFFSET) + +#define PUARROW_UP 0 +#define PUARROW_DOWN 1 +#define PUARROW_FASTUP 2 +#define PUARROW_FASTDOWN 3 +#define PUARROW_LEFT 4 +#define PUARROW_RIGHT 5 +#define PUARROW_FASTLEFT 6 +#define PUARROW_FASTRIGHT 7 + +#define PUBUTTON_NORMAL 0 +#define PUBUTTON_RADIO 1 +#define PUBUTTON_CIRCLE 2 +#define PUBUTTON_VCHECK 3 /* v-shaped checkmark */ +#define PUBUTTON_XCHECK 4 /* X checkmark */ + +/* Rational Definitions of PUI Legend and Label Places */ +#define PUPLACE_TOP_LEFT 0 +#define PUPLACE_TOP_CENTERED 1 +#define PUPLACE_TOP_RIGHT 2 + +#define PUPLACE_CENTERED_LEFT 3 +#define PUPLACE_CENTERED_RIGHT 4 + +#define PUPLACE_BOTTOM_LEFT 5 +#define PUPLACE_BOTTOM_CENTERED 6 +#define PUPLACE_BOTTOM_RIGHT 7 + +/* Additional definitions for PUI Legend places */ +#define PUPLACE_CENTERED_CENTERED 8 + +/* Additional definitions for PUI Label places */ +#define PUPLACE_ABOVE_LEFT 9 +#define PUPLACE_ABOVE_RIGHT 10 + +#define PUPLACE_BELOW_LEFT 11 +#define PUPLACE_BELOW_RIGHT 12 + +#define PUPLACE_UPPER_LEFT 13 +#define PUPLACE_UPPER_RIGHT 14 + +#define PUPLACE_LOWER_LEFT 15 +#define PUPLACE_LOWER_RIGHT 16 + +/* Default places */ +#define PUPLACE_LABEL_DEFAULT PUPLACE_LOWER_RIGHT +#define PUPLACE_LEGEND_DEFAULT PUPLACE_CENTERED_CENTERED + +/* Keep these for backwards compatibility but deprecate them */ +#define PUPLACE_ABOVE PUPLACE_TOP_LEFT +#define PUPLACE_BELOW PUPLACE_BOTTOM_LEFT +#define PUPLACE_LEFT PUPLACE_LOWER_LEFT +#define PUPLACE_RIGHT PUPLACE_LOWER_RIGHT +#define PUPLACE_CENTERED PUPLACE_CENTERED_CENTERED +#define PUPLACE_TOP_CENTER PUPLACE_TOP_CENTERED +#define PUPLACE_BOTTOM_CENTER PUPLACE_BOTTOM_CENTERED +#define PUPLACE_LEFT_CENTER PUPLACE_CENTERED_LEFT +#define PUPLACE_RIGHT_CENTER PUPLACE_CENTERED_RIGHT + +#define PUPLACE_DEFAULT PUPLACE_LABEL_DEFAULT + +#define PUCOL_FOREGROUND 0 +#define PUCOL_BACKGROUND 1 +#define PUCOL_HIGHLIGHT 2 +#define PUCOL_LABEL 3 +#define PUCOL_LEGEND 4 +#define PUCOL_MISC 5 +#define PUCOL_EDITFIELD 6 +#define PUCOL_MAX 7 + +#define PUSLIDER_CLICK 0 +#define PUSLIDER_ALWAYS 1 +#define PUSLIDER_DELTA 2 + +/* These styles may be negated to get 'highlighted' graphics */ + +#define PUSTYLE_DEFAULT PUSTYLE_SHADED +#define PUSTYLE_NONE 0 +#define PUSTYLE_PLAIN 1 +#define PUSTYLE_BEVELLED 2 +#define PUSTYLE_BOXED 3 +#define PUSTYLE_DROPSHADOW 4 +#define PUSTYLE_SPECIAL_UNDERLINED 5 +#define PUSTYLE_SMALL_BEVELLED 6 +#define PUSTYLE_RADIO 7 /* deprecated ! */ +#define PUSTYLE_SHADED 8 +#define PUSTYLE_SMALL_SHADED 9 +#define PUSTYLE_MAX 10 + +/* These are the gaps that we try to leave around text objects */ + +#define PUSTR_TGAP 5 +#define PUSTR_BGAP 5 +#define PUSTR_LGAP 5 +#define PUSTR_RGAP 5 + +#define PU_RADIO_BUTTON_SIZE 16 + +/* When to deactivate a widget and call its down callback */ +#define PUDEACTIVATE_ON_MOUSE_CLICK 0 +#define PUDEACTIVATE_ON_NEXT_WIDGET_ACTIVATION 1 + +extern int puRefresh ; /* Should not be used directly by applications any + longer. Instead, use puPostRefresh () and + puNeedRefresh (). */ + +#define PUCLASS_VALUE 0x00000001 +#define PUCLASS_OBJECT 0x00000002 +#define PUCLASS_GROUP 0x00000004 +#define PUCLASS_INTERFACE 0x00000008 +#define PUCLASS_FRAME 0x00000010 +#define PUCLASS_TEXT 0x00000020 +#define PUCLASS_BUTTON 0x00000040 +#define PUCLASS_ONESHOT 0x00000080 +#define PUCLASS_POPUP 0x00000100 +#define PUCLASS_POPUPMENU 0x00000200 +#define PUCLASS_MENUBAR 0x00000400 +#define PUCLASS_INPUT 0x00000800 +#define PUCLASS_BUTTONBOX 0x00001000 +#define PUCLASS_SLIDER 0x00002000 +#define PUCLASS_DIALOGBOX 0x00004000 +#define PUCLASS_ARROW 0x00008000 +#define PUCLASS_LISTBOX 0x00010000 +#define PUCLASS_DIAL 0x00020000 + +class puValue ; +class puObject ; +class puGroup ; +class puInterface ; +class puButtonBox ; +class puFrame ; +class puText ; +class puButton ; +class puOneShot ; +class puPopup ; +class puPopupMenu ; +class puMenuBar ; +class puInput ; +class puSlider ; +class puListBox ; +class puArrowButton ; +class puDial ; + +// Global function to move active object to the end of the "dlist" +// so it is displayed in front of everything else + +void puMoveToLast ( puObject *ob ) ; + +typedef float puColour [ 4 ] ; /* RGBA */ +typedef puColour puColor ; + +struct puBox +{ + int min [ 2 ] ; + int max [ 2 ] ; + + void draw ( int dx, int dy, int style, puColour colour[], int am_default, int border ) ; + void extend ( puBox *bx ) ; + + void empty ( void ) { min[0]=min[1]=1000000 ; max[0]=max[1]=-1000000 ; } + int isEmpty ( void ) const { return min[0]>max[0] || min[1]>max[1] ; } +} ; + +#define PUSTRING_MAX 256 + +/* With many memory managers, allocating powers of two is more efficient */ +#define PUSTRING_INITIAL 64 + + +inline void puSetColour ( puColour dst, const puColour src ) +{ + dst[0] = src[0] ; dst[1] = src[1] ; dst[2] = src[2] ; dst[3] = src[3] ; +} +inline void puSetColor ( puColour dst, const puColour src ) +{ + dst[0] = src[0] ; dst[1] = src[1] ; dst[2] = src[2] ; dst[3] = src[3] ; +} + +inline void puSetColour ( puColour c, float r, float g, float b, float a = 1.0f ) +{ + c [ 0 ] = r ; c [ 1 ] = g ; c [ 2 ] = b ; c [ 3 ] = a ; +} +inline void puSetColor ( puColour c, float r, float g, float b, float a = 1.0f ) +{ + c [ 0 ] = r ; c [ 1 ] = g ; c [ 2 ] = b ; c [ 3 ] = a ; +} + + +// puInit () -- is a macro, see below +void puRealInit ( void ) ; +void puExit ( void ) ; +void puDisplay ( void ) ; +void puDisplay ( int window_number ) ; /* Deprecated */ +int puMouse ( int button, int updown, int x, int y ) ; +int puMouse ( int x, int y ) ; +int puKeyboard ( int key, int updown, int x, int y ) ; /* For PW */ +int puKeyboard ( int key, int updown ) ; +void puHideCursor ( void ) ; +void puShowCursor ( void ) ; +int puCursorIsHidden ( void ) ; +void puDeleteObject ( puObject *ob ) ; + +int puNeedRefresh ( void ) ; +void puPostRefresh ( void ) ; + +int puGetWindow ( void ) ; +void puGetWindowSize ( int *width, int *height ) ; +int puGetWindowWidth ( void ) ; +int puGetWindowHeight ( void ) ; + +void puSetWindow ( int w ) ; // don't use it! +void puSetWindowSize ( int width, int height ) ; // don't use it! + +void puSetResizeMode ( int mode ) ; // DEPRECATED + + +// Active widget functions + +void puDeactivateWidget ( void ) ; +void puSetActiveWidget ( puObject *w, int x, int y ) ; +puObject *puActiveWidget ( void ) ; + +// Return the currently active mouse button +extern int puGetPressedButton () ; + + + +class puValue +{ + UL_TYPE_DATA + +protected: + int type ; + + int integer ; + float floater ; + char *string ; + bool boolean ; + + int *res_integer ; + float *res_floater ; + char *res_string ; + bool *res_bool ; + + int string_size ; + int res_string_sz ; + + int convert ; + + void re_eval ( void ) ; + void update_res ( void ) const { } /* Obsolete ! */ ; + + void copy_stringval ( const char *str ) ; + + int * getIntegerp ( void ) { return res_integer != NULL ? res_integer : &integer ; } + float * getFloaterp ( void ) { return res_floater != NULL ? res_floater : &floater ; } + char * getStringp ( void ) { return res_string != NULL ? res_string : string ; } + bool * getBooleanp ( void ) { return res_bool != NULL ? res_bool : &boolean ; } + + void enableConversion ( void ) { convert = TRUE ; } + void disableConversion ( void ) { convert = FALSE ; } + int conversionEnabled ( void ) const { return convert ; } + +public: + puValue () + { + convert = TRUE ; + + string_size = PUSTRING_INITIAL ; + string = new char [ string_size ] ; + + type = PUCLASS_VALUE ; + res_integer = NULL ; + res_floater = NULL ; + res_string = NULL ; + res_bool = NULL ; + clrValue () ; + } + + virtual ~puValue () { delete [] string ; } + + int getType ( void ) const { return type ; } + const char *getTypeString ( void ) const ; + void clrValue ( void ) { setValue ( "" ) ; } + + virtual void setValue ( puValue *pv ) + { + *getIntegerp () = pv -> getIntegerValue () ; + *getFloaterp () = pv -> getFloatValue () ; + copy_stringval ( pv -> getStringValue () ) ; + *getBooleanp () = pv -> getBooleanValue () ; + puPostRefresh () ; + } + + void setValuator ( int *i ) + { + res_integer = i ; + + if ( convert == TRUE ) + { + res_floater = NULL ; res_string = NULL ; res_bool = NULL ; + re_eval () ; + } + } + + void setValuator ( float *f ) + { + res_floater = f ; + + if ( convert == TRUE ) + { + res_integer = NULL ; res_string = NULL ; res_bool = NULL ; + re_eval () ; + } + } + + void setValuator ( char *s, int size ) + { + res_string = s ; + res_string_sz = size ; + + if ( convert == TRUE ) + { + res_integer = NULL ; res_floater = NULL ; res_bool = NULL ; + re_eval () ; + } + } + + void setValuator ( bool *b ) + { + res_bool = b ; + + if ( convert == TRUE ) + { + res_integer = NULL ; res_floater = NULL ; res_string = NULL ; + re_eval () ; + } + } + + /* Obsolete ! */ + void setValuator ( char *s ) { setValuator ( s, PUSTRING_MAX ) ; } + + virtual void setValue ( int i ) + { + *getIntegerp () = i ; + + if ( convert == TRUE ) + { + *getFloaterp () = (float) i ; sprintf ( getStringp (), "%d", i ) ; *getBooleanp () = ( i != 0 ) ; + } + + puPostRefresh () ; + } + + virtual void setValue ( float f ) + { + *getFloaterp () = f ; + + if ( convert == TRUE ) + { + *getIntegerp () = (int) f ; sprintf ( getStringp (), "%g", f ) ; *getBooleanp () = ( f != 0.0 ) ; + } + + puPostRefresh () ; + } + + virtual void setValue ( const char *s ) ; + + virtual void setValue ( bool b ) + { + *getBooleanp () = b ; + + if ( convert == TRUE ) + { + *getIntegerp () = b ? 1 : 0 ; *getFloaterp () = b ? 1.0f : 0.0f ; sprintf ( getStringp (), "%s", b ? "1" : "0" ) ; + } + + puPostRefresh () ; + } + + void getValue ( int *i ) { re_eval () ; *i = *getIntegerp () ; } + void getValue ( float *f ) { re_eval () ; *f = *getFloaterp () ; } + void getValue ( char **s ) { re_eval () ; *s = getStringp () ; } + void getValue ( char *s, int size ) + { + re_eval () ; + + /* Work around ANSI strncpy's null-fill behaviour */ + + s[0] = '\0' ; + strncat ( s, getStringp (), size-1 ) ; + } + + void getValue ( char *s ) { getValue ( s, PUSTRING_MAX ) ; } /* Obsolete ! */ + void getValue ( bool *b ) { re_eval () ; *b = *getBooleanp () ; } + + int getValue ( void ) { return getIntegerValue () ; } /* Obsolete ! */ + + virtual int getIntegerValue ( void ) { re_eval () ; return *getIntegerp () ; } + virtual float getFloatValue ( void ) { re_eval () ; return *getFloaterp () ; } + virtual char getCharValue ( void ) { re_eval () ; return getStringp ()[0]; } + virtual char *getStringValue ( void ) { re_eval () ; return getStringp () ; } + virtual bool getBooleanValue ( void ) { re_eval () ; return *getBooleanp () ; } + + /* RTTI */ + ulRTTItypeid getTypeInfo ( void ) const { return RTTI_vinfo () ; } +} ; + +typedef void (*puCallback)(class puObject *) ; +typedef void (*puRenderCallback)(class puObject *, int dx, int dy, void *) ; + +void puSetDefaultStyle ( int style ) ; +int puGetDefaultStyle ( void ) ; +void puSetDefaultBorderThickness ( int t ) ; +int puGetDefaultBorderThickness ( void ) ; +void puSetDefaultFonts ( puFont legendFont, puFont labelFont ) ; +void puGetDefaultFonts ( puFont *legendFont, puFont *labelFont ) ; + +puFont puGetDefaultLabelFont ( void ) ; +puFont puGetDefaultLegendFont ( void ) ; + +void puSetDefaultColourScheme ( float r, float g, float b, float a = 1.0f ) ; +inline void puSetDefaultColorScheme ( float r, float g, float b, float a = 1.0f ) +{ + puSetDefaultColourScheme ( r, g, b, a ) ; +} + +void puGetDefaultColourScheme ( float *r, float *g, float *b, float *a = NULL ); +inline void puGetDefaultColorScheme ( float *r, float *g, float *b, float *a = NULL ) +{ + puGetDefaultColourScheme ( r, g, b, a ) ; +} + +class puObject : public puValue +{ + UL_TYPE_DATA + +protected: + puValue default_value ; + + puBox bbox ; /* Bounding box of entire Object */ + puBox abox ; /* Active (clickable) area */ + puColour colour [ PUCOL_MAX ] ; + puGroup *parent ; + + int active_mouse_edge ; /* is it PU_UP or PU_DOWN (or both) that activates this? */ + int active_mouse_button ; /* which mouse button or buttons activate this */ + int style ; + int visible ; + int active ; + int highlighted ; + int am_default ; + int window ; /* Which window does the object appear in? */ + int v_status ; /* 1 if the Object should lock in the top left corner, 0 if not */ + + const char *label ; puFont labelFont ; int labelPlace ; + const char *legend ; puFont legendFont ; int legendPlace ; + + void *user_data ; + puCallback cb ; + puCallback active_cb ; + puCallback down_cb ; + puRenderCallback r_cb ; + void *render_data ; + int border_thickness ; + + short when_to_deactivate ; /* On next mouseclick or on next widget activation */ + + virtual void draw_legend ( int dx, int dy ) ; + virtual void draw_label ( int dx, int dy ) ; + +public: + virtual int isHit ( int x, int y ) const { return isVisible() && isActive() && + x > abox.min[0] && + x < abox.max[0] && + y > abox.min[1] && + y < abox.max[1] && + window == puGetWindow () ; } + + virtual void doHit ( int button, int updown, int x, int y ) ; + + puObject ( int minx, int miny, int maxx, int maxy ) ; + ~puObject () ; + + puObject *next ; /* Should not be used directly by applications any longer. */ + puObject *prev ; /* Instead, use the setNextObject and setPrevObject + methods. */ + + puBox *getBBox ( void ) const { return (puBox *) &bbox ; } + puBox *getABox ( void ) const { return (puBox *) &abox ; } + + void getAbsolutePosition ( int *x, int *y ) const ; + + virtual void setPosition ( int x, int y ) + { + if ( abox.isEmpty() ) + { + abox.max[0] = abox.min[0] = x ; + abox.max[1] = abox.min[1] = y ; + } + else + { + abox.max[0] += x - abox.min[0] ; + abox.max[1] += y - abox.min[1] ; + abox.min[0] = x ; + abox.min[1] = y ; + } + recalc_bbox() ; puPostRefresh () ; + } + + virtual void setSize ( int w, int h ) + { + abox.max[0] = abox.min[0] + w ; + abox.max[1] = abox.min[1] + h ; + recalc_bbox() ; puPostRefresh () ; + } + + void getPosition ( int *x, int *y ) const + { + if ( abox.isEmpty () ) + { + if ( x ) *x = 0 ; + if ( y ) *y = 0 ; + } + else + { + if ( x ) *x = abox.min[0] ; + if ( y ) *y = abox.min[1] ; + } + } + + void getSize ( int *w, int *h ) const + { + if ( abox.isEmpty () ) + { + if ( w ) *w = 0 ; + if ( h ) *h = 0 ; + } + else + { + if ( w ) *w = abox.max[0] - abox.min[0] ; + if ( h ) *h = abox.max[1] - abox.min[1] ; + } + } + + virtual void recalc_bbox ( void ) ; + virtual int checkHit ( int button, int updown, int x, int y ) ; + virtual int checkKey ( int key , int updown ) ; + virtual void draw ( int dx, int dy ) = 0 ; + + puGroup *getParent ( void ) const { return parent ; } + void setParent ( puGroup* p ) { parent = p ; } + + void setNextObject ( puObject *obj ) { next = obj ; } + puObject *getNextObject ( void ) const { return next ; } + void setPrevObject ( puObject *obj ) { prev = obj ; } + puObject *getPrevObject ( void ) const { return prev ; } + + void setCallback ( puCallback c ) { cb = c ; } + puCallback getCallback ( void ) const { return cb ; } + void invokeCallback ( void ) { if ( cb != NULL ) (*cb)(this) ; } + + void setActiveCallback ( puCallback c ) { active_cb = c ; } + puCallback getActiveCallback ( void ) const { return active_cb ; } + void invokeActiveCallback ( void ) { if ( active_cb != NULL ) (*active_cb)(this) ; } + + void setDownCallback ( puCallback c ) { down_cb = c ; } + puCallback getDownCallback ( void ) const { return down_cb ; } + virtual void invokeDownCallback ( void ) { if ( down_cb != NULL ) (*down_cb)(this) ; } + + void setRenderCallback ( puRenderCallback c, void *d = NULL ) { r_cb = c ; render_data = d ; } + puRenderCallback getRenderCallback ( void ) const { return r_cb ; } + void *getRenderCallbackData ( void ) const { return render_data ; } + void invokeRenderCallback ( int dx, int dy ) { if ( r_cb != NULL ) (*r_cb)(this, dx, dy, render_data) ; } + + void setBorderThickness ( int t ) { border_thickness = t ; puPostRefresh () ; } + int getBorderThickness ( void ) const { return border_thickness ; } + + void makeReturnDefault ( int def ) { am_default = def ; puPostRefresh () ; } + int isReturnDefault ( void ) const { return am_default ; } + + int getWindow ( void ) const { return window ; } + void setWindow ( int w ) { window = w ; puPostRefresh () ; } + + void setActiveDirn ( int e ) { active_mouse_edge = e ; } + int getActiveDirn ( void ) const { return active_mouse_edge ; } + + void setActiveButton ( int b ) { active_mouse_button = b ; } + int getActiveButton ( void ) const { return active_mouse_button ; } + + void setWhenToDeactivate ( short d ) { when_to_deactivate = d ; } + short getWhenToDeactivate ( void ) const { return when_to_deactivate ; } + + void setLegend ( const char *l ) { legend = l ; recalc_bbox() ; puPostRefresh () ; } + const char *getLegend ( void ) const { return legend ; } + + void setLegendFont ( puFont f ) { legendFont = f ; recalc_bbox() ; puPostRefresh () ; } + puFont getLegendFont ( void ) const { return legendFont ; } + + void setLegendPlace ( int lp ) { legendPlace = lp ; recalc_bbox() ; puPostRefresh () ; } + int getLegendPlace ( void ) const { return legendPlace ; } + + void setLabel ( const char *l ) { label = l ; recalc_bbox() ; puPostRefresh () ; } + const char *getLabel ( void ) const { return label ; } + + void setLabelFont ( puFont f ) { labelFont = f ; recalc_bbox() ; puPostRefresh () ; } + puFont getLabelFont ( void ) const { return labelFont ; } + + void setLabelPlace ( int lp ) { labelPlace = lp ; recalc_bbox() ; puPostRefresh () ; } + int getLabelPlace ( void ) const { return labelPlace ; } + + void activate ( void ) { if ( ! active ) { active = TRUE ; puPostRefresh () ; } } + void greyOut ( void ) { if ( active ) { active = FALSE ; puPostRefresh () ; } } + int isActive ( void ) const { return active ; } + + void highlight ( void ) { if ( ! highlighted ) { highlighted = TRUE ; puPostRefresh () ; } } + void lowlight ( void ) { if ( highlighted ) { highlighted = FALSE ; puPostRefresh () ; } } + int isHighlighted( void ) const { return highlighted ; } + + void reveal ( void ) { if ( ! visible ) { visible = TRUE ; puPostRefresh () ; } } + void hide ( void ) { if ( visible ) { visible = FALSE ; puPostRefresh () ; } } + int isVisible ( void ) const { return visible ; } + + void setStyle ( int which ) + { + style = which ; + + switch ( abs(style) ) + { + case PUSTYLE_SPECIAL_UNDERLINED : + border_thickness = 1 ; + break ; + + case PUSTYLE_SMALL_BEVELLED : + case PUSTYLE_SMALL_SHADED : + case PUSTYLE_BOXED : + border_thickness = 2 ; + break ; + + case PUSTYLE_BEVELLED : + case PUSTYLE_SHADED : + case PUSTYLE_DROPSHADOW : + border_thickness = 5 ; + break ; + } + + recalc_bbox () ; + puPostRefresh () ; + } + + int getStyle ( void ) const { return style ; } + + virtual void setColourScheme ( float r, float g, float b, float a = 1.0f ) ; + void setColorScheme ( float r, float g, float b, float a = 1.0f ) + { + setColourScheme ( r, g, b, a ) ; + } + + virtual void setColour ( int which, float r, float g, float b, float a = 1.0f ) + { + puSetColour ( colour [ which ], r, g, b, a ) ; + puPostRefresh () ; + } + void setColor ( int which, float r, float g, float b, float a = 1.0f ) + { + setColour ( which, r, g, b, a ) ; + } + + void getColour ( int which, float *r, float *g, float *b, float *a = NULL ) const + { + if ( r ) *r = colour[which][0] ; + if ( g ) *g = colour[which][1] ; + if ( b ) *b = colour[which][2] ; + if ( a ) *a = colour[which][3] ; + } + void getColor ( int which, float *r, float *g, float *b, float *a = NULL ) const + { + getColour ( which, r, g, b, a ); + } + + void setUserData ( void *data ) { user_data = data ; } + void *getUserData ( void ) const { return user_data ; } + + void defaultValue ( void ) { setValue ( & default_value ) ; } + + void setDefaultValue ( int i ) { default_value.setValue ( i ) ; } + void setDefaultValue ( float f ) { default_value.setValue ( f ) ; } + void setDefaultValue ( const char *s ) { default_value.setValue ( s ) ; } + + void getDefaultValue ( int *i ) { default_value.getValue ( i ) ; } + void getDefaultValue ( float *f ) { default_value.getValue ( f ) ; } + void getDefaultValue ( char **s ) { default_value.getValue ( s ) ; } + void getDefaultValue ( char *s ) { default_value.getValue ( s ) ; } + + int getDefaultValue ( void ) { return default_value.getValue () ; } /* Obsolete ! */ + + int getDefaultIntegerValue ( void ) { return default_value.getIntegerValue () ; } + float getDefaultFloatValue ( void ) { return default_value.getFloatValue () ; } + char *getDefaultStringValue ( void ) { return default_value.getStringValue () ; } + + int getVStatus ( void ) const { return v_status ; } /* JCJ 6 Jun 2002 */ + void setVStatus ( int vstat ) { v_status = vstat ; } +} ; + +/* + The 'live' interface stack is used for clicking and rendering. +*/ + +void puPushLiveInterface ( puInterface *in ) ; +void puPopLiveInterface ( puInterface *in = 0 ) ; +int puNoLiveInterface ( void ) ; +puInterface *puGetBaseLiveInterface ( void ) ; +puInterface *puGetUltimateLiveInterface ( void ) ; + +/* + The regular group stack is used for adding widgets +*/ + +void puPushGroup ( puGroup *in ) ; +void puPopGroup ( void ) ; +int puNoGroup ( void ) ; +puGroup *puGetCurrGroup ( void ) ; + +class puGroup : public puObject +{ + UL_TYPE_DATA + +protected: + int num_children ; + puObject *dlist ; + + int mouse_x ; // Coordinates of mouse when right button pressed for + int mouse_y ; // drag and drop + + int mouse_active; // Flag telling whether interface is presently being dragged + + void doHit ( int button, int updown, int x, int y ) ; + + int floating; // DEPRECATED! -- Flag telling whether the interface floats in the window or stays put + +public: + + puGroup ( int x, int y ) : puObject ( x, y, x, y ) + { + type |= PUCLASS_GROUP ; + dlist = NULL ; + num_children = 0 ; + mouse_x = 0 ; + mouse_y = 0 ; + mouse_active = FALSE ; + floating = FALSE ; // DEPRECATED! + puPushGroup ( this ) ; + } + + ~puGroup () ; + + void recalc_bbox ( void ) ; + virtual void add ( puObject *new_object ) ; + virtual void remove ( puObject *old_object ) ; + virtual void empty ( void ) ; + + void draw ( int dx, int dy ) ; + int checkHit ( int button, int updown, int x, int y ) ; + int checkKey ( int key , int updown ) ; + + puObject *getFirstChild ( void ) const { return dlist ; } + puObject *getLastChild ( void ) const + { + puObject *bo = dlist ; + + if ( bo != NULL ) + { + while ( bo -> getNextObject() != NULL ) + bo = bo -> getNextObject() ; + } + + return bo ; + } + int getNumChildren ( void ) const { return num_children ; } + + virtual void close ( void ) + { + if ( puGetCurrGroup () != this ) + ulSetError ( UL_WARNING, "PUI: puGroup::close() is mismatched!" ) ; + else + puPopGroup () ; + } + + void setFloating ( int value ) { floating = value ; } // DEPRECATED! + int getFloating ( void ) const { return floating ; } // DEPRECATED! + + void setChildStyle ( int childs, int which, int recursive = FALSE ) ; + void setChildBorderThickness ( int childs, int t, int recursive = FALSE ) ; + + void setChildColour ( int childs, int which, + float r, float g, float b, float a = 1.0f, + int recursive = FALSE ) ; + void setChildColor ( int childs, int which, + float r, float g, float b, float a = 1.0f, + int recursive = FALSE ) + { + setChildColour ( childs, which, r, g, b, a, recursive ) ; + } + + void setChildColourScheme ( int childs, + float r, float g, float b, float a = 1.0f, + int recursive = FALSE ) ; + void setChildColorScheme ( int childs, + float r, float g, float b, float a = 1.0f, + int recursive = FALSE ) + { + setChildColourScheme ( childs, r, g, b, a, recursive ) ; + } + + void setChildLegendFont ( int childs, puFont f, int recursive = FALSE ) ; + void setChildLabelFont ( int childs, puFont f, int recursive = FALSE ) ; +} ; + + +class puInterface : public puGroup +{ + UL_TYPE_DATA + +public: + + puInterface ( int x, int y ) : puGroup ( x, y ) + { + type |= PUCLASS_INTERFACE ; + puPushLiveInterface ( this ) ; + } + + ~puInterface () ; +} ; + + +class puFrame : public puObject +{ + UL_TYPE_DATA + +public: + void draw ( int dx, int dy ) ; + puFrame ( int minx, int miny, int maxx, int maxy ) : + puObject ( minx, miny, maxx, maxy ) + { + type |= PUCLASS_FRAME ; + } + + void doHit ( int button, int updown, int x, int y ) + { + if ( puActiveWidget() && ( this != puActiveWidget() ) ) + { + // Active widget exists and is not this one; call its down callback if it exists + + puActiveWidget() -> invokeDownCallback () ; + puDeactivateWidget () ; + } + + if ( isHit ( x, y ) && ( updown != PU_DRAG ) ) + puMoveToLast ( this -> parent ); + } +} ; + + + +class puText : public puObject +{ + UL_TYPE_DATA + +public: + virtual int isHit ( int /* x */, int /* y */ ) const { return FALSE ; } + void draw ( int dx, int dy ) ; + puText ( int x, int y ) : puObject ( x, y, x, y ) + { + type |= PUCLASS_TEXT ; + } +} ; + + +class puButton : public puObject +{ + UL_TYPE_DATA + +protected: + int button_type ; + +public: + void doHit ( int button, int updown, int x, int y ) ; + void draw ( int dx, int dy ) ; + + int getButtonType ( void ) const { return button_type ; } + void setButtonType ( int btype ) { button_type = btype ; puPostRefresh () ; } + + puButton ( int minx, int miny, const char *l ) : + puObject ( minx, miny, + minx + puGetDefaultLegendFont().getStringWidth ( l ) + PUSTR_LGAP + PUSTR_RGAP, + miny + puGetDefaultLegendFont().getStringHeight ( l ) + puGetDefaultLegendFont().getStringDescender () + PUSTR_TGAP + PUSTR_BGAP ) + { + type |= PUCLASS_BUTTON ; + button_type = PUBUTTON_NORMAL ; + setLegend ( l ) ; + } + + puButton ( int minx, int miny, int maxx, int maxy, int btype = PUBUTTON_NORMAL ) : + puObject ( minx, miny, maxx, maxy ) + { + type |= PUCLASS_BUTTON ; + button_type = btype ; + } +} ; + + +class puOneShot : public puButton +{ + UL_TYPE_DATA + +protected: +public: + void doHit ( int button, int updown, int x, int y ) ; + + puOneShot ( int minx, int miny, const char *l ) : puButton ( minx, miny, l ) + { + type |= PUCLASS_ONESHOT ; + } + + puOneShot ( int minx, int miny, int maxx, int maxy ) : + puButton ( minx, miny, maxx, maxy ) + { + type |= PUCLASS_ONESHOT ; + } +} ; + + + +class puArrowButton : public puOneShot +{ + UL_TYPE_DATA + +protected: + int arrow_type ; + +public: + void draw ( int dx, int dy ) ; + + int getArrowType ( void ) const { return arrow_type ; } + void setArrowType ( int i ) { arrow_type = i ; puPostRefresh () ; } + + puArrowButton ( int minx, int miny, int maxx, int maxy, int ptype ) : + puOneShot ( minx, miny, maxx, maxy ) + { + type |= PUCLASS_ARROW ; + arrow_type = ptype ; + } +} ; + +class puRange +{ + UL_TYPE_DATA + +protected: + float minimum_value ; + float maximum_value ; + float step_size ; + float last_cb_value ; + float cb_delta ; + int cb_mode ; + + void puRange_init ( float minval, float maxval, float step ) + { + if ( maxval == minval ) + { + maxval = 1.0f ; + minval = 0.0f ; + } + + minimum_value = minval ; + maximum_value = maxval ; + step_size = step ; + last_cb_value = -1.0f ; + cb_delta = 0.1f ; + cb_mode = PUSLIDER_ALWAYS ; + } + + float clamp ( float f ) + { + if ( f < minimum_value ) return minimum_value ; + else if ( f > maximum_value ) return maximum_value ; + return f ; + } + +public: + puRange () + { + puRange_init ( 0.0f, 1.0f, 0.0f ) ; + } + + puRange ( float minval, float maxval, float step = 0.0f ) + { + puRange_init ( minval, maxval, step ) ; + } + + virtual ~puRange() + { + } + + float getMaxValue ( void ) const { return maximum_value ; } + virtual void setMaxValue ( float f ) { maximum_value = f ; } + + float getMinValue ( void ) const { return minimum_value ; } + virtual void setMinValue ( float f ) { minimum_value = f ; } + + float getStepSize ( void ) const { return step_size ; } + void setStepSize ( float f ) { step_size = f ; } + + float checkStep ( float val_to_check ) const + { + float step = val_to_check ; + + if ( getStepSize () > 0.0f ) + { + step = val_to_check - (float) fmod ( val_to_check, getStepSize () ) ; + + if ( ( val_to_check - step ) > ( step + getStepSize() - val_to_check ) ) + step += getStepSize () ; + } + + return step ; + } + + void setCBMode ( int m ) { cb_mode = m ; } + int getCBMode ( void ) const { return cb_mode ; } + + void setDelta ( float f ) { cb_delta = (f<=0.0f) ? 0.1f : (f>=1.0f) ? 0.9f : f ; } + float getDelta ( void ) const { return cb_delta ; } +} ; + +class puSlider : public puRange, public puObject +{ + UL_TYPE_DATA + +protected: + int vert ; + int start_offset ; + float slider_fraction ; + float page_step_size ; + void draw_slider_box ( int dx, int dy, const puBox &box, float val, const char *box_label = NULL ) ; + + void puSlider_init ( int vertical ) + { + type |= PUCLASS_SLIDER ; + vert = vertical ; + slider_fraction = 0.1f ; + page_step_size = 0.0f ; + } + +public: + void doHit ( int button, int updown, int x, int y ) ; + void draw ( int dx, int dy ) ; + puSlider ( int minx, int miny, int sz, int vertical = FALSE ) : + puRange (), + puObject ( minx, miny, vertical ? + ( minx + puGetDefaultLegendFont().getStringWidth ( "W" ) + + PUSTR_LGAP + PUSTR_RGAP ) : + ( minx + sz ), + vertical ? + ( miny + sz ) : + ( miny + puGetDefaultLegendFont().getStringHeight () + + puGetDefaultLegendFont().getStringDescender () + + PUSTR_TGAP + PUSTR_BGAP ) + ) + { + puSlider_init ( vertical ) ; + } + + /* Blake Friesen - alternate constructor which lets you explicitly set width */ + puSlider ( int minx, int miny, int sz, int vertical, int width ) : + puRange (), + puObject ( minx, miny, vertical ? + ( minx + width ) : + ( minx + sz ), + vertical ? + ( miny + sz ) : + ( miny + width ) + ) + { + puSlider_init ( vertical ) ; + } + + int isVertical ( void ) const { return vert ; } + + void setSliderFraction ( float f ) ; + float getSliderFraction ( void ) const { return slider_fraction ; } + void setPageStepSize ( float s ) { page_step_size = s ; } + float getPageStepSize ( void ) const { return page_step_size ; } +} ; + + +class puListBox : public puButton +{ + UL_TYPE_DATA + +protected: + char ** list ; + int num ; + int top ; + +public: + void doHit ( int button, int updown, int x, int y ) ; + void draw ( int dx, int dy ) ; + puListBox ( int minx, int miny, int maxx, int maxy, char** list = NULL ) ; + + void newList ( char ** _list ) ; + int getNumItems ( void ) const { return num ; } + int getNumVisible ( void ) const + { + int ysize = abox.max[1] - abox.min[1] + 1 ; + int yinc = legendFont.getStringHeight () + PUSTR_BGAP ; + return (ysize - PUSTR_BGAP) / yinc ; + } + + int getTopItem ( void ) const { return top ; } + void setTopItem ( int item_index ) ; +} ; + + +class puDial : public puRange, public puObject +{ + UL_TYPE_DATA + +protected: + int wrap ; // Flag telling whether you can wrap around the bottom of the dial +public: + void doHit ( int button, int updown, int x, int y ) ; + void draw ( int dx, int dy ) ; + + puDial ( int minx, int miny, int sz ) : + puRange (), puObject ( minx, miny, minx+sz, miny+sz ) + { + type |= PUCLASS_DIAL ; + setValue ( 0.0f ) ; + wrap = TRUE ; + } + + puDial ( int minx, int miny, int sz, float minval, float maxval, float step = 0.0f ) : + puRange ( minval, maxval, step ), + puObject ( minx, miny, minx+sz, miny+sz ) + { + type |= PUCLASS_DIAL ; + setValue ( 0.0f ) ; + wrap = TRUE ; + } + + void setWrap ( int in ) { wrap = in ; } + int getWrap ( void ) const { return wrap ; } +} ; + + + +class puPopup : public puInterface +{ + UL_TYPE_DATA + +protected: +public: + puPopup ( int x, int y ) : puInterface ( x, y ) + { + type |= PUCLASS_POPUP ; + hide () ; + } +} ; + + +class puPopupMenu : public puPopup +{ + UL_TYPE_DATA + +protected: +public: + puPopupMenu ( int x, int y ) : puPopup ( x, y ) + { + type |= PUCLASS_POPUPMENU ; + } + + puObject *add_item ( const char *str, puCallback _cb, + void *_user_data = NULL ) ; + int checkHit ( int button, int updown, int x, int y ) ; + int checkKey ( int key , int updown ) ; + void close ( void ) ; +} ; + + +class puMenuBar : public puInterface +{ + UL_TYPE_DATA + +protected: + int bar_height ; + +public: + puMenuBar ( int h = -1 ) : puInterface ( 0, 0 ) + { + type |= PUCLASS_MENUBAR ; + + bar_height = h ; + } + + void add_submenu ( const char *str, char *items[], puCallback _cb[], + void *_user_data[] = NULL ) ; + void close ( void ) ; +} ; + + +class puInputBase +{ + UL_TYPE_DATA + +protected: + int accepting ; + int cursor_position ; + int select_start_position ; + int select_end_position ; + char *valid_data ; + int input_disabled ; + + char *displayed_text ; // Pointer to text as it is displayed in the box (chopped or word-wrapped) + + puObject *widget ; /* Pointer to associated input box widget */ + + virtual void normalizeCursors ( void ) ; + virtual void removeSelectRegion ( void ) ; + +public: + int isAcceptingInput ( void ) const { return accepting ; } + void rejectInput ( void ) { accepting = FALSE ; puPostRefresh () ; } + + void acceptInput ( void ) + { + accepting = TRUE ; + cursor_position = strlen ( widget -> getStringValue () ) ; + select_start_position = select_end_position = -1 ; + puPostRefresh () ; + } + + int getCursor ( void ) const { return cursor_position ; } + void setCursor ( int c ) { cursor_position = c ; puPostRefresh () ; } + + virtual void setSelectRegion ( int s, int e ) + { + select_start_position = s ; + select_end_position = e ; + puPostRefresh () ; + } + + void getSelectRegion ( int *s, int *e ) const + { + if ( s ) *s = select_start_position ; + if ( e ) *e = select_end_position ; + } + + char *getValidData ( void ) const { return valid_data ; } + void setValidData ( const char *data ) + { + delete [] valid_data ; + valid_data = ( data != NULL ) ? ulStrDup ( data ) : NULL ; + } + + void addValidData ( const char *data ) ; + + int isValidCharacter ( char c ) const + { + if ( valid_data != NULL ) + return ( strchr ( valid_data, c ) != NULL ) ? 1 : 0 ; + else + return 1 ; + } + + void enableInput ( void ) { input_disabled = FALSE ; } + void disableInput ( void ) { input_disabled = TRUE ; } + int inputDisabled ( void ) const { return input_disabled ; } + + puInputBase ( void ) + { + accepting = FALSE ; + cursor_position = 0 ; + select_start_position = -1 ; + select_end_position = -1 ; + valid_data = NULL; + displayed_text = NULL ; + + widget = (puObject *)NULL ; + + input_disabled = FALSE ; + } + + virtual ~puInputBase () { delete [] valid_data ; delete [] displayed_text ; } +} ; + + +class puInput : public puInputBase, public puObject +{ + UL_TYPE_DATA + + int display_starting_point ; + + char *getDisplayedText ( void ) + { + return ( displayed_text == NULL ? getStringValue () : displayed_text ) ; + } + +public: + void draw ( int dx, int dy ) ; + void doHit ( int button, int updown, int x, int y ) ; + int checkKey ( int key, int updown ) ; + + void invokeDownCallback ( void ) + { + rejectInput () ; + normalizeCursors () ; + if ( down_cb != NULL ) (*down_cb)(this) ; + } + + puInput ( int minx, int miny, int maxx, int maxy ) : + puInputBase (), puObject ( minx, miny, maxx, maxy ) + { + type |= PUCLASS_INPUT ; + + display_starting_point = 0 ; + + setColourScheme ( colour [ PUCOL_EDITFIELD ][0], + colour [ PUCOL_EDITFIELD ][1], + colour [ PUCOL_EDITFIELD ][2], + colour [ PUCOL_EDITFIELD ][3] ) ; + setColour ( PUCOL_MISC, 0.1f, 0.1f, 1.0f ) ; /* Colour of 'I' bar cursor */ + + widget = this ; + } + + virtual void setValue ( puValue *pv ) + { + puValue::setValue ( pv ) ; + delete [] displayed_text ; displayed_text = NULL ; + } + + virtual void setValue ( int i ) + { + puValue::setValue ( i ) ; + delete [] displayed_text ; displayed_text = NULL ; + } + + virtual void setValue ( float f ) + { + puValue::setValue ( f ) ; + delete [] displayed_text ; displayed_text = NULL ; + } + + virtual void setValue ( const char *s ) + { + puValue::setValue ( s ) ; + delete [] displayed_text ; displayed_text = NULL ; + } + + virtual void setValue ( bool b ) + { + puValue::setValue ( b ) ; + delete [] displayed_text ; displayed_text = NULL ; + } +} ; + + +class puButtonBox : public puObject +{ + UL_TYPE_DATA + +protected: + int one_only ; + int num_kids ; + char **button_labels ; + +public: + + puButtonBox ( int minx, int miny, int maxx, int maxy, + char **labels, int one_button ) ; + + int isOneButton ( void ) const { return one_only ; } + + void newList ( char ** _list ) ; + int getNumItems ( void ) const { return num_kids ; } + + int checkKey ( int key , int updown ) ; + int checkHit ( int button, int updown, int x, int y ) ; + void draw ( int dx, int dy ) ; +} ; + + +class puDialogBox : public puPopup +{ + UL_TYPE_DATA + +protected: +public: + + puDialogBox ( int x, int y ) : puPopup ( x, y ) + { + type |= PUCLASS_DIALOGBOX ; + } +} ; + + + +/* + * Window System Integration + * ------------------------- + * + * PUI has direct support for GLUT, PW, FLTK, SDL and GTK. All code is provided + * inline, making PUI itself independent. There are several ways to choose + * implementation, for instance: + * + * #include + * #include + * + * or simply: + * + * #include + * + * Note that both cases may fail if pu.h has been included earlier. + * A safer option is therefore to compile with -DPU_USE_FLTK. + * + * The default system is GLUT for backwards compability. + * + * To use PUI with an unsupported system, define PU_USE_NONE and + * provide your own callbacks (if needed, the defaults will work + * in many cases). + * + * When compiling the PUI library itself, PU_USE_NONE must be defined. + * + */ + +typedef int (*puGetWindowCallback) ( ) ; +typedef void (*puSetWindowCallback) ( int window ) ; +typedef void (*puGetWindowSizeCallback) ( int *width, int *height ) ; +typedef void (*puSetWindowSizeCallback) ( int width, int height ) ; + +void puSetWindowFuncs ( puGetWindowCallback, + puSetWindowCallback, + puGetWindowSizeCallback, + puSetWindowSizeCallback ) ; + + +// Choose implementation + +#if !defined(PU_USE_GLUT) && \ + !defined(PU_USE_PW) && \ + !defined(PU_USE_FLTK) && \ + !defined(PU_USE_SDL) && \ + !defined(PU_USE_NATIVE) && \ + !defined(PU_USE_NONE) + +// Nothing selected. Try to figure out which one to use. +#if defined(PW_IS_PRESENT) +# define PU_USE_PW +#elif defined(FL_MAJOR_VERSION) +# define PU_USE_FLTK +#elif defined(SDL_MAJOR_VERSION) +# define PU_USE_SDL +#else +# define PU_USE_GLUT +#endif + +#endif + + +// Roll out the code and define puInit + +#if defined(PU_USE_GLUT) +# include "puGLUT.h" +# define puInit puInitGLUT +#elif defined(PU_USE_PW) +# include "puPW.h" +# define puInit puInitPW +#elif defined(PU_USE_FLTK) +# include "puFLTK.h" +# define puInit puInitFLTK +#elif defined(PU_USE_SDL) +# include "puSDL.h" +# define puInit puInitSDL +#elif defined(PU_USE_NATIVE) +# include "puNative.h" +# define puInit puInitNative +#else +# define puInit +#endif + + +#endif diff --git a/include/plib/puAux.h b/include/plib/puAux.h new file mode 100644 index 0000000..b2c8898 --- /dev/null +++ b/include/plib/puAux.h @@ -0,0 +1,944 @@ +/* + PUI Auxiliary Widget Library + Derived from PLIB, the Portable Game Library by Steve Baker. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: puAux.h 2160 2010-02-27 03:48:23Z fayjf $ +*/ + +#ifndef _PUI_AUX_WIDGETS_H_ +#define _PUI_AUX_WIDGETS_H_ 1 + +#include "pu.h" + +// Widget Class Bit Patterns +// PUI classes take up 0x00000001 through 0x00020000 + +#define PUCLASS_FILESELECTOR 0x00040000 /* Because FilePicker is obsolete */ +#define PUCLASS_BISLIDER 0x00080000 +#define PUCLASS_TRISLIDER 0x00100000 +#define PUCLASS_VERTMENU 0x00200000 +#define PUCLASS_LARGEINPUT 0x00400000 +#define PUCLASS_COMBOBOX 0x00800000 +#define PUCLASS_SELECTBOX 0x01000000 +#define PUCLASS_SPINBOX 0x02000000 +#define PUCLASS_SCROLLBAR 0x04000000 +#define PUCLASS_BISLIDERWITHENDS 0x08000000 +#define PUCLASS_SLIDERWITHINPUT 0x10000000 +#define PUCLASS_COMPASS 0x20000000 +#define PUCLASS_CHOOSER 0x40000000 +#define PUCLASS_LIST 0x80000000 + + +// Widget Declarations +class puaSpinBox ; +class puaFileSelector ; +class puaBiSlider ; +class puaTriSlider ; +class puaVerticalMenu ; +class puaLargeInput ; +class puaComboBox ; +class puaSelectBox ; +class puaScrollBar ; +class puaBiSliderWithEnds ; +class puaCompass ; +class puaSliderWithInput ; +class puaChooser ; +class puaList ; + + +// A File selector widget +class puaFileSelector : public puDialogBox +{ + UL_TYPE_DATA + +protected: + char** files ; + char* dflag ; + int num_files ; + int arrow_count ; + + char *startDir ; + + void find_files ( void ) ; + static void handle_select ( puObject* ) ; + static void input_entered ( puObject* ) ; + + puFrame *frame ; + puListBox *list_box ; + puSlider *slider ; + puOneShot *cancel_button ; + puOneShot *ok_button ; + puInput *input ; + puArrowButton *up_arrow ; + puArrowButton *down_arrow ; + puArrowButton *fastup_arrow ; + puArrowButton *fastdown_arrow ; + + void puaFileSelectorInit ( int x, int y, int w, int h, + int arrows, const char *dir, const char *title ) ; + +public: + + puaFileSelector ( int x, int y, int w, int h, int arrows, + const char *dir, const char *title = "Pick a file" ) : + puDialogBox ( x, y ) + { + puaFileSelectorInit ( x, y, w, h, arrows, dir, title ) ; + } + + puaFileSelector ( int x, int y, int w, int h, + const char *dir, const char *title = "Pick a file" ) : + puDialogBox ( x, y ) + { + puaFileSelectorInit ( x, y, w, h, 1, dir, title ) ; + } + + puaFileSelector ( int x, int y, int arrows, + const char *dir, const char *title = "Pick a file" ) : + puDialogBox ( x, y ) + { + puaFileSelectorInit ( x, y, 220, 170, arrows, dir, title ) ; + } + + puaFileSelector ( int x, int y, + const char *dir, const char *title = "Pick a file" ) : + puDialogBox ( x, y ) + { + puaFileSelectorInit ( x, y, 220, 170, 1, dir, title ) ; + } + + ~puaFileSelector () ; + + /* Not for application use!! */ + puInput *__getInput ( void ) const { return input ; } + char *__getStartDir ( void ) const { return (char *) startDir ; } + + void setInitialValue ( const char *fname ) ; + void setSize ( int w, int h ) ; +} ; + + +// An input box that takes an arbitrary number of lines of input +class puaLargeInput : public puInputBase, public puGroup +{ + UL_TYPE_DATA + +protected: + int num_lines ; // Number of lines of text in the box + int lines_in_window ; // Number of lines showing in the window + int top_line_in_window ; // Number of the first line in the window + int max_width ; // Width of longest line of text in box, in pixels + int slider_width ; + int line_height ; // Text height + interline gap + int vgap ; // Gap on top and bottom + int hgap ; // Gap on the left and right side + int input_width ; // Width of display area (widget minus gaps & slider) + int input_height ; // Height of display area + + puFrame *frame ; + puFrame *plug ; // Little square in the bottom right corner + + puaScrollBar *bottom_slider ; // Horizontal slider at bottom of window + puaScrollBar *right_slider ; // Vertical slider at right of window + + int arrow_count ; // Number of up/down arrows above and below the right slider + + void normalizeCursors ( void ) ; + void removeSelectRegion ( void ) ; + void updateGeometry ( void ) ; + + char *wrapText ( int target_width = 0, int *numlines = 0, int *maxwidth = 0 ) ; + void getTextProperties(int *numlines, int *maxwidth) ; + char *getText () { return bottom_slider ? getStringValue () : getDisplayedText () ; } + +public: + puaLargeInput ( int x, int y, int w, int h, int arrows, int sl_width, int wrap_text = FALSE ) ; + ~puaLargeInput () + { + if ( puActiveWidget() == this ) + puDeactivateWidget () ; + } + + void setSize ( int w, int h ) ; + void setLegendFont ( puFont f ) { puGroup::setLegendFont ( f ) ; updateGeometry () ; } + + int getNumLines ( void ) const { return num_lines ; } + int getLinesInWindow ( void ) const { return lines_in_window ; } + void setTopLineInWindow ( int val ) { top_line_in_window = (val<0) ? 0 : ( (val>num_lines-2) ? num_lines-2 : val ) ; } + void setSliderPosition ( float fraction ) ; + + void draw ( int dx, int dy ) ; + int checkHit ( int button, int updown, int x, int y ) ; + void doHit ( int button, int updown, int x, int y ) ; + int checkKey ( int key, int updown ) ; + + void setSelectRegion ( int s, int e ) ; + void selectEntireLine ( void ) ; + + void invokeDownCallback ( void ) + { + rejectInput () ; + normalizeCursors () ; + if ( down_cb != NULL ) (*down_cb)(this) ; + } + + void setValue ( const char *s ) ; + void addNewLine ( const char *l ) ; + void addText ( const char *l ) ; + void appendText ( const char *l ) ; + void removeText ( int start, int end ) ; + char *getDisplayedText ( void ) + { + return ( displayed_text == NULL ? getStringValue () : displayed_text ) ; + } +} ; + + +// A box that contains a set of alternatives that drop down when the user clicks on the down-arrow +// Defined constants telling how the callback got triggered. This is needed for +// cases in which the user has deleted the entry in the input box and wants that +// entry deleted from the list of items. +#define PUACOMBOBOX_CALLBACK_NONE 0 +#define PUACOMBOBOX_CALLBACK_INPUT 1 +#define PUACOMBOBOX_CALLBACK_ARROW 2 +class puaComboBox : public puGroup +{ + UL_TYPE_DATA + +protected: + char ** list ; + int num_items ; + + int curr_item ; + + puInput *input ; + puArrowButton *arrow_btn ; + puPopupMenu *popup_menu ; + + int callback_source ; + + static void input_cb ( puObject *inp ) ; + static void input_active_cb ( puObject *inp ) ; + static void input_down_cb ( puObject *inp ) ; + static void handle_arrow ( puObject *arrow ) ; + static void handle_popup ( puObject *popupm ) ; + + void update_widgets ( void ) ; + void update_current_item ( void ) ; + void setCallbackSource ( int s ) { callback_source = s ; } + +public: + /* Not for application use ! */ + puPopupMenu * __getPopupMenu ( void ) const { return popup_menu ; } + + void newList ( char ** _list ) ; + int getNumItems ( void ) const { return num_items ; } + char *getNewEntry ( void ) const { return input->getStringValue () ; } + + int getCurrentItem ( void ) ; + void setCurrentItem ( int item ) + { + if ( ( item >= 0 ) && ( item < num_items ) ) + { + curr_item = item ; + update_widgets () ; + + callback_source = PUACOMBOBOX_CALLBACK_ARROW ; + invokeCallback () ; + } + } + + void setCurrentItem ( const char *item_ptr ) ; + + void setPosition ( int x, int y ) + { + puGroup::setPosition ( x, y ) ; + + /* Ensure that popup menu will show up at the right place */ + newList ( list ) ; + } + + void setSize ( int w, int h ) ; + + void setValue ( float f ) { puValue::setValue ( f ) ; input->setValue ( f ) ; } + void setValue ( int i ) { puValue::setValue ( i ) ; input->setValue ( i ) ; } + void setValue ( const char *s ) { puValue::setValue ( s ) ; input->setValue ( s ) ; } + void setValue ( puValue *pv ) { puValue::setValue ( pv ) ; input->setValue ( pv ) ; } + + void draw ( int dx, int dy ) ; + int checkHit ( int button, int updown, int x, int y ) ; + int checkKey ( int key, int updown ) ; + + int getCallbackSource ( void ) const { return callback_source ; } + + virtual void setColourScheme ( float r, float g, float b, float a = 1.0f ) ; + virtual void setColour ( int which, float r, float g, float b, float a = 1.0f ) ; + + puaComboBox ( int minx, int miny, int maxx, int maxy, + char **list, int editable = TRUE ) ; + + ~puaComboBox () + { + int i ; + for ( i = 0; i < num_items; i++ ) + delete [] list[i] ; + + delete [] list ; + } +} ; + + +// Like a menu bar, but the selections are one above the other +class puaVerticalMenu : public puGroup +{ + UL_TYPE_DATA + +protected: +public: + puaVerticalMenu ( int x = -1, int y = -1 ) : + + puGroup ( x < 0 ? puGetWindowWidth() - + ( puGetDefaultLegendFont().getStringWidth ( " " ) + + PUSTR_TGAP + PUSTR_BGAP ) : x, + + y < 0 ? puGetWindowHeight() - + ( puGetDefaultLegendFont().getStringHeight () + + PUSTR_TGAP + PUSTR_BGAP ) : y) + { + type |= PUCLASS_VERTMENU ; + floating = TRUE ; // DEPRECATED! -- we need to replace this code. + if ( y < 0 ) { setVStatus( TRUE ) ; } /* It is now supposed to stick to the top left - JCJ*/ + } + + void add_submenu ( const char *str, char *items[], puCallback _cb[], + void *_user_data[] = NULL ) ; + void close ( void ) ; +} ; + + +// Not sure what this one does ... +class puaSelectBox : public puGroup +{ + UL_TYPE_DATA + +protected: + char ** list ; + int num_items ; + + int curr_item ; + + puInput *input ; + puArrowButton *down_arrow ; + puArrowButton *up_arrow ; + + static void handle_arrow ( puObject *arrow ) ; + + void update_widgets ( void ) ; + +public: + void newList ( char ** _list ) ; + int getNumItems ( void ) const { return num_items ; } + + int getCurrentItem ( void ) const { return curr_item ; } + void setCurrentItem ( int item ) + { + if ( ( item >= 0 ) && ( item < num_items ) ) + { + curr_item = item ; + update_widgets () ; + + invokeCallback () ; + } + } + + void setSize ( int w, int h ) ; + void draw ( int dx, int dy ) ; + int checkKey ( int key, int updown ) ; + + virtual void setColourScheme ( float r, float g, float b, float a = 1.0f ) ; + virtual void setColour ( int which, float r, float g, float b, float a = 1.0f ) ; + + puaSelectBox ( int minx, int miny, int maxx, int maxy, + char **list ) ; +} ; + + +// A slider with up- and down-arrows on its ends +class puaScrollBar : public puSlider +{ + UL_TYPE_DATA + +protected: + int arrow_count ; + int active_arrow ; + float line_step_size ; + enum { NONE = 0, FASTDOWN = 1, DOWN = 2, UP = 4, FASTUP = 8 }; + +public: + void doHit ( int button, int updown, int x, int y ) ; + void draw ( int dx, int dy ) ; + int checkHit ( int button, int updown, int x, int y ) ; + puaScrollBar ( int minx, int miny, int sz, int arrows, int vertical = FALSE ) : + puSlider ( minx, miny, sz, vertical ) + { + type |= PUCLASS_SCROLLBAR ; + arrow_count = arrows ; + active_arrow = NONE ; + line_step_size = 0.0f ; + } + + /* Alternate constructor which lets you explicitly set width */ + + puaScrollBar ( int minx, int miny, int sz, int arrows, int vertical, int width ) : + puSlider ( minx, miny, sz, vertical, width ) + { + type |= PUCLASS_SCROLLBAR ; + arrow_count = arrows ; + active_arrow = NONE ; + line_step_size = 0.0f ; + } + + void setMaxValue ( float f ) + { + maximum_value = f ; + slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ; + puPostRefresh () ; + } + + + void setMinValue ( float i ) + { + minimum_value = i ; + slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ; + puPostRefresh () ; + } + + void setLineStepSize ( float s ) { line_step_size = s ; } + float getLineStepSize ( void ) const { return line_step_size ; } +} ; + + + +// A puSlider with two slide boxes instead of one +class puaBiSlider : public puSlider +{ + UL_TYPE_DATA + +protected: + float current_max ; + float current_min ; + + int active_button ; // Zero for none, one for min, two for max +public: + void doHit ( int button, int updown, int x, int y ) ; + void draw ( int dx, int dy ) ; + puaBiSlider ( int minx, int miny, int sz, int vertical = FALSE ) : + puSlider ( minx, miny, sz, vertical ) + { + type |= PUCLASS_BISLIDER ; + setMaxValue ( 1.0f ) ; + setMinValue ( 0.0f ) ; + setStepSize ( 1.0f ) ; + current_max = 1.0f ; + current_min = 0.0f ; + active_button = 0 ; + } + + /* Alternate constructor which lets you explicitly set width */ + + puaBiSlider ( int minx, int miny, int sz, int vertical, int width ) : + puSlider ( minx, miny, sz, vertical, width ) + { + type |= PUCLASS_BISLIDER ; + setMaxValue ( 1.0f ) ; + setMinValue ( 0.0f ) ; + setStepSize ( 1.0f ) ; + current_max = 1.0f ; + current_min = 0.0f ; + active_button = 0 ; + } + + void setMaxValue ( float i ) + { + maximum_value = i ; + slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ; + puPostRefresh () ; + } + + + void setMinValue ( float i ) + { + minimum_value = i ; + slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ; + puPostRefresh () ; + } + + void setCurrentMax ( int i ) { current_max = (float) i ; puPostRefresh () ; } /* DEPRECATED */ + void setCurrentMax ( float f ) { current_max = f ; puPostRefresh () ; } + float getCurrentMax ( void ) const { return current_max ; } + + void setCurrentMin ( int i ) { current_min = (float) i ; puPostRefresh () ; } /* DEPRECATED */ + void setCurrentMin ( float f ) { current_min = f ; puPostRefresh () ; } + float getCurrentMin ( void ) const { return current_min ; } + + void setActiveButton ( int i ) { active_button = i ; } + int getActiveButton ( void ) const { return active_button ; } +} ; + + +// A puSlider with three slide boxes + +class puaTriSlider : public puaBiSlider +{ + UL_TYPE_DATA + +protected: + // "active_button" is now zero for none, one for min, two for middle, three for max + int freeze_ends ; // true to make end sliders unmovable +public: + void doHit ( int button, int updown, int x, int y ) ; + void draw ( int dx, int dy ) ; + puaTriSlider ( int minx, int miny, int sz, int vertical = FALSE ) : + puaBiSlider ( minx, miny, sz, vertical ) + { + type |= PUCLASS_TRISLIDER ; + freeze_ends = TRUE ; + } + + /* Alternate constructor which lets you explicitly set width */ + + puaTriSlider ( int minx, int miny, int sz, int vertical, int width ) : + puaBiSlider ( minx, miny, sz, vertical, width ) + { + type |= PUCLASS_TRISLIDER ; + freeze_ends = TRUE ; + } + + int getFreezeEnds ( void ) const { return freeze_ends ; } + void setFreezeEnds ( int val ) { freeze_ends = val ; puPostRefresh () ; } +} ; + + +// A vertical puBiSlider with a puInput box above it showing the current maximum +// value and a puInput box below it showing the current minimum value + +class puaBiSliderWithEnds : public puGroup +{ + UL_TYPE_DATA + +protected: + puaBiSlider *slider ; + puInput *max_box ; + puInput *min_box ; + + static void handle_slider ( puObject *obj ) ; + static void handle_max ( puObject *obj ) ; + static void handle_min ( puObject *obj ) ; + static void input_down_callback ( puObject *obj ) ; + + void update_widgets ( void ) ; + +public: + // For internal use only: + void __setMax ( float f ) { max_box->setValue ( f ) ; } + void __setMin ( float f ) { min_box->setValue ( f ) ; } + + // For public use: + + void draw ( int dx, int dy ) ; + int checkHit ( int button, int updown, int x, int y ) + { + return puGroup::checkHit ( button, updown, x, y ) ; + } + + int checkKey ( int key, int updown ) ; + + puaBiSliderWithEnds ( int minx, int miny, int maxx, int maxy ) ; + + void setSize ( int w, int h ) ; + + void setMaxValue ( float f ) { slider->setMaxValue ( f ) ; } + float getMaxValue ( void ) const { return slider->getMaxValue () ; } + void setMinValue ( float f ) { slider->setMinValue ( f ) ; } + float getMinValue ( void ) const { return slider->getMinValue () ; } + + void setCurrentMax ( float f ) + { + slider->setCurrentMax ( f ) ; + max_box->setValue ( f ) ; + } + + float getCurrentMax ( void ) const { return slider->getCurrentMax () ; } + + void setCurrentMin ( float f ) + { + slider->setCurrentMin ( f ) ; + min_box->setValue ( f ) ; + } + + float getCurrentMin ( void ) const { return slider->getCurrentMin () ; } + + void setActiveButton ( int i ) { slider->setActiveButton ( i ) ; } + int getActiveButton ( void ) const { return slider->getActiveButton () ; } + + char *getValidData ( void ) const { return max_box->getValidData () ; } + void setValidData ( char *data ) { max_box->setValidData ( data ) ; min_box->setValidData ( data ) ; } + void addValidData ( char *data ) { max_box->addValidData ( data ) ; min_box->addValidData ( data ) ; } + + void setCBMode ( int m ) { slider->setCBMode ( m ) ; } + int getCBMode ( void ) const { return slider->getCBMode () ; } + + void setDelta ( float f ) { slider->setDelta ( f ) ; } + float getDelta ( void ) const { return slider->getDelta () ; } + + float getStepSize ( void ) const { return slider->getStepSize () ; } + void setStepSize ( float f ) { slider->setStepSize ( f ) ; } +} ; + + +// A vertical puSlider with a puInput box above or below it showing its value + +class puaSliderWithInput : public puGroup +{ + UL_TYPE_DATA + +protected: + puSlider *slider ; + puInput *input_box ; + int input_position ; + + static void handle_slider ( puObject *obj ) ; + static void handle_input ( puObject *obj ) ; + static void input_down_callback ( puObject *obj ) ; + + void update_widgets ( void ) ; + +public: + // For internal use only: + void __setInputBox ( float f ) { input_box->setValue ( f ) ; } + + // For public use: + + void draw ( int dx, int dy ) ; + int checkHit ( int button, int updown, int x, int y ) + { + return puGroup::checkHit ( button, updown, x, y ) ; + } + + int checkKey ( int key, int updown ) ; + + puaSliderWithInput ( int minx, int miny, int maxx, int maxy, int above = 0 ) ; + + void setSize ( int w, int h ) ; + + void setMaxValue ( float f ) { slider->setMaxValue ( f ) ; } + float getMaxValue ( void ) const { return slider->getMaxValue () ; } + void setMinValue ( float f ) { slider->setMinValue ( f ) ; } + float getMinValue ( void ) const { return slider->getMinValue () ; } + + void setValue ( int i ) { slider->setValue ( i ) ; input_box->setValue ( i ) ; } + void setValue ( float f ) { slider->setValue ( f ) ; input_box->setValue ( f ) ; } + virtual void setValue ( const char *s ) { slider->setValue ( s ) ; } + virtual void setValue ( bool b ) { slider->setValue ( b ) ; } + + int getIntegerValue ( void ) { return slider->getIntegerValue () ; } + float getFloatValue ( void ) { return slider->getFloatValue () ; } + char getCharValue ( void ) { return slider->getCharValue () ; } + char *getStringValue ( void ) { return slider->getStringValue () ; } + bool getBooleanValue ( void ) { return slider->getBooleanValue () ; } + + char *getValidData ( void ) const { return input_box->getValidData () ; } + void setValidData ( char *data ) { input_box->setValidData ( data ) ; } + void addValidData ( char *data ) { input_box->addValidData ( data ) ; } + + void setCBMode ( int m ) { slider->setCBMode ( m ) ; } + int getCBMode ( void ) const { return slider->getCBMode () ; } + + void setDelta ( float f ) { slider->setDelta ( f ) ; } + float getDelta ( void ) const { return slider->getDelta () ; } + + float getStepSize ( void ) const { return slider->getStepSize () ; } + void setStepSize ( float f ) { slider->setStepSize ( f ) ; } +} ; + +class puaSpinBox : public puRange, public puGroup +{ + UL_TYPE_DATA + +protected : + puInput *input_box ; + puArrowButton *up_arrow ; + puArrowButton *down_arrow ; + + int arrow_position ; + +public : + /* Whether the arrows are on the LEFT of the input box (0) or RIGHT (1 DEFAULT) */ + int getArrowPosition ( void ) const { return arrow_position ; } + /* Offered as a proportion of the input box height. Default = 0.5 */ + void setArrowHeight ( float height ) + { + puBox ibox = *(input_box->getABox()) ; + int size = int(height * ( ibox.max[1] - ibox.min[1] )) ; + up_arrow->setSize ( size, size ) ; + down_arrow->setSize ( size, size ) ; + int xpos = getArrowPosition () ? ibox.max[0] : ibox.min[0] - size ; + int ymid = ( ibox.max[1] + ibox.min[1] ) / 2 ; + if ( getArrowPosition () == 0 ) /* Arrows are on the left, adjust the x-position of the input box */ + { + ibox.min[0] -= xpos ; + input_box->setPosition ( ibox.min[0], ibox.min[1] ) ; + abox.min[0] += xpos ; + xpos = 0 ; + } + + if ( height > 0.5f ) /* Adjust the input box to be up from the bottom */ + { + input_box->setPosition ( ibox.min[0], ibox.min[1] + size - ymid ) ; + abox.min[1] += ymid - size ; + ymid = size ; + } + else /* Input box is at the bottom of the group area */ + { + input_box->setPosition ( ibox.min[0], 0 ) ; + abox.min[1] += ibox.min[1] ; + } + + up_arrow->setPosition ( xpos, ymid ) ; + down_arrow->setPosition ( xpos, ymid - size ) ; + recalc_bbox() ; + } + + float getArrowHeight ( void ) const + { + int awid, ahgt, iwid, ihgt ; + input_box->getSize ( &iwid, &ihgt ) ; + up_arrow->getSize ( &awid, &ahgt ) ; + return float(ahgt) / float(ihgt) ; + } + + puaSpinBox ( int minx, int miny, int maxx, int maxy, int arrow_pos = 1 ) ; + + void setValue ( float f ) { puValue::setValue ( f ) ; input_box->setValue ( f ) ; } + void setValue ( int i ) { puValue::setValue ( i ) ; input_box->setValue ( i ) ; } + void setValue ( const char *s ) { puValue::setValue ( s ) ; input_box->setValue ( s ) ; } + void setValue ( puValue *pv ) { puValue::setValue ( pv ) ; input_box->setValue ( pv ) ; } +} ; + + +/* + * Widget that looks like a 3-d coordinate system with quarter-circles in the coordinate planes. + * It is used in 3-d modeling to translate and rotate the scene. The coordinates rotate with + * the scene but do not translate. Defined values are: + * 0 - Nothing active + * 1 - Dot at origin active: reset (usually) + * 2 - X-axis dot active: rotate about y- and z-axes + * 3 - Y-axis dot active: rotate about z- and x-axes + * 4 - Z-axis dot active: rotate about x- and y-axes + * 5 - X-axis bar active: translate along x-axis + * 6 - Y-axis bar active: translate along y-axis + * 7 - Z-axis bar active: translate along z-axis + * 8 - XY-plane arc active: rotate about z-axis + * 9 - YZ-plane arc active: rotate about x-axis + * 10 - ZX-plane arc active: rotate about y-axis + * 11 - X-axis, Y-axis, and XY-arc active: translate in xy-plane + * 12 - Y-axis, Z-axis, and YZ-arc active: translate in yz-plane + * 13 - Z-axis, X-axis, and ZX-arc active: translate in zx-plane + */ +#define PUACOMPASS_INACTIVE 0 +#define PUACOMPASS_RESET 1 +#define PUACOMPASS_ROTATE_Y_Z 2 +#define PUACOMPASS_ROTATE_Z_X 3 +#define PUACOMPASS_ROTATE_X_Y 4 +#define PUACOMPASS_TRANSLATE_X 5 +#define PUACOMPASS_TRANSLATE_Y 6 +#define PUACOMPASS_TRANSLATE_Z 7 +#define PUACOMPASS_ROTATE_Z 8 +#define PUACOMPASS_ROTATE_X 9 +#define PUACOMPASS_ROTATE_Y 10 +#define PUACOMPASS_TRANSLATE_X_Y 11 +#define PUACOMPASS_TRANSLATE_Y_Z 12 +#define PUACOMPASS_TRANSLATE_Z_X 13 + +class puaCompass : public puObject +{ + UL_TYPE_DATA + +protected : + sgQuat rotation ; + sgVec3 translation ; + float point_size ; + int button_state ; + int trigger_button ; + float mouse_x, mouse_y, mouse_z ; + float translation_sensitivity ; + + float xint, yint, zint ; + float prev_angle ; + sgQuat prev_rotation ; + +public : + puaCompass ( int minx, int miny, int maxx, int maxy ) : puObject ( minx, miny, maxx, maxy ) + { + setValue ( PUACOMPASS_INACTIVE ) ; + +// sgSetQuat ( rotation, 1.0f, 0.0f, 0.0f, 0.0f ) ; +// sgSetQuat ( rotation, 0.707107f, 0.707107f, 0.0f, 0.0f ) ; +// sgSetQuat ( rotation, 0.5f, -0.5f, 0.5f, 0.5f ) ; +// sgSetQuat ( rotation, 0.866025f, -0.166667f, 0.166667f, 0.166667f ) ; + sgSetQuat ( rotation, 0.866025f, -0.408248f, 0.288675f, 0.0f ) ; + sgSetVec3 ( translation, 0.0f, 0.0f, 0.0f ) ; + + point_size = 10.0f ; + + button_state = PU_UP ; + trigger_button = active_mouse_button ; + mouse_x = mouse_y = mouse_z = 0.0f ; + translation_sensitivity = 1.0f ; + + xint = yint = zint = 0.0f ; + prev_angle = 0.0f ; + sgCopyQuat ( prev_rotation, rotation ) ; + } + + void draw ( int dx, int dy ) ; + void doHit ( int button, int updown, int x, int y ) ; + + // Accessors and mutators + void getRotation ( sgQuat q ) const { memcpy ( q, rotation, 4 * sizeof(sgFloat) ) ; } + void setRotation ( sgQuat q ) { memcpy ( rotation, q, 4 * sizeof(sgFloat) ) ; } + void setRotation ( sgFloat t, sgFloat x, sgFloat y, sgFloat z ) + { + sgFloat sinth = sgSin ( t / 2.0f ) ; + sgFloat norm = sgSqrt ( x * x + y * y + z * z ) ; + if ( norm == 0.0 ) norm = 1.0 ; + rotation[SG_W] = sgCos ( t / 2.0f ) ; + rotation[SG_X] = sinth * x / norm ; + rotation[SG_Y] = sinth * y / norm ; + rotation[SG_Z] = sinth * z / norm ; + } + + void getTranslation ( sgVec3 t ) const { memcpy ( t, translation, 3 * sizeof(sgFloat) ) ; } + void setTranslation ( sgVec3 t ) { memcpy ( translation, t, 3 * sizeof(sgFloat) ) ; } + void setTranslation ( sgFloat x, sgFloat y, sgFloat z ) { translation[SG_X] = x ; translation[SG_Y] = y ; translation[SG_Z] = z ; } + + float getPointSize () const { return point_size ; } + void setPointSize ( float p ) { point_size = p ; } + + int getTriggerButton () const { return trigger_button ; } + void setTriggerButton ( int b ) { trigger_button = b ; } + + float getTranslationSensitivity () const { return translation_sensitivity ; } + void setTranslationSensitivity ( float t ) { translation_sensitivity = t ; } +} ; + + +class puaChooser +{ + UL_TYPE_DATA + + puButton *chooser_button ; + puPopupMenu *popup_menu ; + + int x1, y1, x2, y2 ; + + static void static_popup_cb ( puObject * ) ; + static void static_menu_cb ( puObject * ) ; + +public: + + virtual ~puaChooser () + { + delete chooser_button ; + delete popup_menu ; + } + + puaChooser ( int _x1, int _y1, int _x2, int _y2, char *legend ) ; + + void add_item ( char *str, puCallback _cb, void *_user_data = NULL ) ; + void close () ; + + void popup_cb () ; + + void menuCleanup ( const char *s ) ; + + void hide () { chooser_button -> hide () ; popup_menu -> hide () ; } + void reveal () { chooser_button -> reveal () ; popup_menu -> hide () ; } + + static void menuCleanup ( puObject * ) ; +} ; + + +/** + * A scrolling list for PUI. + * + * Believe it or not, PUI does not have one of these. + * + * This widget consists of a puListBox, a slider and two + * arrow buttons. This makes the ListBox scrollable, + * very handy if the box is too small to show all items + * at once. + * + * (Original code taken from FlightGear 0.9.6 sources, + * modified by Jan Reucker) + */ +class puaList : public puGroup +{ + UL_TYPE_DATA + + char ** _contents; + puFrame * _frame; + puSlider * _slider; + puArrowButton * _up_arrow; + puArrowButton * _down_arrow; + int _style; + int _sw; // slider width + int _width, _height; + +protected: + virtual void init (int w, int h, short transparent); + puListBox * _list_box; + +public: + puaList (int x, int y, int w, int h, int sl_width = 20); + puaList (int x, int y, int w, int h, char ** contents, int sl_width = 20); + puaList (int x, int y, int w, int h, short transparent, int sl_width = 20); + puaList (int x, int y, int w, int h, short transparent, char ** contents, int sl_width = 20); + virtual ~puaList (); + + virtual void newList (char ** contents); + + virtual char * getStringValue (); + virtual int getIntegerValue (); + virtual void getValue (char **ps); + virtual void getValue (int *i); + + virtual void setColourScheme (float r, float g, float b, float a); + virtual void setColour (int which, float r, float g, float b, float a); + virtual void setSize (int w, int h); + + int checkHit ( int button, int updown, int x, int y ); + int getNumVisible ( void ) const { return _list_box->getNumVisible(); } + int getNumItems ( void ) const { return _list_box->getNumItems(); } + int getTopItem ( void ) const { return _list_box->getTopItem(); } + void setTopItem ( int item_index ); +}; + +#endif + diff --git a/include/plib/puAuxLocal.h b/include/plib/puAuxLocal.h new file mode 100644 index 0000000..3d9526f --- /dev/null +++ b/include/plib/puAuxLocal.h @@ -0,0 +1,4 @@ + +#define PU_USE_NONE 1 +#include "puAux.h" + diff --git a/include/plib/puFLTK.h b/include/plib/puFLTK.h new file mode 100644 index 0000000..e684864 --- /dev/null +++ b/include/plib/puFLTK.h @@ -0,0 +1,68 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: puFLTK.h 1857 2004-02-16 13:49:03Z stromberg $ +*/ + +#ifndef _PU_FLTK_H_ +#define _PU_FLTK_H_ + +#ifndef PU_USE_FLTK +# define PU_USE_FLTK +#endif + +#include "pu.h" +#include + + +inline int puGetWindowFLTK () +{ + return (int) Fl_Window::current () ; +} + +inline void puSetWindowFLTK ( int window ) +{ + ((Fl_Gl_Window *) window) -> make_current () ; +} + +inline void puGetWindowSizeFLTK ( int *width, int *height ) +{ + Fl_Window * window = Fl_Window::current () ; + *width = window->w() ; + *height = window->h() ; +} + +inline void puSetWindowSizeFLTK ( int width, int height ) +{ + Fl_Window * window = Fl_Window::current () ; + window -> resize ( window->x(), window->y(), width, height ) ; +} + +inline void puInitFLTK () +{ + puSetWindowFuncs ( puGetWindowFLTK, + puSetWindowFLTK, + puGetWindowSizeFLTK, + puSetWindowSizeFLTK ) ; + puRealInit () ; +} + + +#endif diff --git a/include/plib/puGLUT.h b/include/plib/puGLUT.h new file mode 100644 index 0000000..bd564a0 --- /dev/null +++ b/include/plib/puGLUT.h @@ -0,0 +1,75 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: puGLUT.h 2122 2007-09-15 12:34:36Z fayjf $ +*/ + +#ifndef _PU_GLUT_H_ +#define _PU_GLUT_H_ + +#ifndef PU_USE_GLUT +# define PU_USE_GLUT +#endif + +#include "pu.h" + +#ifdef UL_MAC_OSX +# include +#else +# ifdef FREEGLUT_IS_PRESENT /* for FreeGLUT like PLIB 1.6.1*/ +# include +# else +# include +# endif +#endif + + +inline int puGetWindowGLUT() +{ + return glutGetWindow () ; +} + +inline void puSetWindowGLUT ( int window ) +{ + glutSetWindow ( window ) ; +} + +inline void puGetWindowSizeGLUT ( int *width, int *height ) +{ + *width = glutGet ( (GLenum) GLUT_WINDOW_WIDTH ) ; + *height = glutGet ( (GLenum) GLUT_WINDOW_HEIGHT ) ; +} + +inline void puSetWindowSizeGLUT ( int width, int height ) +{ + glutReshapeWindow ( width, height ) ; +} + +inline void puInitGLUT () +{ + puSetWindowFuncs ( puGetWindowGLUT, + puSetWindowGLUT, + puGetWindowSizeGLUT, + puSetWindowSizeGLUT ) ; + puRealInit () ; +} + + +#endif diff --git a/include/plib/puNative.h b/include/plib/puNative.h new file mode 100644 index 0000000..0abbb4f --- /dev/null +++ b/include/plib/puNative.h @@ -0,0 +1,101 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: puNative.h 1857 2004-02-16 13:49:03Z stromberg $ +*/ + +#ifndef _PU_NATIVE_H_ +#define _PU_NATIVE_H_ + +#ifndef PU_USE_NATIVE +# define PU_USE_NATIVE +#endif + +#include "pu.h" + +#if defined(UL_GLX) +# include +#elif defined(UL_WGL) +// nothing +#elif defined(UL_AGL) +# include +#elif defined(UL_CGL) +# include +#endif + + +inline int puGetWindowNative () +{ +#if defined(UL_GLX) + return (int) glXGetCurrentDrawable () ; +#elif defined(UL_WGL) + return (int) wglGetCurrentDC () ; +#elif defined(UL_AGL) + return (int) aglGetCurrentDrawable () ; +#elif defined(UL_CGL) + return (int) CGLGetCurrentContext () ; +#else + return 0 ; +#endif +} + + +inline void puGetWindowSizeNative ( int *width, int *height ) +{ +#if defined(UL_GLX) + + Window root ; + int x, y ; + unsigned int w, h, b, d ; + + XGetGeometry ( glXGetCurrentDisplay (), + glXGetCurrentDrawable (), + &root, &x, &y, &w, &h, &b, &d ) ; + *width = w ; + *height = h ; + +#elif defined(UL_WGL) + + RECT r ; + GetClientRect( WindowFromDC( wglGetCurrentDC() ), &r ); + *width = r.right ; + *height = r.bottom ; + +#else // Help! Need implementations for more systems. + + GLint vp[4] ; + glGetIntegerv ( GL_VIEWPORT, vp ) ; + *width = vp[0] + vp[2] ; + *height = vp[1] + vp[3] ; + // Note: puSetOpenGLState calls glViewport(0, 0, w, h). + +#endif +} + + +inline void puInitNative () +{ + puSetWindowFuncs ( puGetWindowNative, NULL, + puGetWindowSizeNative, NULL ) ; + puRealInit () ; +} + + +#endif diff --git a/include/plib/puPW.h b/include/plib/puPW.h new file mode 100644 index 0000000..3b030ef --- /dev/null +++ b/include/plib/puPW.h @@ -0,0 +1,66 @@ + +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: puPW.h 1863 2004-02-17 01:43:21Z sjbaker $ +*/ + +#ifndef _PU_PW_H_ +#define _PU_PW_H_ + +#include "pu.h" + +#define PUPW_WINDOW_MAGIC 0x3DEB4938 /* Random! */ + +inline int puGetWindowPW() +{ + return PUPW_WINDOW_MAGIC ; +} + +inline void puSetWindowPW ( int window ) +{ + // Not possible because PW is a single-window library. + // But we can at least check that the handle matches. + + assert ( window == PUPW_WINDOW_MAGIC ) ; +} + +inline void puGetWindowSizePW ( int *width, int *height ) +{ + pwGetSize ( width, height ) ; +} + +inline void puSetWindowSizePW ( int width, int height ) +{ + pwSetSize ( width, height ) ; +} + +inline void puInitPW () +{ + puSetWindowFuncs ( puGetWindowPW, + puSetWindowPW, + puGetWindowSizePW, + puSetWindowSizePW ) ; + puRealInit () ; +} + + +#endif + diff --git a/include/plib/puSDL.h b/include/plib/puSDL.h new file mode 100644 index 0000000..c9c48a8 --- /dev/null +++ b/include/plib/puSDL.h @@ -0,0 +1,55 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: puSDL.h 2130 2007-11-18 21:46:37Z fayjf $ +*/ + +#ifndef _PU_SDL_H_ +#define _PU_SDL_H_ + +#ifndef PU_USE_SDL +# define PU_USE_SDL +#endif + +#include "pu.h" +#include "SDL.h" + + +inline int puGetWindowSDL () +{ + return 0; +} + +inline void puGetWindowSizeSDL ( int *width, int *height ) +{ + SDL_Surface *display = SDL_GetVideoSurface () ; + *width = display->w ; + *height = display->h ; +} + +inline void puInitSDL () +{ + puSetWindowFuncs ( puGetWindowSDL, NULL, + puGetWindowSizeSDL, NULL ) ; + puRealInit () ; +} + + +#endif diff --git a/include/plib/sg.h b/include/plib/sg.h new file mode 100644 index 0000000..8b339a3 --- /dev/null +++ b/include/plib/sg.h @@ -0,0 +1,3102 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: sg.h 2121 2007-09-15 03:36:21Z fayjf $ +*/ + + +#ifndef SG_H +#define SG_H 1 + +#include +#include "ul.h" + +#define sgFloat float +#define SGfloat float + +#define SG_ZERO 0.0f +#define SG_HALF 0.5f +#define SG_ONE 1.0f +#define SG_TWO 2.0f +#define SG_THREE 3.0f +#define SG_FOUR 4.0f +#define SG_45 45.0f +#define SG_60 60.0f +#define SG_90 90.0f +#define SG_180 180.0f +#define SG_MAX FLT_MAX + +#define SG_X 0 +#define SG_Y 1 +#define SG_Z 2 +#define SG_W 3 + +#ifndef M_PI +#define SG_PI 3.1415926535f +#else +#define SG_PI ((SGfloat) M_PI) +#endif + +#define SG_DEGREES_TO_RADIANS (SG_PI/SG_180) +#define SG_RADIANS_TO_DEGREES (SG_180/SG_PI) + +/* + These are just convenient redefinitions of standard + math library functions to stop float/double warnings. +*/ + +inline SGfloat sgSqrt ( const SGfloat x ) { return (SGfloat) sqrt ( x ) ; } +inline SGfloat sgSquare ( const SGfloat x ) { return x * x ; } +inline SGfloat sgAbs ( const SGfloat a ) { return (axyz, src->hpr ) ; +} + +extern void sgMakeLookAtMat4 ( sgMat4 dst, + const sgVec3 eye, const sgVec3 center, const sgVec3 up ) ; + +extern void sgMakeRotMat4 ( sgMat4 dst, const SGfloat angle, const sgVec3 axis ) ; + +inline void sgMakeRotMat4 ( sgMat4 dst, const sgVec3 hpr ) +{ + sgMakeCoordMat4 ( dst, SG_ZERO, SG_ZERO, SG_ZERO, hpr[0], hpr[1], hpr[2] ) ; +} + +inline void sgMakeRotMat4 ( sgMat4 dst,const SGfloat h, const SGfloat p, const SGfloat r ) +{ + sgMakeCoordMat4 ( dst, SG_ZERO, SG_ZERO, SG_ZERO, h, p, r ) ; +} + +extern void sgMakeTransMat4 ( sgMat4 dst, const sgVec3 xyz ) ; +extern void sgMakeTransMat4 ( sgMat4 dst, const SGfloat x, const SGfloat y, const SGfloat z ) ; + + +extern void sgSetCoord ( sgCoord *coord, const sgMat4 src ) ; + +extern void sgMultMat4 ( sgMat4 dst, const sgMat4 a, const sgMat4 b ) ; +extern void sgPostMultMat4 ( sgMat4 dst, const sgMat4 a ) ; +extern void sgPreMultMat4 ( sgMat4 dst, const sgMat4 a ) ; + +extern void sgTransposeNegateMat4 ( sgMat4 dst ) ; +extern void sgTransposeNegateMat4 ( sgMat4 dst, const sgMat4 src ) ; +extern void sgInvertMat4 ( sgMat4 dst, const sgMat4 src ) ; +inline void sgInvertMat4 ( sgMat4 dst ) { sgInvertMat4 ( dst, dst ) ; } + +extern void sgXformVec3 ( sgVec3 dst, const sgVec3 src, const sgMat4 mat ) ; +extern void sgXformPnt3 ( sgVec3 dst, const sgVec3 src, const sgMat4 mat ) ; +extern void sgXformVec4 ( sgVec4 dst, const sgVec4 src, const sgMat4 mat ) ; +extern void sgXformPnt4 ( sgVec4 dst, const sgVec4 src, const sgMat4 mat ) ; +extern void sgFullXformPnt3 ( sgVec3 dst, const sgVec3 src, const sgMat4 mat ) ; +extern void sgFullXformPnt4 ( sgVec4 dst, const sgVec4 src, const sgMat4 mat ) ; + +inline void sgXformVec3 ( sgVec3 dst, const sgMat4 mat ) { sgXformVec3 ( dst, dst, mat ) ; } +inline void sgXformPnt3 ( sgVec3 dst, const sgMat4 mat ) { sgXformPnt3 ( dst, dst, mat ) ; } +inline void sgXformVec4 ( sgVec4 dst, const sgMat4 mat ) { sgXformVec4 ( dst, dst, mat ) ; } +inline void sgXformPnt4 ( sgVec4 dst, const sgMat4 mat ) { sgXformPnt4 ( dst, dst, mat ) ; } +inline void sgFullXformPnt3 ( sgVec3 dst, const sgMat4 mat ) { sgFullXformPnt3 ( dst, dst, mat ) ; } +inline void sgFullXformPnt4 ( sgVec4 dst, const sgMat4 mat ) { sgFullXformPnt4 ( dst, dst, mat ) ; } + + +/* Bits returned by sgClassifyMat4 */ + +#define SG_IDENTITY 0x00 // for clarity +#define SG_ROTATION 0x01 // includes a rotational component +#define SG_MIRROR 0x02 // changes handedness (det < 0) +#define SG_SCALE 0x04 // uniform scaling +#define SG_NONORTHO 0x10 // 3x3 not orthogonal +#define SG_TRANSLATION 0x20 // translates +#define SG_PROJECTION 0x40 // forth column not 0,0,0,1 + +/* Are these needed? sgClassifyMat4() does set the general scale bit for some matrices, + * but it is not easily defined. Use SG_NONORTHO instead (which is also set). */ +#define SG_UNIFORM_SCALE SG_SCALE +#define SG_GENERAL_SCALE 0x08 // x, y and z scaled differently + +extern int sgClassifyMat4 ( const sgMat4 mat ) ; + + + +/* + Basic low-level vector functions. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + For each of Vec2, Vec3 and Vec4, we provide inlines for + + Zero - set all elements to zero. + Set - set each element individually. + Add - add vectors element by element. + Sub - subtract vectors element by element. + Scale - multiply each element of a vector by a variable. + AddScaled - multiply second vector by a constant and add the + result to the first vector. + Negate - negate each element of a vector. + Compare - compare vectors element by element with optional tolerance. + (return TRUE if vectors are equal - within tolerances) + Equal - return TRUE if vectors are exactly equal. + Length - compute length of a vector. + Distance - compute distance between two points. + ScalarProduct - scalar (dot) product. + VectorProduct - vector (cross) product (3-element vectors ONLY!). + Normalise/Normalize - make vector be one unit long. +*/ + +inline void sgZeroVec2 ( sgVec2 dst ) { dst[0]=dst[1]=SG_ZERO ; } +inline void sgZeroVec3 ( sgVec3 dst ) { dst[0]=dst[1]=dst[2]=SG_ZERO ; } +inline void sgZeroVec4 ( sgVec4 dst ) { dst[0]=dst[1]=dst[2]=dst[3]=SG_ZERO ; } + + +inline void sgSetVec2 ( sgVec2 dst, const SGfloat x, const SGfloat y ) +{ + dst [ 0 ] = x ; + dst [ 1 ] = y ; +} + +inline void sgSetVec3 ( sgVec3 dst, const SGfloat x, const SGfloat y, const SGfloat z ) +{ + dst [ 0 ] = x ; + dst [ 1 ] = y ; + dst [ 2 ] = z ; +} + +inline void sgSetVec4 ( sgVec4 dst, const SGfloat x, const SGfloat y, const SGfloat z, const SGfloat w ) +{ + dst [ 0 ] = x ; + dst [ 1 ] = y ; + dst [ 2 ] = z ; + dst [ 3 ] = w ; +} + + +inline void sgCopyVec2 ( sgVec2 dst, const sgVec2 src ) +{ + dst [ 0 ] = src [ 0 ] ; + dst [ 1 ] = src [ 1 ] ; +} + +inline void sgCopyVec3 ( sgVec3 dst, const sgVec3 src ) +{ + dst [ 0 ] = src [ 0 ] ; + dst [ 1 ] = src [ 1 ] ; + dst [ 2 ] = src [ 2 ] ; +} + +inline void sgCopyVec4 ( sgVec4 dst, const sgVec4 src ) +{ + dst [ 0 ] = src [ 0 ] ; + dst [ 1 ] = src [ 1 ] ; + dst [ 2 ] = src [ 2 ] ; + dst [ 3 ] = src [ 3 ] ; +} + + +inline void sgAddVec2 ( sgVec2 dst, const sgVec2 src ) +{ + dst [ 0 ] += src [ 0 ] ; + dst [ 1 ] += src [ 1 ] ; +} + +inline void sgAddVec3 ( sgVec3 dst, const sgVec3 src ) +{ + dst [ 0 ] += src [ 0 ] ; + dst [ 1 ] += src [ 1 ] ; + dst [ 2 ] += src [ 2 ] ; +} + +inline void sgAddVec4 ( sgVec4 dst, const sgVec4 src ) +{ + dst [ 0 ] += src [ 0 ] ; + dst [ 1 ] += src [ 1 ] ; + dst [ 2 ] += src [ 2 ] ; + dst [ 3 ] += src [ 3 ] ; +} + + +inline void sgAddVec2 ( sgVec2 dst, const sgVec2 src1, const sgVec2 src2 ) +{ + dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] ; + dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] ; +} + +inline void sgAddVec3 ( sgVec3 dst, const sgVec3 src1, const sgVec3 src2 ) +{ + dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] ; + dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] ; + dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] ; +} + +inline void sgAddVec4 ( sgVec4 dst, const sgVec4 src1, const sgVec4 src2 ) +{ + dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] ; + dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] ; + dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] ; + dst [ 3 ] = src1 [ 3 ] + src2 [ 3 ] ; +} + + +inline void sgSubVec2 ( sgVec2 dst, const sgVec2 src ) +{ + dst [ 0 ] -= src [ 0 ] ; + dst [ 1 ] -= src [ 1 ] ; +} + +inline void sgSubVec3 ( sgVec3 dst, const sgVec3 src ) +{ + dst [ 0 ] -= src [ 0 ] ; + dst [ 1 ] -= src [ 1 ] ; + dst [ 2 ] -= src [ 2 ] ; +} + +inline void sgSubVec4 ( sgVec4 dst, const sgVec4 src ) +{ + dst [ 0 ] -= src [ 0 ] ; + dst [ 1 ] -= src [ 1 ] ; + dst [ 2 ] -= src [ 2 ] ; + dst [ 3 ] -= src [ 3 ] ; +} + +inline void sgSubVec2 ( sgVec2 dst, const sgVec2 src1, const sgVec2 src2 ) +{ + dst [ 0 ] = src1 [ 0 ] - src2 [ 0 ] ; + dst [ 1 ] = src1 [ 1 ] - src2 [ 1 ] ; +} + +inline void sgSubVec3 ( sgVec3 dst, const sgVec3 src1, const sgVec3 src2 ) +{ + dst [ 0 ] = src1 [ 0 ] - src2 [ 0 ] ; + dst [ 1 ] = src1 [ 1 ] - src2 [ 1 ] ; + dst [ 2 ] = src1 [ 2 ] - src2 [ 2 ] ; +} + +inline void sgSubVec4 ( sgVec4 dst, const sgVec4 src1, const sgVec4 src2 ) +{ + dst [ 0 ] = src1 [ 0 ] - src2 [ 0 ] ; + dst [ 1 ] = src1 [ 1 ] - src2 [ 1 ] ; + dst [ 2 ] = src1 [ 2 ] - src2 [ 2 ] ; + dst [ 3 ] = src1 [ 3 ] - src2 [ 3 ] ; +} + + +inline void sgNegateVec2 ( sgVec2 dst ) +{ + dst [ 0 ] = -dst [ 0 ] ; + dst [ 1 ] = -dst [ 1 ] ; +} + +inline void sgNegateVec3 ( sgVec3 dst ) +{ + dst [ 0 ] = -dst [ 0 ] ; + dst [ 1 ] = -dst [ 1 ] ; + dst [ 2 ] = -dst [ 2 ] ; +} + +inline void sgNegateVec4 ( sgVec4 dst ) +{ + dst [ 0 ] = -dst [ 0 ] ; + dst [ 1 ] = -dst [ 1 ] ; + dst [ 2 ] = -dst [ 2 ] ; + dst [ 3 ] = -dst [ 3 ] ; +} + + +inline void sgNegateVec2 ( sgVec2 dst, const sgVec2 src ) +{ + dst [ 0 ] = -src [ 0 ] ; + dst [ 1 ] = -src [ 1 ] ; +} + +inline void sgNegateVec3 ( sgVec3 dst, const sgVec3 src ) +{ + dst [ 0 ] = -src [ 0 ] ; + dst [ 1 ] = -src [ 1 ] ; + dst [ 2 ] = -src [ 2 ] ; +} + +inline void sgNegateVec4 ( sgVec4 dst, const sgVec4 src ) +{ + dst [ 0 ] = -src [ 0 ] ; + dst [ 1 ] = -src [ 1 ] ; + dst [ 2 ] = -src [ 2 ] ; + dst [ 3 ] = -src [ 3 ] ; +} + + +inline void sgScaleVec2 ( sgVec2 dst, const SGfloat s ) +{ + dst [ 0 ] *= s ; + dst [ 1 ] *= s ; +} + +inline void sgScaleVec3 ( sgVec3 dst, const SGfloat s ) +{ + dst [ 0 ] *= s ; + dst [ 1 ] *= s ; + dst [ 2 ] *= s ; +} + +inline void sgScaleVec4 ( sgVec4 dst, const SGfloat s ) +{ + dst [ 0 ] *= s ; + dst [ 1 ] *= s ; + dst [ 2 ] *= s ; + dst [ 3 ] *= s ; +} + +inline void sgScaleVec2 ( sgVec2 dst, const sgVec2 src, const SGfloat s ) +{ + dst [ 0 ] = src [ 0 ] * s ; + dst [ 1 ] = src [ 1 ] * s ; +} + +inline void sgScaleVec3 ( sgVec3 dst, const sgVec3 src, const SGfloat s ) +{ + dst [ 0 ] = src [ 0 ] * s ; + dst [ 1 ] = src [ 1 ] * s ; + dst [ 2 ] = src [ 2 ] * s ; +} + +inline void sgScaleVec4 ( sgVec4 dst, const sgVec4 src, const SGfloat s ) +{ + dst [ 0 ] = src [ 0 ] * s ; + dst [ 1 ] = src [ 1 ] * s ; + dst [ 2 ] = src [ 2 ] * s ; + dst [ 3 ] = src [ 3 ] * s ; +} + + +inline void sgAddScaledVec2 ( sgVec2 dst, const sgVec2 src, const SGfloat s ) +{ + dst [ 0 ] += src [ 0 ] * s ; + dst [ 1 ] += src [ 1 ] * s ; +} + +inline void sgAddScaledVec3 ( sgVec3 dst, const sgVec3 src, const SGfloat s ) +{ + dst [ 0 ] += src [ 0 ] * s ; + dst [ 1 ] += src [ 1 ] * s ; + dst [ 2 ] += src [ 2 ] * s ; +} + +inline void sgAddScaledVec4 ( sgVec4 dst, const sgVec4 src, const SGfloat s ) +{ + dst [ 0 ] += src [ 0 ] * s ; + dst [ 1 ] += src [ 1 ] * s ; + dst [ 2 ] += src [ 2 ] * s ; + dst [ 3 ] += src [ 3 ] * s ; +} + + +inline void sgAddScaledVec2 ( sgVec2 dst, const sgVec2 src1, const sgVec2 src2, const SGfloat s ) +{ + dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] * s ; + dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] * s ; +} + +inline void sgAddScaledVec3 ( sgVec3 dst, const sgVec3 src1, const sgVec3 src2, const SGfloat s ) +{ + dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] * s ; + dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] * s ; + dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] * s ; +} + +inline void sgAddScaledVec4 ( sgVec4 dst, const sgVec4 src1, const sgVec4 src2, const SGfloat s ) +{ + dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] * s ; + dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] * s ; + dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] * s ; + dst [ 3 ] = src1 [ 3 ] + src2 [ 3 ] * s ; +} + + +inline int sgCompareVec2 ( const sgVec2 a, const sgVec2 b, const SGfloat tol ) +{ + if ( sgCompareFloat( a[0], b[0], tol ) != 0 ) return FALSE ; + if ( sgCompareFloat( a[1], b[1], tol ) != 0 ) return FALSE ; + + return TRUE ; +} + +inline int sgCompareVec3 ( const sgVec3 a, const sgVec3 b, const SGfloat tol ) +{ + if ( sgCompareFloat( a[0], b[0], tol ) != 0 ) return FALSE ; + if ( sgCompareFloat( a[1], b[1], tol ) != 0 ) return FALSE ; + if ( sgCompareFloat( a[2], b[2], tol ) != 0 ) return FALSE ; + + return TRUE ; +} + +inline int sgCompareVec4 ( const sgVec4 a, const sgVec4 b, const SGfloat tol ) +{ + if ( sgCompareFloat( a[0], b[0], tol ) != 0 ) return FALSE ; + if ( sgCompareFloat( a[1], b[1], tol ) != 0 ) return FALSE ; + if ( sgCompareFloat( a[2], b[2], tol ) != 0 ) return FALSE ; + if ( sgCompareFloat( a[3], b[3], tol ) != 0 ) return FALSE ; + + return TRUE ; +} + + +inline int sgEqualVec2 ( const sgVec2 a, const sgVec2 b ) +{ + return a[0] == b[0] && + a[1] == b[1] ; +} + +inline int sgEqualVec3 ( const sgVec3 a, const sgVec3 b ) +{ + return a[0] == b[0] && + a[1] == b[1] && + a[2] == b[2] ; +} + +inline int sgEqualVec4 ( const sgVec4 a, const sgVec4 b ) +{ + return a[0] == b[0] && + a[1] == b[1] && + a[2] == b[2] && + a[3] == b[3] ; +} + + +inline SGfloat sgScalarProductVec2 ( const sgVec2 a, const sgVec2 b ) +{ + return a[0]*b[0] + a[1]*b[1] ; +} + +inline SGfloat sgScalarProductVec3 ( const sgVec3 a, const sgVec3 b ) +{ + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] ; +} + +inline SGfloat sgScalarProductVec4 ( const sgVec4 a, const sgVec4 b ) +{ + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3] ; +} + + +extern void sgVectorProductVec3 ( sgVec3 dst, const sgVec3 a, const sgVec3 b ) ; + +inline SGfloat sgLerp ( const SGfloat a, const SGfloat b, const SGfloat f ) +{ + return a + f * ( b - a ) ; +} + +inline void sgLerpVec4 ( sgVec4 dst, const sgVec4 a, const sgVec4 b, const SGfloat f ) +{ + dst[0] = a[0] + f * ( b[0] - a[0] ) ; + dst[1] = a[1] + f * ( b[1] - a[1] ) ; + dst[2] = a[2] + f * ( b[2] - a[2] ) ; + dst[3] = a[3] + f * ( b[3] - a[3] ) ; +} + + +inline void sgLerpVec3 ( sgVec3 dst, const sgVec3 a, const sgVec3 b, const SGfloat f ) +{ + dst[0] = a[0] + f * ( b[0] - a[0] ) ; + dst[1] = a[1] + f * ( b[1] - a[1] ) ; + dst[2] = a[2] + f * ( b[2] - a[2] ) ; +} + + +inline void sgLerpVec2 ( sgVec2 dst, const sgVec2 a, const sgVec2 b, const SGfloat f ) +{ + dst[0] = a[0] + f * ( b[0] - a[0] ) ; + dst[1] = a[1] + f * ( b[1] - a[1] ) ; +} + + +inline void sgLerpAnglesVec3 ( sgVec3 dst, const sgVec3 a, + const sgVec3 b, + const SGfloat f ) +{ + sgVec3 tmp ; + + if ( b[0] - a[0] > 180.0f ) tmp[0] = a[0] + 360.0f ; else + if ( b[0] - a[0] < -180.0f ) tmp[0] = a[0] - 360.0f ; else tmp[0] = a[0] ; + + if ( b[1] - a[1] > 180.0f ) tmp[1] = a[1] + 360.0f ; else + if ( b[1] - a[1] < -180.0f ) tmp[1] = a[1] - 360.0f ; else tmp[1] = a[1] ; + + if ( b[2] - a[2] > 180.0f ) tmp[2] = a[2] + 360.0f ; else + if ( b[2] - a[2] < -180.0f ) tmp[2] = a[2] - 360.0f ; else tmp[2] = a[2] ; + + dst[0] = tmp[0] + f * ( b[0] - tmp[0] ) ; + dst[1] = tmp[1] + f * ( b[1] - tmp[1] ) ; + dst[2] = tmp[2] + f * ( b[2] - tmp[2] ) ; +} + + + +inline SGfloat sgDistanceSquaredVec2 ( const sgVec2 a, const sgVec2 b ) +{ + return sgSquare ( a[0]-b[0] ) + sgSquare ( a[1]-b[1] ) ; +} + +inline SGfloat sgDistanceSquaredVec3 ( const sgVec3 a, const sgVec3 b ) +{ + return sgSquare ( a[0]-b[0] ) + sgSquare ( a[1]-b[1] ) + + sgSquare ( a[2]-b[2] ) ; +} + +inline SGfloat sgDistanceSquaredVec4 ( const sgVec4 a, const sgVec4 b ) +{ + return sgSquare ( a[0]-b[0] ) + sgSquare ( a[1]-b[1] ) + + sgSquare ( a[2]-b[2] ) + sgSquare ( a[3]-b[3] ) ; +} + +inline SGfloat sgDistanceVec2 ( const sgVec2 a, const sgVec2 b ) +{ + return sgSqrt ( sgSquare ( a[0]-b[0] ) + sgSquare ( a[1]-b[1] ) ) ; +} + +inline SGfloat sgDistanceVec3 ( const sgVec3 a, const sgVec3 b ) +{ + return sgSqrt ( sgSquare ( a[0]-b[0] ) + sgSquare ( a[1]-b[1] ) + + sgSquare ( a[2]-b[2] ) ) ; +} + +inline SGfloat sgDistanceVec4 ( const sgVec4 a, const sgVec4 b ) +{ + return sgSqrt ( sgSquare ( a[0]-b[0] ) + sgSquare ( a[1]-b[1] ) + + sgSquare ( a[2]-b[2] ) + sgSquare ( a[3]-b[3] ) ) ; +} + + +inline SGfloat sgLengthVec2 ( const sgVec2 src ) +{ + return sgSqrt ( sgScalarProductVec2 ( src, src ) ) ; +} + +inline SGfloat sgLengthVec3 ( const sgVec3 src ) +{ + return sgSqrt ( sgScalarProductVec3 ( src, src ) ) ; +} + +inline SGfloat sgLengthVec4 ( const sgVec4 src ) +{ + return sgSqrt ( sgScalarProductVec4 ( src, src ) ) ; +} + +inline SGfloat sgLengthSquaredVec2 ( sgVec2 const src ) +{ + return sgScalarProductVec2 ( src, src ) ; +} + +inline SGfloat sgLengthSquaredVec3 ( sgVec3 const src ) +{ + return sgScalarProductVec3 ( src, src ) ; +} + +inline SGfloat sgLengthSquaredVec4 ( sgVec4 const src ) +{ + return sgScalarProductVec4 ( src, src ) ; +} + + +/* Anglo-US spelling issues. */ +#define sgNormalizeVec2 sgNormaliseVec2 +#define sgNormalizeVec3 sgNormaliseVec3 +#define sgNormalizeVec4 sgNormaliseVec4 +#define sgNormalizeQuat sgNormaliseQuat + +inline void sgNormaliseVec2 ( sgVec2 dst ) +{ + sgScaleVec2 ( dst, SG_ONE / sgLengthVec2 ( dst ) ) ; +} + +inline void sgNormaliseVec3 ( sgVec3 dst ) +{ + sgScaleVec3 ( dst, SG_ONE / sgLengthVec3 ( dst ) ) ; +} + +inline void sgNormaliseVec4 ( sgVec4 dst ) +{ + sgScaleVec4 ( dst, SG_ONE / sgLengthVec4 ( dst ) ) ; +} + +inline void sgNormaliseVec2 ( sgVec2 dst, const sgVec2 src ) +{ + sgScaleVec2 ( dst, src, SG_ONE / sgLengthVec2 ( src ) ) ; +} + +inline void sgNormaliseVec3 ( sgVec3 dst, const sgVec3 src ) +{ + sgScaleVec3 ( dst, src, SG_ONE / sgLengthVec3 ( src ) ) ; +} + +inline void sgNormaliseVec4 ( sgVec4 dst, const sgVec4 src ) +{ + sgScaleVec4 ( dst, src, SG_ONE / sgLengthVec4 ( src ) ) ; +} + + +inline void sgZeroCoord ( sgCoord *dst ) +{ + sgSetVec3 ( dst->xyz, SG_ZERO, SG_ZERO, SG_ZERO ) ; + sgSetVec3 ( dst->hpr, SG_ZERO, SG_ZERO, SG_ZERO ) ; +} + +inline void sgSetCoord ( sgCoord *dst, const SGfloat x, const SGfloat y, const SGfloat z, + const SGfloat h, const SGfloat p, const SGfloat r ) +{ + sgSetVec3 ( dst->xyz, x, y, z ) ; + sgSetVec3 ( dst->hpr, h, p, r ) ; +} + +inline void sgSetCoord ( sgCoord *dst, const sgVec3 xyz, const sgVec3 hpr ) +{ + sgCopyVec3 ( dst->xyz, xyz ) ; + sgCopyVec3 ( dst->hpr, hpr ) ; +} + +inline void sgCopyCoord ( sgCoord *dst, const sgCoord *src ) +{ + sgCopyVec3 ( dst->xyz, src->xyz ) ; + sgCopyVec3 ( dst->hpr, src->hpr ) ; +} + + + +inline void sgCopyMat4 ( sgMat4 dst, const sgMat4 src ) +{ + sgCopyVec4 ( dst[ 0 ], src[ 0 ] ) ; + sgCopyVec4 ( dst[ 1 ], src[ 1 ] ) ; + sgCopyVec4 ( dst[ 2 ], src[ 2 ] ) ; + sgCopyVec4 ( dst[ 3 ], src[ 3 ] ) ; +} + + +inline void sgScaleMat4 ( sgMat4 dst, const sgMat4 src, const SGfloat scale ) +{ + sgScaleVec4 ( dst[0], src[0], scale ) ; + sgScaleVec4 ( dst[1], src[1], scale ) ; + sgScaleVec4 ( dst[2], src[2], scale ) ; + sgScaleVec4 ( dst[3], src[3], scale ) ; +} + + +inline void sgMakeIdentMat4 ( sgMat4 dst ) +{ + sgSetVec4 ( dst[0], SG_ONE , SG_ZERO, SG_ZERO, SG_ZERO ) ; + sgSetVec4 ( dst[1], SG_ZERO, SG_ONE , SG_ZERO, SG_ZERO ) ; + sgSetVec4 ( dst[2], SG_ZERO, SG_ZERO, SG_ONE , SG_ZERO ) ; + sgSetVec4 ( dst[3], SG_ZERO, SG_ZERO, SG_ZERO, SG_ONE ) ; +} + + +extern void sgMakePickMatrix( sgMat4 mat, sgFloat x, sgFloat y, + sgFloat width, sgFloat height, sgVec4 viewport ) ; + +extern int sgCompare3DSqdDist ( const sgVec3 a, const sgVec3 b, const SGfloat sqd_dist ) ; + +inline SGfloat sgDistToLineVec2 ( const sgVec3 line, const sgVec2 pnt ) +{ + return sgScalarProductVec2 ( line, pnt ) + line[2] ; +} + + +struct sgLineSegment3 /* Bounded line segment */ +{ + sgVec3 a ; + sgVec3 b ; +} ; + +struct sgLine3 /* Infinite line */ +{ + sgVec3 point_on_line ; + sgVec3 direction_vector ; /* Should be a unit vector */ +} ; + + +inline void sgLineSegment3ToLine3 ( sgLine3 *line, + const sgLineSegment3 lineseg ) +{ + sgCopyVec3 ( line->point_on_line , lineseg.a ) ; + sgSubVec3 ( line->direction_vector, lineseg.b, lineseg.a ) ; + sgNormaliseVec3 ( line->direction_vector ) ; +} + + +SGfloat sgDistSquaredToLineVec3 ( const sgLine3 line, + const sgVec3 pnt ) ; +SGfloat sgDistSquaredToLineSegmentVec3 ( const sgLineSegment3 line, + const sgVec3 pnt ) ; + + +inline SGfloat sgDistToLineVec3 ( const sgLine3 line, + const sgVec3 pnt ) +{ + return sgSqrt ( sgDistSquaredToLineVec3 ( line, pnt ) ); +} + + +inline SGfloat sgDistToLineSegmentVec3 ( const sgLineSegment3 line, + const sgVec3 pnt ) +{ + return sgSqrt ( sgDistSquaredToLineSegmentVec3(line,pnt) ) ; +} + + +inline SGfloat sgDistToPlaneVec3 ( const sgVec4 plane, const sgVec3 pnt ) +{ + return sgScalarProductVec3 ( plane, pnt ) + plane[3] ; +} + + +inline SGfloat sgHeightAbovePlaneVec3 ( const sgVec4 plane, const sgVec3 pnt ) +{ + return pnt[2] - sgHeightOfPlaneVec2 ( plane, pnt ) ; +} + +extern void sgReflectInPlaneVec3 ( sgVec3 dst, const sgVec3 src, const sgVec4 plane ) ; + +inline void sgReflectInPlaneVec3 ( sgVec3 dst, const sgVec4 plane ) +{ + sgReflectInPlaneVec3 ( dst, dst, plane ) ; +} + +extern void sgMakeNormal ( sgVec2 dst, const sgVec3 a, const sgVec3 b ) ; + + +extern void sgMakeNormal ( sgVec3 dst, const sgVec3 a, const sgVec3 b, const sgVec3 c ) ; + + +inline void sgMake2DLine ( sgVec3 dst, const sgVec2 a, const sgVec2 b ) +{ + dst[0] = b[1]-a[1] ; + dst[1] = -(b[0]-a[0]) ; + sgNormalizeVec2 ( dst ) ; + dst[2] = - ( dst[0]*a[0] + dst[1]*a[1] ) ; +} + +inline void sgMakePlane ( sgVec4 dst, const sgVec3 normal, const sgVec3 pnt ) +{ + sgCopyVec3 ( dst, normal ) ; + dst [ 3 ] = - sgScalarProductVec3 ( normal, pnt ) ; +} + +inline void sgMakePlane ( sgVec4 dst, const sgVec3 a, const sgVec3 b, const sgVec3 c ) +{ + /* + Ax + By + Cz + D == 0 ; + D = - ( Ax + By + Cz ) + = - ( A*a[0] + B*a[1] + C*a[2] ) + = - sgScalarProductVec3 ( normal, a ) ; + */ + + sgMakeNormal ( dst, a, b, c ) ; + + dst [ 3 ] = - sgScalarProductVec3 ( dst, a ) ; +} + +float sgTriArea( sgVec3 p0, sgVec3 p1, sgVec3 p2 ); + + +// Fast code. Result is in the range 0..180: +inline SGfloat sgAngleBetweenNormalizedVec3 ( sgVec3 v1, sgVec3 v2 ) +{ + float f = sgScalarProductVec3 ( v1, v2 ) ; + + return (float) acos ( ( f >= 1.0f ) ? 1.0f : + ( f <= -1.0f ) ? -1.0f : f ) * + SG_RADIANS_TO_DEGREES ; +} + +// Fast code. Result is in the range 0..180: + +SGfloat sgAngleBetweenVec3 ( sgVec3 v1, sgVec3 v2 ); + +// All three have to be normalized. Slow code. Result is in the range 0..360: + +SGfloat sgAngleBetweenNormalizedVec3 (sgVec3 first, sgVec3 second, sgVec3 normal); + +// Normal has to be normalized. Slow code. Result is in the range 0..360: + +SGfloat sgAngleBetweenVec3 ( sgVec3 v1, sgVec3 v2, sgVec3 normal ); + +class sgSphere +{ +public: + sgVec3 center ; + SGfloat radius ; + + + sgSphere () { empty () ; } + + const SGfloat *getCenter (void) const { return center ; } + + void setCenter ( const sgVec3 c ) + { + sgCopyVec3 ( center, c ) ; + } + + void setCenter ( const SGfloat x, const SGfloat y, const SGfloat z ) + { + sgSetVec3 ( center, x, y, z ) ; + } + + SGfloat getRadius (void) const { return radius ; } + void setRadius ( const SGfloat r ) { radius = r ; } + + int isEmpty (void) const { return radius < SG_ZERO ; } + void empty (void) { radius = - SG_ONE ; } + + void orthoXform ( const sgMat4 m ) + { + sgXformPnt3 ( center, center, m ) ; + // radius *= sgLengthVec3 ( m[0] ) ; -- degrades performance for non-scaled matrices ... + } + + void extend ( const sgSphere *s ) ; + void extend ( const sgBox *b ) ; + void extend ( const sgVec3 v ) ; + + int intersects ( const sgSphere *s ) const + { + return sgCompare3DSqdDist ( center, s->getCenter(), + sgSquare ( radius + s->getRadius() ) ) <= 0 ; + } + + int intersects ( const sgVec4 plane ) const + { + return sgAbs ( sgDistToPlaneVec3 ( plane, center ) ) <= radius ; + } + + int intersects ( const sgBox *b ) const ; +} ; + + +class sgBox +{ +public: + sgVec3 min ; + sgVec3 max ; + + + sgBox () { empty () ; } + + const SGfloat *getMin (void) const { return min ; } + const SGfloat *getMax (void) const { return max ; } + + void setMin ( const SGfloat x, const SGfloat y, const SGfloat z ) + { + sgSetVec3 ( min, x, y, z ) ; + } + + void setMin ( const sgVec3 src ) + { + sgCopyVec3 ( min, src ) ; + } + + void setMax ( const SGfloat x, const SGfloat y, const SGfloat z ) + { + sgSetVec3 ( max, x, y, z ) ; + } + + void setMax ( const sgVec3 src ) + { + sgCopyVec3 ( max, src ) ; + } + + int isEmpty(void) const + { + return ( min[0] > max[0] || + min[1] > max[1] || + min[2] > max[2] ) ; + } + + void empty (void) + { + sgSetVec3 ( min, SG_MAX, SG_MAX, SG_MAX ) ; + sgSetVec3 ( max, -SG_MAX, -SG_MAX, -SG_MAX ) ; + } + + void extend ( const sgSphere *s ) ; + void extend ( const sgBox *b ) ; + void extend ( const sgVec3 v ) ; + + int intersects ( const sgSphere *s ) const + { + return s -> intersects ( this ) ; + } + + int intersects ( const sgBox *b ) const + { + return min[0] <= b->getMax()[0] && max[0] >= b->getMin()[0] && + min[1] <= b->getMax()[1] && max[1] >= b->getMin()[1] && + min[2] <= b->getMax()[2] && max[2] >= b->getMin()[2] ; + } + + int intersects ( const sgVec4 plane ) const ; +} ; + + +#define SG_LEFT_PLANE 0 +#define SG_RIGHT_PLANE 1 +#define SG_BOT_PLANE 2 +#define SG_TOP_PLANE 3 +#define SG_NEAR_PLANE 4 +#define SG_FAR_PLANE 5 + +class sgFrustum +{ + /* Is the projection orthographic (or perspective)? */ + int ortho ; + + /* The parameters for glFrustum/glOrtho */ + + SGfloat left, right, bot, top, nnear, ffar ; + + /* The computed projection matrix for this frustum */ + + sgMat4 mat ; + + /* The A,B,C,D terms of the plane equations of the clip planes */ + /* A point (x,y,z) is inside the frustum iff Ax + By + Cz + D >= 0 for all planes */ + + sgVec4 plane [ 6 ] ; + + /* These two are only valid for simple frusta */ + /* Note that to convert to parameters for gluPerspective you do the following: + * "fovy" is "vfov" + * "aspect" is the ratio "hfov" / "vfov" + * Note also that the "hfov" and "vfov" variables are NOT automatically set. + */ + + SGfloat hfov ; /* Horizontal Field of View -or- Orthographic Width */ + SGfloat vfov ; /* Vertical Field of View -or- Orthographic Height */ + + void update (void) ; + int getOutcode ( const sgVec4 src ) const ; + +public: + + sgFrustum (void) + { + ortho = FALSE ; + nnear = SG_ONE ; + ffar = 1000000.0f ; + hfov = SG_45 ; + vfov = SG_45 ; + update () ; + } + + void setFrustum ( const SGfloat l, const SGfloat r, + const SGfloat b, const SGfloat t, + const SGfloat n, const SGfloat f ) + { + ortho = FALSE ; + left = l ; + right = r ; + bot = b ; + top = t ; + nnear = n ; + ffar = f ; + hfov = vfov = SG_ZERO ; + update () ; + } + + void setOrtho ( const SGfloat l, const SGfloat r, + const SGfloat b, const SGfloat t, + const SGfloat n, const SGfloat f ) + { + ortho = TRUE ; + left = l ; + right = r ; + bot = b ; + top = t ; + nnear = n ; + ffar = f ; + hfov = vfov = SG_ZERO ; + update () ; + } + + void getMat4 ( sgMat4 dst ) { sgCopyMat4 ( dst, mat ) ; } + + SGfloat getLeft (void) const { return left ; } + SGfloat getRight(void) const { return right ; } + SGfloat getBot (void) const { return bot ; } + SGfloat getTop (void) const { return top ; } + SGfloat getNear (void) const { return nnear ; } + SGfloat getFar (void) const { return ffar ; } + + const SGfloat *getPlane ( int i ) const { return plane [ i ] ; } + + SGfloat getHFOV (void) const { return hfov ; } + SGfloat getVFOV (void) const { return vfov ; } + + void getFOV ( SGfloat *h, SGfloat *v ) const + { + if ( h != (SGfloat *) 0 ) *h = hfov ; + if ( v != (SGfloat *) 0 ) *v = vfov ; + } + + void setFOV ( const SGfloat h, const SGfloat v ) + { + ortho = FALSE ; + hfov = ( h <= 0 ) ? ( v * SG_FOUR / SG_THREE ) : h ; + vfov = ( v <= 0 ) ? ( h * SG_THREE / SG_FOUR ) : v ; + update () ; + } + + void getOrtho ( SGfloat *w, SGfloat *h ) const + { + if ( w != (SGfloat *) 0 ) *w = right - left ; + if ( h != (SGfloat *) 0 ) *h = top - bot ; + } + + void setOrtho ( const SGfloat w, const SGfloat h ) + { + ortho = TRUE ; + hfov = ( w <= 0 ) ? ( h * SG_FOUR / SG_THREE ) : w ; + vfov = ( h <= 0 ) ? ( w * SG_FOUR / SG_THREE ) : h ; + update () ; + } + + void getNearFar ( SGfloat *n, SGfloat *f ) const + { + if ( n != (SGfloat *) 0 ) *n = nnear ; + if ( f != (SGfloat *) 0 ) *f = ffar ; + } + + void setNearFar ( const SGfloat n, const SGfloat f ) + { + nnear = n ; + ffar = f ; + update () ; + } + + int isOrtho (void) const { return ortho ; } + + int contains ( const sgVec3 p ) const ; + int contains ( const sgSphere *s ) const ; + int contains ( const sgBox *b ) const ; +} ; + + +/* + Quaternion routines are Copyright (C) 1999 + Kevin B. Thompson + Modified by Sylvan W. Clebsch + Largely rewritten by "Negative0" + Added to by John Fay +*/ + +/* + Quaternion structure w = real, (x, y, z) = vector + CHANGED sqQuat to float array so that syntax matches + vector and matrix routines +*/ + + +inline void sgMakeIdentQuat ( sgQuat dst ) +{ + sgSetVec4 ( dst, SG_ZERO, SG_ZERO, SG_ZERO, SG_ONE ) ; +} + + +inline void sgSetQuat ( sgQuat dst, + const SGfloat w, const SGfloat x, + const SGfloat y, const SGfloat z ) +{ + sgSetVec4 ( dst, x, y, z, w ) ; +} + +inline void sgCopyQuat ( sgQuat dst, const sgQuat src ) +{ + sgCopyVec4 ( dst, src ) ; +} + + +/* Construct a unit quaternion (length==1) */ + +inline void sgNormaliseQuat ( sgQuat dst, const sgQuat src ) +{ + SGfloat d = sgScalarProductVec4 ( src, src ) ; + + d = (d > SG_ZERO) ? (SG_ONE / sgSqrt ( d )) : SG_ONE ; + + sgScaleVec4 ( dst, src, d ) ; +} + + + +inline void sgNormaliseQuat ( sgQuat dst ) { sgNormaliseQuat ( dst, dst ) ; } + + +inline void sgInvertQuat ( sgQuat dst, const sgQuat src ) +{ + SGfloat d = sgScalarProductVec4 ( src, src ) ; + + d = ( d == SG_ZERO ) ? SG_ONE : ( SG_ONE / d ) ; + + dst[SG_W] = src[SG_W] * d ; + dst[SG_X] = -src[SG_X] * d ; + dst[SG_Y] = -src[SG_Y] * d ; + dst[SG_Z] = -src[SG_Z] * d ; +} + +inline void sgInvertQuat ( sgQuat dst ) { sgInvertQuat ( dst, dst ) ; } + + +/* Make an angle and axis of rotation from a Quaternion. */ + +void sgQuatToAngleAxis ( SGfloat *angle, sgVec3 axis, const sgQuat src ) ; +void sgQuatToAngleAxis ( SGfloat *angle, + SGfloat *x, SGfloat *y, SGfloat *z, + const sgQuat src ) ; + +/* Make a quaternion from a given angle and axis of rotation */ + +void sgAngleAxisToQuat ( sgQuat dst, const SGfloat angle, const sgVec3 axis ) ; +void sgAngleAxisToQuat ( sgQuat dst, + const SGfloat angle, + const SGfloat x, const SGfloat y, const SGfloat z ) ; + +/* Convert a matrix to/from a quat */ + +void sgMatrixToQuat ( sgQuat quat, const sgMat4 m ) ; +void sgQuatToMatrix ( sgMat4 m, const sgQuat quat ) ; + +/* Convert a set of eulers to/from a quat */ + +void sgQuatToEuler( sgVec3 hpr, const sgQuat quat ) ; +void sgEulerToQuat( sgQuat quat, const sgVec3 hpr ) ; + +inline void sgEulerToQuat( sgQuat dst, + SGfloat h, SGfloat p, SGfloat r ) +{ + sgVec3 hpr ; + + sgSetVec3 ( hpr, h, p, r ) ; + + sgEulerToQuat( dst, hpr ) ; +} + +inline void sgHPRToQuat ( sgQuat dst, SGfloat h, SGfloat p, SGfloat r ) +{ + sgVec3 hpr; + + hpr[0] = h * SG_DEGREES_TO_RADIANS ; + hpr[1] = p * SG_DEGREES_TO_RADIANS ; + hpr[2] = r * SG_DEGREES_TO_RADIANS ; + + sgEulerToQuat( dst, hpr ) ; +} + +inline void sgHPRToQuat ( sgQuat dst, const sgVec3 hpr ) +{ + sgVec3 tmp ; + + sgScaleVec3 ( tmp, hpr, SG_DEGREES_TO_RADIANS ) ; + + sgEulerToQuat ( dst, tmp ) ; +} + + +/* Multiply quaternions together (concatenate rotations) */ + +void sgMultQuat ( sgQuat dst, const sgQuat a, const sgQuat b ) ; + +inline void sgPostMultQuat ( sgQuat dst, const sgQuat q ) +{ + sgQuat r ; + + sgCopyQuat ( r, dst ) ; + sgMultQuat ( dst, r, q ) ; +} + +inline void sgPreMultQuat ( sgQuat dst, const sgQuat q ) +{ + sgQuat r ; + + sgCopyQuat ( r, dst ) ; + sgMultQuat ( dst, q, r ) ; +} + + +/* Rotate a quaternion by a given angle and axis (convenience function) */ + + +inline void sgPreRotQuat ( sgQuat dst, const SGfloat angle, const sgVec3 axis ) +{ + sgQuat q ; + sgAngleAxisToQuat ( q, angle, axis ) ; + sgPreMultQuat ( dst, q ) ; + sgNormaliseQuat ( dst ) ; +} + + +inline void sgPostRotQuat ( sgQuat dst, const SGfloat angle, const sgVec3 axis ) +{ + sgQuat q ; + sgAngleAxisToQuat ( q, angle, axis ) ; + sgPostMultQuat ( dst, q ) ; + sgNormaliseQuat ( dst ) ; +} + + +inline void sgPreRotQuat ( sgQuat dst, + const SGfloat angle, + const SGfloat x, const SGfloat y, const SGfloat z ) +{ + sgVec3 axis ; + + sgSetVec3 ( axis, x, y, z ) ; + sgPreRotQuat ( dst, angle, axis ) ; +} + +inline void sgPostRotQuat ( sgQuat dst, + const SGfloat angle, + const SGfloat x, const SGfloat y, const SGfloat z ) +{ + sgVec3 axis ; + + sgSetVec3 ( axis, x, y, z ) ; + sgPostRotQuat ( dst, angle, axis ) ; +} + + +/* more meaningful names */ +#define sgWorldRotQuat sgPostRotQuat +#define sgLocalRotQuat sgPreRotQuat + +/* for backwards compatibility */ +#define sgRotQuat sgPostRotQuat + + +/* SWC - Interpolate between to quaternions */ + +extern void sgSlerpQuat ( sgQuat dst, + const sgQuat from, const sgQuat to, + const SGfloat t ) ; + + + +/* + Intersection testing. +*/ + +int sgIsectPlanePlane ( sgVec3 point, sgVec3 dir, + sgVec4 plane1, sgVec4 plane2 ) ; +int sgIsectInfLinePlane ( sgVec3 dst, + sgVec3 l_org, sgVec3 l_vec, + sgVec4 plane ) ; +int sgIsectInfLineInfLine ( sgVec3 dst, + sgVec3 l1_org, sgVec3 l1_vec, + sgVec3 l2_org, sgVec3 l2_vec ) ; +SGfloat sgIsectLinesegPlane ( sgVec3 dst, + sgVec3 v1, sgVec3 v2, + sgVec4 plane ) ; + +bool sgPointInTriangle3 ( sgVec3 point, sgVec3 tri[3] ) ; +bool sgPointInTriangle2 ( sgVec2 point, sgVec2 tri[3] ) ; + +inline bool sgPointInTriangle ( sgVec3 point, sgVec3 tri[3] ) +{ + return sgPointInTriangle3 ( point, tri ) ; +} + + + +/**********************************************************************/ + +#define sgdFloat double +#define SGDfloat double + +#define SGD_ZERO 0.0 +#define SGD_HALF 0.5 +#define SGD_ONE 1.0 +#define SGD_TWO 2.0 +#define SGD_THREE 3.0 +#define SGD_FOUR 4.0 +#define SGD_45 45.0 +#define SGD_60 60.0 +#define SGD_90 90.0 +#define SGD_180 180.0 +#define SGD_MAX DBL_MAX + + +#define SGD_X 0 +#define SGD_Y 1 +#define SGD_Z 2 +#define SGD_W 3 + +#ifndef M_PI +#define SGD_PI 3.14159265358979323846 /* From M_PI under Linux/X86 */ +#else +#define SGD_PI M_PI +#endif + +#define SGD_DEGREES_TO_RADIANS (SGD_PI/SGD_180) +#define SGD_RADIANS_TO_DEGREES (SGD_180/SGD_PI) + +/* + These are just convenient redefinitions of standard + math library functions to stop float/double warnings. +*/ + +inline SGDfloat sgdSqrt ( const SGDfloat x ) { return sqrt ( x ) ; } +inline SGDfloat sgdSquare ( const SGDfloat x ) { return x * x ; } +inline SGDfloat sgdAbs ( const SGDfloat a ) { return ( a < SGD_ZERO ) ? -a : a ; } + +inline SGDfloat sgdASin ( SGDfloat s ) + { return (SGDfloat) asin ( s ) * SGD_RADIANS_TO_DEGREES ; } +inline SGDfloat sgdACos ( SGDfloat s ) + { return (SGDfloat) acos ( s ) * SGD_RADIANS_TO_DEGREES ; } +inline SGDfloat sgdATan ( SGDfloat s ) + { return (SGDfloat) atan ( s ) * SGD_RADIANS_TO_DEGREES ; } +inline SGDfloat sgdATan2 ( SGDfloat y, SGDfloat x ) + { return (SGDfloat) atan2 ( y,x ) * SGD_RADIANS_TO_DEGREES ; } +inline SGDfloat sgdSin ( SGDfloat s ) + { return (SGDfloat) sin ( s * SGD_DEGREES_TO_RADIANS ) ; } +inline SGDfloat sgdCos ( SGDfloat s ) + { return (SGDfloat) cos ( s * SGD_DEGREES_TO_RADIANS ) ; } +inline SGDfloat sgdTan ( SGDfloat s ) + { return (SGDfloat) tan ( s * SGD_DEGREES_TO_RADIANS ) ; } + +inline int sgdCompareFloat ( const SGDfloat a, const SGDfloat b, const SGDfloat tol ) +{ + if ( ( a + tol ) < b ) return -1 ; + if ( ( b + tol ) < a ) return 1 ; + return 0 ; +} + + +/* + Types used in SGD. +*/ + +typedef SGDfloat sgdVec2 [ 2 ] ; +typedef SGDfloat sgdVec3 [ 3 ] ; +typedef SGDfloat sgdVec4 [ 4 ] ; + +typedef sgdVec4 sgdQuat ; + +typedef SGDfloat sgdMat3 [3][3] ; +typedef SGDfloat sgdMat4 [4][4] ; + +struct sgdCoord +{ + sgdVec3 xyz ; + sgdVec3 hpr ; +} ; + +class sgdSphere ; +class sgdBox ; +class sgdFrustum ; + +/* + Some handy constants +*/ + +#define SGD_OUTSIDE FALSE +#define SGD_INSIDE TRUE +#define SGD_STRADDLE 2 + +inline SGDfloat sgdHeightOfPlaneVec2 ( const sgdVec4 plane, const sgdVec2 pnt ) +{ + if ( plane[2] == SGD_ZERO ) + return SGD_ZERO ; + else + return -( plane[0] * pnt[0] + plane[1] * pnt[1] + plane[3] ) / plane[2] ; +} + +/* + Convert a direction vector into a set of euler angles, + (with zero roll) +*/ + +extern void sgdHPRfromVec3 ( sgdVec3 hpr, const sgdVec3 src ) ; + +extern void sgdMakeCoordMat4 ( sgdMat4 dst, const SGDfloat x, const SGDfloat y, const SGDfloat z, + const SGDfloat h, const SGDfloat p, const SGDfloat r ) ; + +inline void sgdMakeCoordMat4( sgdMat4 dst, const sgdVec3 xyz, const sgdVec3 hpr ) +{ + sgdMakeCoordMat4 ( dst, xyz[0], xyz[1], xyz[2], + hpr[0], hpr[1], hpr[2] ) ; +} + +inline void sgdMakeCoordMat4( sgdMat4 dst, const sgdCoord *src ) +{ + sgdMakeCoordMat4 ( dst, src->xyz, src->hpr ) ; +} + +extern void sgdMakeRotMat4 ( sgdMat4 dst, const SGDfloat angle, const sgdVec3 axis ) ; + +inline void sgdMakeRotMat4 ( sgdMat4 dst, const sgdVec3 hpr ) +{ + sgdMakeCoordMat4 ( dst, SGD_ZERO, SGD_ZERO, SGD_ZERO, hpr[0], hpr[1], hpr[2] ) ; +} + +inline void sgdMakeRotMat4 ( sgdMat4 dst, const SGDfloat h, const SGDfloat p, const SGDfloat r ) +{ + sgdMakeCoordMat4 ( dst, SGD_ZERO, SGD_ZERO, SGD_ZERO, h, p, r ) ; +} + +extern void sgdMakeTransMat4 ( sgdMat4 dst, const sgdVec3 xyz ) ; +extern void sgdMakeTransMat4 ( sgdMat4 dst, const SGDfloat x, const SGDfloat y, const SGDfloat z ) ; + + +extern void sgdSetCoord ( sgdCoord *coord, const sgdMat4 src ) ; + +extern void sgdMultMat4 ( sgdMat4 dst, const sgdMat4 a, const sgdMat4 b ) ; +extern void sgdPostMultMat4 ( sgdMat4 dst, const sgdMat4 a ) ; +extern void sgdPreMultMat4 ( sgdMat4 dst, const sgdMat4 a ) ; + +extern void sgdTransposeNegateMat4 ( sgdMat4 dst ) ; +extern void sgdTransposeNegateMat4 ( sgdMat4 dst, const sgdMat4 src ) ; + +extern void sgdInvertMat4 ( sgdMat4 dst, const sgdMat4 src ) ; +inline void sgdInvertMat4 ( sgdMat4 dst ) { sgdInvertMat4 ( dst, dst ) ; } + +extern void sgdXformVec3 ( sgdVec3 dst, const sgdVec3 src, const sgdMat4 mat ) ; +extern void sgdXformPnt3 ( sgdVec3 dst, const sgdVec3 src, const sgdMat4 mat ) ; +extern void sgdXformVec4 ( sgdVec4 dst, const sgdVec4 src, const sgdMat4 mat ) ; +extern void sgdXformPnt4 ( sgdVec4 dst, const sgdVec4 src, const sgdMat4 mat ) ; +extern void sgdFullXformPnt3 ( sgdVec3 dst, const sgdVec3 src, const sgdMat4 mat ) ; +extern void sgdFullXformPnt4 ( sgdVec4 dst, const sgdVec4 src, const sgdMat4 mat ) ; + +inline void sgdXformVec3 ( sgdVec3 dst, const sgdMat4 mat ) { sgdXformVec3 ( dst, dst, mat ) ; } +inline void sgdXformPnt3 ( sgdVec3 dst, const sgdMat4 mat ) { sgdXformPnt3 ( dst, dst, mat ) ; } +inline void sgdXformVec4 ( sgdVec4 dst, const sgdMat4 mat ) { sgdXformVec4 ( dst, dst, mat ) ; } +inline void sgdXformPnt4 ( sgdVec4 dst, const sgdMat4 mat ) { sgdXformPnt4 ( dst, dst, mat ) ; } +inline void sgdFullXformPnt3 ( sgdVec3 dst, const sgdMat4 mat ) { sgdFullXformPnt3 ( dst, dst, mat ) ; } +inline void sgdFullXformPnt4 ( sgdVec4 dst, const sgdMat4 mat ) { sgdFullXformPnt4 ( dst, dst, mat ) ; } + +/* + Basic low-level vector functions. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + For each of Vec2, Vec3 and Vec4, we provide inlines for + + Zero - set all elements to zero. + Set - set each element individually. + Add - add vectors element by element. + Sub - subtract vectors element by element. + Scale - multiply each element of a vector by a variable. + Negate - negate each element of a vector. + Compare - compare vectors element by element with optional tolerance. + (return TRUE if vectors are equal - within tolerances) + Equal - return TRUE if vectors are exactly equal. + Length - compute length of a vector. + Distance - compute distance between two points. + LengthSquared - compute the square of the length of a vector. + DistanceSquared - compute the square of the distance between two points. + ScalarProduct - scalar (dot) product. + VectorProduct - vector (cross) product (3-element vectors ONLY!). + Normalise/Normalize - make vector be one unit long. + Lerp - linear interpolation by a fraction 'f'. +*/ + +inline void sgdZeroVec2 ( sgdVec2 dst ) { dst[0]=dst[1]=SGD_ZERO ; } +inline void sgdZeroVec3 ( sgdVec3 dst ) { dst[0]=dst[1]=dst[2]=SGD_ZERO ; } +inline void sgdZeroVec4 ( sgdVec4 dst ) { dst[0]=dst[1]=dst[2]=dst[3]=SGD_ZERO ; } + + +inline void sgdSetVec2 ( sgdVec2 dst, const SGDfloat x, const SGDfloat y ) +{ + dst [ 0 ] = x ; + dst [ 1 ] = y ; +} + +inline void sgdSetVec3 ( sgdVec3 dst, const SGDfloat x, const SGDfloat y, const SGDfloat z ) +{ + dst [ 0 ] = x ; + dst [ 1 ] = y ; + dst [ 2 ] = z ; +} + +inline void sgdSetVec4 ( sgdVec4 dst, const SGDfloat x, const SGDfloat y, const SGDfloat z, const SGDfloat w ) +{ + dst [ 0 ] = x ; + dst [ 1 ] = y ; + dst [ 2 ] = z ; + dst [ 3 ] = w ; +} + + +inline void sgdCopyVec2 ( sgdVec2 dst, const sgdVec2 src ) +{ + dst [ 0 ] = src [ 0 ] ; + dst [ 1 ] = src [ 1 ] ; +} + +inline void sgdCopyVec3 ( sgdVec3 dst, const sgdVec3 src ) +{ + dst [ 0 ] = src [ 0 ] ; + dst [ 1 ] = src [ 1 ] ; + dst [ 2 ] = src [ 2 ] ; +} + +inline void sgdCopyVec4 ( sgdVec4 dst, const sgdVec4 src ) +{ + dst [ 0 ] = src [ 0 ] ; + dst [ 1 ] = src [ 1 ] ; + dst [ 2 ] = src [ 2 ] ; + dst [ 3 ] = src [ 3 ] ; +} + + +inline void sgdAddVec2 ( sgdVec2 dst, const sgdVec2 src ) +{ + dst [ 0 ] += src [ 0 ] ; + dst [ 1 ] += src [ 1 ] ; +} + +inline void sgdAddVec3 ( sgdVec3 dst, const sgdVec3 src ) +{ + dst [ 0 ] += src [ 0 ] ; + dst [ 1 ] += src [ 1 ] ; + dst [ 2 ] += src [ 2 ] ; +} + +inline void sgdAddVec4 ( sgdVec4 dst, const sgdVec4 src ) +{ + dst [ 0 ] += src [ 0 ] ; + dst [ 1 ] += src [ 1 ] ; + dst [ 2 ] += src [ 2 ] ; + dst [ 3 ] += src [ 3 ] ; +} + + +inline void sgdAddVec2 ( sgdVec2 dst, const sgdVec2 src1, const sgdVec2 src2 ) +{ + dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] ; + dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] ; +} + +inline void sgdAddVec3 ( sgdVec3 dst, const sgdVec3 src1, const sgdVec3 src2 ) +{ + dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] ; + dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] ; + dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] ; +} + +inline void sgdAddVec4 ( sgdVec4 dst, const sgdVec4 src1, const sgdVec4 src2 ) +{ + dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] ; + dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] ; + dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] ; + dst [ 3 ] = src1 [ 3 ] + src2 [ 3 ] ; +} + + +inline void sgdSubVec2 ( sgdVec2 dst, const sgdVec2 src ) +{ + dst [ 0 ] -= src [ 0 ] ; + dst [ 1 ] -= src [ 1 ] ; +} + +inline void sgdSubVec3 ( sgdVec3 dst, const sgdVec3 src ) +{ + dst [ 0 ] -= src [ 0 ] ; + dst [ 1 ] -= src [ 1 ] ; + dst [ 2 ] -= src [ 2 ] ; +} + +inline void sgdSubVec4 ( sgdVec4 dst, const sgdVec4 src ) +{ + dst [ 0 ] -= src [ 0 ] ; + dst [ 1 ] -= src [ 1 ] ; + dst [ 2 ] -= src [ 2 ] ; + dst [ 3 ] -= src [ 3 ] ; +} + +inline void sgdSubVec2 ( sgdVec2 dst, const sgdVec2 src1, const sgdVec2 src2 ) +{ + dst [ 0 ] = src1 [ 0 ] - src2 [ 0 ] ; + dst [ 1 ] = src1 [ 1 ] - src2 [ 1 ] ; +} + +inline void sgdSubVec3 ( sgdVec3 dst, const sgdVec3 src1, const sgdVec3 src2 ) +{ + dst [ 0 ] = src1 [ 0 ] - src2 [ 0 ] ; + dst [ 1 ] = src1 [ 1 ] - src2 [ 1 ] ; + dst [ 2 ] = src1 [ 2 ] - src2 [ 2 ] ; +} + +inline void sgdSubVec4 ( sgdVec4 dst, const sgdVec4 src1, const sgdVec4 src2 ) +{ + dst [ 0 ] = src1 [ 0 ] - src2 [ 0 ] ; + dst [ 1 ] = src1 [ 1 ] - src2 [ 1 ] ; + dst [ 2 ] = src1 [ 2 ] - src2 [ 2 ] ; + dst [ 3 ] = src1 [ 3 ] - src2 [ 3 ] ; +} + + +inline void sgdNegateVec2 ( sgdVec2 dst ) +{ + dst [ 0 ] = -dst [ 0 ] ; + dst [ 1 ] = -dst [ 1 ] ; +} + +inline void sgdNegateVec3 ( sgdVec3 dst ) +{ + dst [ 0 ] = -dst [ 0 ] ; + dst [ 1 ] = -dst [ 1 ] ; + dst [ 2 ] = -dst [ 2 ] ; +} + +inline void sgdNegateVec4 ( sgdVec4 dst ) +{ + dst [ 0 ] = -dst [ 0 ] ; + dst [ 1 ] = -dst [ 1 ] ; + dst [ 2 ] = -dst [ 2 ] ; + dst [ 3 ] = -dst [ 3 ] ; +} + + +inline void sgdNegateVec2 ( sgdVec2 dst, const sgdVec2 src ) +{ + dst [ 0 ] = -src [ 0 ] ; + dst [ 1 ] = -src [ 1 ] ; +} + +inline void sgdNegateVec3 ( sgdVec3 dst, const sgdVec3 src ) +{ + dst [ 0 ] = -src [ 0 ] ; + dst [ 1 ] = -src [ 1 ] ; + dst [ 2 ] = -src [ 2 ] ; +} + +inline void sgdNegateVec4 ( sgdVec4 dst, const sgdVec4 src ) +{ + dst [ 0 ] = -src [ 0 ] ; + dst [ 1 ] = -src [ 1 ] ; + dst [ 2 ] = -src [ 2 ] ; + dst [ 3 ] = -src [ 3 ] ; +} + + +inline void sgdScaleVec2 ( sgdVec2 dst, const SGDfloat s ) +{ + dst [ 0 ] *= s ; + dst [ 1 ] *= s ; +} + +inline void sgdScaleVec3 ( sgdVec3 dst, const SGDfloat s ) +{ + dst [ 0 ] *= s ; + dst [ 1 ] *= s ; + dst [ 2 ] *= s ; +} + +inline void sgdScaleVec4 ( sgdVec4 dst, const SGDfloat s ) +{ + dst [ 0 ] *= s ; + dst [ 1 ] *= s ; + dst [ 2 ] *= s ; + dst [ 3 ] *= s ; +} + +inline void sgdScaleVec2 ( sgdVec2 dst, const sgdVec2 src, const SGDfloat s ) +{ + dst [ 0 ] = src [ 0 ] * s ; + dst [ 1 ] = src [ 1 ] * s ; +} + +inline void sgdScaleVec3 ( sgdVec3 dst, const sgdVec3 src, const SGDfloat s ) +{ + dst [ 0 ] = src [ 0 ] * s ; + dst [ 1 ] = src [ 1 ] * s ; + dst [ 2 ] = src [ 2 ] * s ; +} + +inline void sgdScaleVec4 ( sgdVec4 dst, const sgdVec4 src, const SGDfloat s ) +{ + dst [ 0 ] = src [ 0 ] * s ; + dst [ 1 ] = src [ 1 ] * s ; + dst [ 2 ] = src [ 2 ] * s ; + dst [ 3 ] = src [ 3 ] * s ; +} + + +inline void sgdAddScaledVec2 ( sgdVec2 dst, const sgdVec2 src, const SGDfloat s ) +{ + dst [ 0 ] += src [ 0 ] * s ; + dst [ 1 ] += src [ 1 ] * s ; +} + +inline void sgdAddScaledVec3 ( sgdVec3 dst, const sgdVec3 src, const SGDfloat s ) +{ + dst [ 0 ] += src [ 0 ] * s ; + dst [ 1 ] += src [ 1 ] * s ; + dst [ 2 ] += src [ 2 ] * s ; +} + +inline void sgdAddScaledVec4 ( sgdVec4 dst, const sgdVec4 src, const SGDfloat s ) +{ + dst [ 0 ] += src [ 0 ] * s ; + dst [ 1 ] += src [ 1 ] * s ; + dst [ 2 ] += src [ 2 ] * s ; + dst [ 3 ] += src [ 3 ] * s ; +} + + +inline void sgdAddScaledVec2 ( sgdVec2 dst, const sgdVec2 src1, const sgdVec2 src2, const SGDfloat s ) +{ + dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] * s ; + dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] * s ; +} + +inline void sgdAddScaledVec3 ( sgdVec3 dst, const sgdVec3 src1, const sgdVec3 src2, const SGDfloat s ) +{ + dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] * s ; + dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] * s ; + dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] * s ; +} + +inline void sgdAddScaledVec4 ( sgdVec4 dst, const sgdVec4 src1, const sgdVec4 src2, const SGDfloat s ) +{ + dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] * s ; + dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] * s ; + dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] * s ; + dst [ 3 ] = src1 [ 3 ] + src2 [ 3 ] * s ; +} + + + +inline int sgdCompareVec2 ( const sgdVec2 a, const sgdVec2 b, const SGDfloat tol ) +{ + int val = 0 ; + + if ( ( val = sgdCompareFloat( a[0], b[0], tol ) ) != 0 ) return val ; + if ( ( val = sgdCompareFloat( a[1], b[1], tol ) ) != 0 ) return val ; + + return 0 ; +} + +inline int sgdCompareVec3 ( const sgdVec3 a, const sgdVec3 b, const SGDfloat tol ) +{ + int val = 0 ; + + if ( ( val = sgdCompareFloat( a[0], b[0], tol ) ) != 0 ) return val ; + if ( ( val = sgdCompareFloat( a[1], b[1], tol ) ) != 0 ) return val ; + if ( ( val = sgdCompareFloat( a[2], b[2], tol ) ) != 0 ) return val ; + + return 0 ; +} + +inline int sgdCompareVec4 ( const sgdVec4 a, const sgdVec4 b, const SGDfloat tol ) +{ + int val = 0 ; + + if ( ( val = sgdCompareFloat( a[0], b[0], tol ) ) != 0 ) return val ; + if ( ( val = sgdCompareFloat( a[1], b[1], tol ) ) != 0 ) return val ; + if ( ( val = sgdCompareFloat( a[2], b[2], tol ) ) != 0 ) return val ; + if ( ( val = sgdCompareFloat( a[3], b[3], tol ) ) != 0 ) return val ; + + return 0 ; +} + + +inline int sgdEqualVec2 ( const sgdVec2 a, const sgdVec2 b ) +{ + return a[0] == b[0] && + a[1] == b[1] ; +} + +inline int sgdEqualVec3 ( const sgdVec3 a, const sgdVec3 b ) +{ + return a[0] == b[0] && + a[1] == b[1] && + a[2] == b[2] ; +} + +inline int sgdEqualVec4 ( const sgdVec4 a, const sgdVec4 b ) +{ + return a[0] == b[0] && + a[1] == b[1] && + a[2] == b[2] && + a[3] == b[3] ; +} + + +inline SGDfloat sgdScalarProductVec2 ( const sgdVec2 a, const sgdVec2 b ) +{ + return a[0]*b[0] + a[1]*b[1] ; +} + +inline SGDfloat sgdScalarProductVec3 ( const sgdVec3 a, const sgdVec3 b ) +{ + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] ; +} + +inline SGDfloat sgdScalarProductVec4 ( const sgdVec4 a, const sgdVec4 b ) +{ + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3] ; +} + + +extern void sgdVectorProductVec3 ( sgdVec3 dst, const sgdVec3 a, const sgdVec3 b ) ; + + +inline void sgdLerpVec4 ( sgdVec4 dst, const sgdVec4 a, const sgdVec4 b, const SGDfloat f ) +{ + dst[0] = a[0] + f * ( b[0] - a[0] ) ; + dst[1] = a[1] + f * ( b[1] - a[1] ) ; + dst[2] = a[2] + f * ( b[2] - a[2] ) ; + dst[3] = a[3] + f * ( b[3] - a[3] ) ; +} + +inline void sgdLerpVec3 ( sgdVec3 dst, const sgdVec3 a, const sgdVec3 b, const SGDfloat f ) +{ + dst[0] = a[0] + f * ( b[0] - a[0] ) ; + dst[1] = a[1] + f * ( b[1] - a[1] ) ; + dst[2] = a[2] + f * ( b[2] - a[2] ) ; +} + +inline void sgdLerpVec2 ( sgdVec2 dst, const sgdVec2 a, const sgdVec2 b, const SGDfloat f ) +{ + dst[0] = a[0] + f * ( b[0] - a[0] ) ; + dst[1] = a[1] + f * ( b[1] - a[1] ) ; +} + +inline void sgdLerpAnglesVec3 ( sgdVec3 dst, const sgdVec3 a, + const sgdVec3 b, + const SGDfloat f ) +{ + sgdVec3 tmp ; + + if ( b[0] - a[0] > 180.0 ) tmp[0] = a[0] + 360.0 ; else + if ( b[0] - a[0] < -180.0 ) tmp[0] = a[0] - 360.0 ; else tmp[0] = a[0] ; + + if ( b[1] - a[1] > 180.0 ) tmp[1] = a[1] + 360.0 ; else + if ( b[1] - a[1] < -180.0 ) tmp[1] = a[1] - 360.0 ; else tmp[1] = a[1] ; + + if ( b[2] - a[2] > 180.0 ) tmp[2] = a[2] + 360.0 ; else + if ( b[2] - a[2] < -180.0 ) tmp[2] = a[2] - 360.0 ; else tmp[2] = a[2] ; + + dst[0] = tmp[0] + f * ( b[0] - tmp[0] ) ; + dst[1] = tmp[1] + f * ( b[1] - tmp[1] ) ; + dst[2] = tmp[2] + f * ( b[2] - tmp[2] ) ; +} + + + + +inline SGDfloat sgdDistanceSquaredVec2 ( const sgdVec2 a, const sgdVec2 b ) +{ + return sgdSquare ( a[0]-b[0] ) + sgdSquare ( a[1]-b[1] ) ; +} + +inline SGDfloat sgdDistanceSquaredVec3 ( const sgdVec3 a, const sgdVec3 b ) +{ + return sgdSquare ( a[0]-b[0] ) + sgdSquare ( a[1]-b[1] ) + + sgdSquare ( a[2]-b[2] ) ; +} + +inline SGDfloat sgdDistanceSquaredVec4 ( const sgdVec4 a, const sgdVec4 b ) +{ + return sgdSquare ( a[0]-b[0] ) + sgdSquare ( a[1]-b[1] ) + + sgdSquare ( a[2]-b[2] ) + sgdSquare ( a[3]-b[3] ) ; +} + + +inline SGDfloat sgdDistanceVec2 ( const sgdVec2 a, const sgdVec2 b ) +{ + return sgdSqrt ( sgdSquare ( a[0]-b[0] ) + sgdSquare ( a[1]-b[1] ) ) ; +} + +inline SGDfloat sgdDistanceVec3 ( const sgdVec3 a, const sgdVec3 b ) +{ + return sgdSqrt ( sgdSquare ( a[0]-b[0] ) + sgdSquare ( a[1]-b[1] ) + + sgdSquare ( a[2]-b[2] ) ) ; +} + +inline SGDfloat sgdDistanceVec4 ( const sgdVec4 a, const sgdVec4 b ) +{ + return sgdSqrt ( sgdSquare ( a[0]-b[0] ) + sgdSquare ( a[1]-b[1] ) + + sgdSquare ( a[2]-b[2] ) + sgdSquare ( a[3]-b[3] ) ) ; +} + + +inline SGDfloat sgdLengthVec2 ( sgdVec2 const src ) +{ + return sgdSqrt ( sgdScalarProductVec2 ( src, src ) ) ; +} + +inline SGDfloat sgdLengthVec3 ( sgdVec3 const src ) +{ + return sgdSqrt ( sgdScalarProductVec3 ( src, src ) ) ; +} + +inline SGDfloat sgdLengthVec4 ( sgdVec4 const src ) +{ + return sgdSqrt ( sgdScalarProductVec4 ( src, src ) ) ; +} + +inline SGDfloat sgdLengthSquaredVec2 ( sgdVec2 const src ) +{ + return sgdScalarProductVec2 ( src, src ) ; +} + +inline SGDfloat sgdLengthSquaredVec3 ( sgdVec3 const src ) +{ + return sgdScalarProductVec3 ( src, src ) ; +} + +inline SGDfloat sgdLengthSquaredVec4 ( sgdVec4 const src ) +{ + return sgdScalarProductVec4 ( src, src ) ; +} + +/* Anglo-US spelling issues. */ +#define sgdNormalizeVec2 sgdNormaliseVec2 +#define sgdNormalizeVec3 sgdNormaliseVec3 +#define sgdNormalizeVec4 sgdNormaliseVec4 +#define sgdNormalizeQuat sgdNormaliseQuat + +inline void sgdNormaliseVec2 ( sgdVec2 dst ) +{ + sgdScaleVec2 ( dst, SGD_ONE / sgdLengthVec2 ( dst ) ) ; +} + +inline void sgdNormaliseVec3 ( sgdVec3 dst ) +{ + sgdScaleVec3 ( dst, SGD_ONE / sgdLengthVec3 ( dst ) ) ; +} + +inline void sgdNormaliseVec4 ( sgdVec4 dst ) +{ + sgdScaleVec4 ( dst, SGD_ONE / sgdLengthVec4 ( dst ) ) ; +} + +inline void sgdNormaliseVec2 ( sgdVec2 dst, const sgdVec2 src ) +{ + sgdScaleVec2 ( dst, src, SGD_ONE / sgdLengthVec2 ( src ) ) ; +} + +inline void sgdNormaliseVec3 ( sgdVec3 dst, const sgdVec3 src ) +{ + sgdScaleVec3 ( dst, src, SGD_ONE / sgdLengthVec3 ( src ) ) ; +} + +inline void sgdNormaliseVec4 ( sgdVec4 dst, const sgdVec4 src ) +{ + sgdScaleVec4 ( dst, src, SGD_ONE / sgdLengthVec4 ( src ) ) ; +} + + +inline void sgdZeroCoord ( sgdCoord *dst ) +{ + sgdSetVec3 ( dst->xyz, SGD_ZERO, SGD_ZERO, SGD_ZERO ) ; + sgdSetVec3 ( dst->hpr, SGD_ZERO, SGD_ZERO, SGD_ZERO ) ; +} + +inline void sgdSetCoord ( sgdCoord *dst, const SGDfloat x, const SGDfloat y, const SGDfloat z, + const SGDfloat h, const SGDfloat p, const SGDfloat r ) +{ + sgdSetVec3 ( dst->xyz, x, y, z ) ; + sgdSetVec3 ( dst->hpr, h, p, r ) ; +} + +inline void sgdSetCoord ( sgdCoord *dst, const sgdVec3 xyz, const sgdVec3 hpr ) +{ + sgdCopyVec3 ( dst->xyz, xyz ) ; + sgdCopyVec3 ( dst->hpr, hpr ) ; +} + +inline void sgdCopyCoord ( sgdCoord *dst, const sgdCoord *src ) +{ + sgdCopyVec3 ( dst->xyz, src->xyz ) ; + sgdCopyVec3 ( dst->hpr, src->hpr ) ; +} + + + +inline void sgdCopyMat4 ( sgdMat4 dst, const sgdMat4 src ) +{ + sgdCopyVec4 ( dst[ 0 ], src[ 0 ] ) ; + sgdCopyVec4 ( dst[ 1 ], src[ 1 ] ) ; + sgdCopyVec4 ( dst[ 2 ], src[ 2 ] ) ; + sgdCopyVec4 ( dst[ 3 ], src[ 3 ] ) ; +} + + +inline void sgdScaleMat4 ( sgdMat4 dst, const sgdMat4 src, const SGDfloat scale ) +{ + sgdScaleVec4 ( dst[0], src[0], scale ) ; + sgdScaleVec4 ( dst[1], src[1], scale ) ; + sgdScaleVec4 ( dst[2], src[2], scale ) ; + sgdScaleVec4 ( dst[3], src[3], scale ) ; +} + + +inline void sgdMakeIdentMat4 ( sgdMat4 dst ) +{ + sgdSetVec4 ( dst[0], SGD_ONE , SGD_ZERO, SGD_ZERO, SGD_ZERO ) ; + sgdSetVec4 ( dst[1], SGD_ZERO, SGD_ONE , SGD_ZERO, SGD_ZERO ) ; + sgdSetVec4 ( dst[2], SGD_ZERO, SGD_ZERO, SGD_ONE , SGD_ZERO ) ; + sgdSetVec4 ( dst[3], SGD_ZERO, SGD_ZERO, SGD_ZERO, SGD_ONE ) ; +} + + +extern void sgdMakeTransMat4 ( sgdMat4 m, const SGDfloat x, const SGDfloat y, const SGDfloat z ) ; +extern void sgdMakeTransMat4 ( sgdMat4 m, const sgdVec3 xyz ) ; +extern void sgdMakeCoordMat4 ( sgdMat4 m, const SGDfloat x, const SGDfloat y, const SGDfloat z, + const SGDfloat h, const SGDfloat p, const SGDfloat r ) ; +extern void sgdMakeCoordMat4 ( sgdMat4 m, const sgdCoord *c ) ; + +extern int sgdCompare3DSqdDist ( const sgdVec3 a, const sgdVec3 b, const SGDfloat sqd_dist ) ; + +inline SGDfloat sgdDistToLineVec2 ( const sgdVec3 line, const sgdVec2 pnt ) +{ + return sgdScalarProductVec2 ( line, pnt ) + line[2] ; +} + + +struct sgdLineSegment3 /* Bounded line segment */ +{ + sgdVec3 a ; + sgdVec3 b ; +} ; + +struct sgdLine3 /* Infinite line */ +{ + sgdVec3 point_on_line ; + sgdVec3 direction_vector ; /* Should be a unit vector */ +} ; + + +inline void sgdLineSegment3ToLine3 ( sgdLine3 *line, + const sgdLineSegment3 lineseg ) +{ + sgdCopyVec3 ( line->point_on_line , lineseg.a ) ; + sgdSubVec3 ( line->direction_vector, lineseg.b, lineseg.a ) ; + sgdNormaliseVec3 ( line->direction_vector ) ; +} + + +SGDfloat sgdDistSquaredToLineVec3 ( const sgdLine3 line, + const sgdVec3 pnt ) ; +SGDfloat sgdDistSquaredToLineSegmentVec3 ( const sgdLineSegment3 line, + const sgdVec3 pnt ) ; + + +inline SGDfloat sgdDistToLineVec3 ( const sgdLine3 line, + const sgdVec3 pnt ) +{ + return sgdSqrt ( sgdDistSquaredToLineVec3 ( line, pnt ) ); +} + + +inline SGDfloat sgdDistToLineSegmentVec3 ( const sgdLineSegment3 line, + const sgdVec3 pnt ) +{ + return sgdSqrt ( sgdDistSquaredToLineSegmentVec3(line,pnt) ) ; +} + +inline SGDfloat sgdDistToPlaneVec3 ( const sgdVec4 plane, const sgdVec3 pnt ) +{ + return sgdScalarProductVec3 ( plane, pnt ) + plane[3] ; +} + +inline SGDfloat sgdHeightAbovePlaneVec3 ( const sgdVec4 plane, const sgdVec3 pnt ) +{ + return pnt[2] - sgdHeightOfPlaneVec2 ( plane, pnt ) ; +} + +extern void sgdReflectInPlaneVec3 ( sgdVec3 dst, const sgdVec3 src, const sgdVec4 plane ) ; + +inline void sgdReflectInPlaneVec3 ( sgdVec3 dst, const sgdVec4 plane ) +{ + sgdReflectInPlaneVec3 ( dst, dst, plane ) ; +} + +extern void sgdMakeNormal ( sgdVec3 dst, const sgdVec3 a, const sgdVec3 b, const sgdVec3 c ) ; + +inline void sgdMake2DLine ( sgdVec3 dst, const sgdVec2 a, const sgdVec2 b ) +{ + dst[0] = b[1]-a[1] ; + dst[1] = -b[0]-a[0] ; + sgdNormalizeVec2 ( dst ) ; + dst[2] = - ( dst[0]*a[0] + dst[1]*a[1] ) ; +} + +inline void sgdMakePlane ( sgdVec4 dst, const sgdVec3 normal, const sgdVec3 pnt ) +{ + sgdCopyVec3 ( dst, normal ) ; + dst [ 3 ] = - sgdScalarProductVec3 ( normal, pnt ) ; +} + +inline void sgdMakePlane ( sgdVec4 dst, const sgdVec3 a, const sgdVec3 b, const sgdVec3 c ) +{ + /* + Ax + By + Cz + D == 0 ; + D = - ( Ax + By + Cz ) + = - ( A*a[0] + B*a[1] + C*a[2] ) + = - sgdScalarProductVec3 ( normal, a ) ; + */ + + sgdMakeNormal ( dst, a, b, c ) ; + + dst [ 3 ] = - sgdScalarProductVec3 ( dst, a ) ; +} + +SGDfloat sgdTriArea( sgdVec3 p0, sgdVec3 p1, sgdVec3 p2 ); + + +// Fast code. Result is in the range 0..180: +inline SGDfloat sgdAngleBetweenNormalizedVec3 ( sgdVec3 v1, sgdVec3 v2 ) +{ + SGDfloat f = sgdScalarProductVec3 ( v1, v2 ) ; + + return (float) acos ( ( f >= 1.0f ) ? 1.0f : + ( f <= -1.0f ) ? -1.0f : f ) * + SGD_RADIANS_TO_DEGREES ; +} + +// Fast code. Result is in the range 0..180: + +SGDfloat sgdAngleBetweenVec3 ( sgdVec3 v1, sgdVec3 v2 ); + +// All three have to be normalized. Slow code. Result is in the range 0..360: + +SGDfloat sgdAngleBetweenNormalizedVec3 (sgdVec3 first, sgdVec3 second, sgdVec3 normal); + +// Normal has to be normalized. Slow code. Result is in the range 0..360: + +SGDfloat sgdAngleBetweenVec3 ( sgdVec3 v1, sgdVec3 v2, sgdVec3 normal ); + + + +class sgdSphere +{ +public: + sgdVec3 center ; + SGDfloat radius ; + + + const SGDfloat *getCenter (void) const { return center ; } + + void setCenter ( const sgdVec3 c ) + { + sgdCopyVec3 ( center, c ) ; + } + + void setCenter ( const SGDfloat x, const SGDfloat y, const SGDfloat z ) + { + sgdSetVec3 ( center, x, y, z ) ; + } + + SGDfloat getRadius (void) const { return radius ; } + void setRadius ( const SGDfloat r ) { radius = r ; } + + int isEmpty (void) const { return radius < SGD_ZERO ; } + void empty (void) { radius = - SGD_ONE ; } + + void orthoXform ( const sgdMat4 m ) + { + sgdXformPnt3 ( center, center, m ) ; + // radius *= sgdLengthVec3 ( m[0] ) ; + } + + void extend ( const sgdSphere *s ) ; + void extend ( const sgdBox *b ) ; + void extend ( const sgdVec3 v ) ; + + int intersects ( const sgdSphere *s ) const + { + return sgdCompare3DSqdDist ( center, s->getCenter(), + sgdSquare ( radius + s->getRadius() ) ) <= 0 ; + } + + int intersects ( const sgdVec4 plane ) const + { + return sgdAbs ( sgdDistToPlaneVec3 ( plane, center ) ) <= radius ; + } + + int intersects ( const sgdBox *b ) const ; +} ; + + +class sgdBox +{ +public: + sgdVec3 min ; + sgdVec3 max ; + + + const SGDfloat *getMin (void) const { return min ; } + const SGDfloat *getMax (void) const { return max ; } + + void setMin ( const SGDfloat x, const SGDfloat y, const SGDfloat z ) + { + sgdSetVec3 ( min, x, y, z ) ; + } + + void setMin ( const sgdVec3 src ) + { + sgdCopyVec3 ( min, src ) ; + } + + void setMax ( const SGDfloat x, const SGDfloat y, const SGDfloat z ) + { + sgdSetVec3 ( max, x, y, z ) ; + } + + void setMax ( const sgdVec3 src ) + { + sgdCopyVec3 ( max, src ) ; + } + + int isEmpty(void) const + { + return ( min[0] > max[0] || + min[1] > max[1] || + min[2] > max[2] ) ; + } + + void empty (void) + { + sgdSetVec3 ( min, SGD_MAX, SGD_MAX, SGD_MAX ) ; + sgdSetVec3 ( max, -SGD_MAX, -SGD_MAX, -SGD_MAX ) ; + } + + void extend ( const sgdSphere *s ) ; + void extend ( const sgdBox *b ) ; + void extend ( const sgdVec3 v ) ; + + int intersects ( const sgdSphere *s ) const + { + return s -> intersects ( this ) ; + } + + int intersects ( const sgdBox *b ) const + { + return min[0] <= b->getMax()[0] && max[0] >= b->getMin()[0] && + min[1] <= b->getMax()[1] && max[1] >= b->getMin()[1] && + min[2] <= b->getMax()[2] && max[2] >= b->getMin()[2] ; + } + + int intersects ( const sgdVec4 plane ) const ; +} ; + + +class sgdFrustum +{ + /* Is the projection orthographic (or perspective)? */ + int ortho ; + + /* The parameters for glFrustum/glOrtho */ + + SGDfloat left, right, bot, top, nnear, ffar ; + + /* The computed projection matrix for this frustum */ + + sgdMat4 mat ; + + /* The A,B,C,D terms of the plane equations of the clip planes */ + /* A point (x,y,z) is inside the frustum iff Ax + By + Cz + D >= 0 for all planes */ + + sgdVec4 plane [ 6 ] ; + + /* These two are only valid for simple frusta */ + + SGDfloat hfov ; /* Horizontal Field of View -or- Orthographic Width */ + SGDfloat vfov ; /* Vertical Field of View -or- Orthographic Height */ + + void update (void) ; + int getOutcode ( const sgdVec4 src ) const ; + +public: + + sgdFrustum (void) + { + ortho = FALSE ; + nnear = SGD_ONE ; + ffar = 1000000.0f ; + hfov = SGD_45 ; + vfov = SGD_45 ; + update () ; + } + + void setFrustum ( const SGDfloat l, const SGDfloat r, + const SGDfloat b, const SGDfloat t, + const SGDfloat n, const SGDfloat f ) + { + ortho = FALSE ; + left = l ; + right = r ; + bot = b ; + top = t ; + nnear = n ; + ffar = f ; + hfov = vfov = SGD_ZERO ; + update () ; + } + + void setOrtho ( const SGDfloat l, const SGDfloat r, + const SGDfloat b, const SGDfloat t, + const SGDfloat n, const SGDfloat f ) + { + ortho = TRUE ; + left = l ; + right = r ; + bot = b ; + top = t ; + nnear = n ; + ffar = f ; + hfov = vfov = SGD_ZERO ; + update () ; + } + + void getMat4 ( sgdMat4 dst ) { sgdCopyMat4 ( dst, mat ) ; } + + SGDfloat getLeft (void) const { return left ; } + SGDfloat getRight(void) const { return right ; } + SGDfloat getBot (void) const { return bot ; } + SGDfloat getTop (void) const { return top ; } + SGDfloat getNear (void) const { return nnear ; } + SGDfloat getFar (void) const { return ffar ; } + + const SGDfloat *getPlane ( int i ) const { return plane [ i ] ; } + + SGDfloat getHFOV (void) const { return hfov ; } + SGDfloat getVFOV (void) const { return vfov ; } + + void getFOV ( SGDfloat *h, SGDfloat *v ) const + { + if ( h != (SGDfloat *) 0 ) *h = hfov ; + if ( v != (SGDfloat *) 0 ) *v = vfov ; + } + + void setFOV ( const SGDfloat h, const SGDfloat v ) + { + ortho = FALSE ; + hfov = ( h <= 0 ) ? ( v * SGD_FOUR / SGD_THREE ) : h ; + vfov = ( v <= 0 ) ? ( h * SGD_THREE / SGD_FOUR ) : v ; + update () ; + } + + void getOrtho ( SGDfloat *w, SGDfloat *h ) const + { + if ( w != (SGDfloat *) 0 ) *w = right - left ; + if ( h != (SGDfloat *) 0 ) *h = top - bot ; + } + + void setOrtho ( const SGDfloat w, const SGDfloat h ) + { + ortho = TRUE ; + hfov = ( w <= 0 ) ? ( h * SGD_FOUR / SGD_THREE ) : w ; + vfov = ( h <= 0 ) ? ( w * SGD_FOUR / SGD_THREE ) : h ; + update () ; + } + + void getNearFar ( SGDfloat *n, SGDfloat *f ) const + { + if ( n != (SGDfloat *) 0 ) *n = nnear ; + if ( f != (SGDfloat *) 0 ) *f = ffar ; + } + + void setNearFar ( const SGDfloat n, const SGDfloat f ) + { + nnear = n ; + ffar = f ; + update () ; + } + + int isOrtho (void) const { return ortho ; } + + int contains ( const sgdVec3 p ) const ; + int contains ( const sgdSphere *s ) const ; + int contains ( const sgdBox *b ) const ; +} ; + + +/* + Quaternion routines are Copyright (C) 1999 + Kevin B. Thompson + Modified by Sylvan W. Clebsch + Largely rewritten by "Negative0" +*/ + +/* + Quaternion structure w = real, (x, y, z) = vector + CHANGED sqQuat to float array so that syntax matches + vector and matrix routines +*/ + + +inline void sgdMakeIdentQuat ( sgdQuat dst ) +{ + sgdSetVec4 ( dst, SGD_ZERO, SGD_ZERO, SGD_ZERO, SGD_ONE ) ; +} + + +inline void sgdSetQuat ( sgdQuat dst, + const SGDfloat w, const SGDfloat x, + const SGDfloat y, const SGDfloat z ) +{ + sgdSetVec4 ( dst, x, y, z, w ) ; +} + +inline void sgdCopyQuat ( sgdQuat dst, const sgdQuat src ) +{ + sgdCopyVec4 ( dst, src ) ; +} + + +/* Construct a unit quaternion (length==1) */ + +inline void sgdNormaliseQuat ( sgdQuat dst, const sgdQuat src ) +{ + SGDfloat d = sgdScalarProductVec4 ( src, src ) ; + + d = (d > SGD_ZERO) ? (SGD_ONE / sgdSqrt ( d )) : SGD_ONE ; + + sgdScaleVec4 ( dst, src, d ) ; +} + + + +inline void sgdNormaliseQuat ( sgdQuat dst ) { sgdNormaliseQuat ( dst, dst ) ; } + + +inline void sgdInvertQuat ( sgdQuat dst, const sgdQuat src ) +{ + SGDfloat d = sgdScalarProductVec4 ( src, src ) ; + + d = ( d == SGD_ZERO ) ? SGD_ONE : ( SGD_ONE / d ) ; + + dst[SG_W] = src[SG_W] * d ; + dst[SG_X] = -src[SG_X] * d ; + dst[SG_Y] = -src[SG_Y] * d ; + dst[SG_Z] = -src[SG_Z] * d ; +} + +inline void sgdInvertQuat ( sgdQuat dst ) { sgdInvertQuat ( dst, dst ) ; } + + +/* Make an angle and axis of rotation from a Quaternion. */ + +void sgdQuatToAngleAxis ( SGDfloat *angle, sgdVec3 axis, const sgdQuat src ) ; +void sgdQuatToAngleAxis ( SGDfloat *angle, + SGDfloat *x, SGDfloat *y, SGDfloat *z, + const sgdQuat src ) ; + +/* Make a quaternion from a given angle and axis of rotation */ + +void sgdAngleAxisToQuat ( sgdQuat dst, + const SGDfloat angle, const sgdVec3 axis ) ; +void sgdAngleAxisToQuat ( sgdQuat dst, + const SGDfloat angle, + const SGDfloat x, const SGDfloat y, const SGDfloat z ); + +/* Convert a matrix to/from a quat */ + +void sgdMatrixToQuat ( sgdQuat quat, const sgdMat4 m ) ; +void sgdQuatToMatrix ( sgdMat4 m, const sgdQuat quat ) ; + +/* Convert a set of eulers to/from a quat */ + +void sgdQuatToEuler( sgdVec3 hpr, const sgdQuat quat ) ; +void sgdEulerToQuat( sgdQuat quat, const sgdVec3 hpr ) ; + +inline void sgdEulerToQuat( sgdQuat dst, + SGDfloat h, SGDfloat p, SGDfloat r ) +{ + sgdVec3 hpr ; + + sgdSetVec3 ( hpr, h, p, r ) ; + + sgdEulerToQuat( dst, hpr ) ; +} + +inline void sgdHPRToQuat ( sgdQuat dst, SGDfloat h, SGDfloat p, SGDfloat r ) +{ + sgdVec3 hpr; + + hpr[0] = h * SGD_DEGREES_TO_RADIANS ; + hpr[1] = p * SGD_DEGREES_TO_RADIANS ; + hpr[2] = r * SGD_DEGREES_TO_RADIANS ; + + sgdEulerToQuat( dst, hpr ) ; +} + +inline void sgdHPRToQuat ( sgdQuat dst, const sgdVec3 hpr ) +{ + sgdVec3 tmp ; + + sgdScaleVec3 ( tmp, hpr, SGD_DEGREES_TO_RADIANS ) ; + + sgdEulerToQuat ( dst, tmp ) ; +} + +/* Multiply quaternions together (concatenate rotations) */ + +void sgdMultQuat ( sgdQuat dst, const sgdQuat a, const sgdQuat b ) ; + +inline void sgdPostMultQuat ( sgdQuat dst, const sgdQuat q ) +{ + sgdQuat r ; + + sgdCopyQuat ( r, dst ) ; + sgdMultQuat ( dst, r, q ) ; +} + +inline void sgdPreMultQuat ( sgdQuat dst, const sgdQuat q ) +{ + sgdQuat r ; + + sgdCopyQuat ( r, dst ) ; + sgdMultQuat ( dst, q, r ) ; +} + + +/* Rotate a quaternion by a given angle and axis (convenience function) */ + + +inline void sgdRotQuat ( sgdQuat dst, const SGDfloat angle, const sgdVec3 axis ) +{ + sgdQuat q ; + + sgdAngleAxisToQuat ( q, angle, axis ) ; + sgdPostMultQuat ( dst, q ) ; + sgdNormaliseQuat ( dst ) ; +} + + +inline void sgdRotQuat ( sgdQuat dst, + const SGDfloat angle, + const SGDfloat x, const SGDfloat y, const SGDfloat z ) +{ + sgdVec3 axis ; + + sgdSetVec3 ( axis, x, y, z ) ; + sgdRotQuat ( dst, angle, axis ) ; +} + +/* SWC - Interpolate between to quaternions */ + +extern void sgdSlerpQuat ( sgdQuat dst, + const sgdQuat from, const sgdQuat to, + const SGDfloat t ) ; + + +/* Conversions between sg and sgd types. */ + +inline void sgSetVec2 ( sgVec2 dst, sgdVec2 src ) +{ + dst [ 0 ] = (SGfloat) src [ 0 ] ; + dst [ 1 ] = (SGfloat) src [ 1 ] ; +} + +inline void sgSetVec3 ( sgVec3 dst, sgdVec3 src ) +{ + dst [ 0 ] = (SGfloat) src [ 0 ] ; + dst [ 1 ] = (SGfloat) src [ 1 ] ; + dst [ 2 ] = (SGfloat) src [ 2 ] ; +} + +inline void sgSetVec4 ( sgVec4 dst, sgdVec4 src ) +{ + dst [ 0 ] = (SGfloat) src [ 0 ] ; + dst [ 1 ] = (SGfloat) src [ 1 ] ; + dst [ 2 ] = (SGfloat) src [ 2 ] ; + dst [ 3 ] = (SGfloat) src [ 3 ] ; +} + +inline void sgdSetVec2 ( sgdVec2 dst, sgVec2 src ) +{ + dst [ 0 ] = (SGDfloat) src [ 0 ] ; + dst [ 1 ] = (SGDfloat) src [ 1 ] ; +} + +inline void sgdSetVec3 ( sgdVec3 dst, sgVec3 src ) +{ + dst [ 0 ] = (SGDfloat) src [ 0 ] ; + dst [ 1 ] = (SGDfloat) src [ 1 ] ; + dst [ 2 ] = (SGDfloat) src [ 2 ] ; +} + +inline void sgdSetVec4 ( sgdVec4 dst, sgVec4 src ) +{ + dst [ 0 ] = (SGDfloat) src [ 0 ] ; + dst [ 1 ] = (SGDfloat) src [ 1 ] ; + dst [ 2 ] = (SGDfloat) src [ 2 ] ; + dst [ 3 ] = (SGDfloat) src [ 3 ] ; +} + + +inline void sgSetMat4 ( sgMat4 dst, sgdMat4 src ) +{ + sgSetVec4 ( dst [ 0 ], src [ 0 ] ) ; + sgSetVec4 ( dst [ 1 ], src [ 1 ] ) ; + sgSetVec4 ( dst [ 2 ], src [ 2 ] ) ; + sgSetVec4 ( dst [ 3 ], src [ 3 ] ) ; +} + + +inline void sgdSetMat4 ( sgdMat4 dst, sgMat4 src ) +{ + sgdSetVec4 ( dst [ 0 ], src [ 0 ] ) ; + sgdSetVec4 ( dst [ 1 ], src [ 1 ] ) ; + sgdSetVec4 ( dst [ 2 ], src [ 2 ] ) ; + sgdSetVec4 ( dst [ 3 ], src [ 3 ] ) ; +} + + +inline void sgSetCoord ( sgCoord *dst, sgdCoord *src ) +{ + sgSetVec3 ( dst->xyz, src->xyz ) ; + sgSetVec3 ( dst->hpr, src->hpr ) ; +} + + +inline void sgdSetCoord ( sgdCoord *dst, sgCoord *src ) +{ + sgdSetVec3 ( dst->xyz, src->xyz ) ; + sgdSetVec3 ( dst->hpr, src->hpr ) ; +} + +inline void sgSetQuat ( sgQuat dst, sgdQuat src ) +{ + sgSetVec4 ( dst, src ) ; +} + + + +inline void sgdSetQuat ( sgdQuat dst, sgQuat src ) +{ + sgdSetVec4 ( dst, src ) ; +} + + +/* Function to rotate a vector through a given quaternion using the formula + * R = Q r Q-1 -- this gives the components of a ROTATED vector in a STATIONARY + * coordinate system. We assume that Q is a unit quaternion. + */ + +void sgRotateVecQuat ( sgVec3 vec, sgQuat q ) ; +void sgdRotateVecQuat ( sgdVec3 vec, sgdQuat q ) ; + +/* Function to rotate a vector through a given quaternion using the formula + * R = Q-1 r Q -- this gives the components of a STATIONARY vector in a ROTATED + * coordinate system. We assume that Q is a unit quaternion. + */ + +void sgRotateCoordQuat ( sgVec3 vec, sgQuat q ) ; +void sgdRotateCoordQuat ( sgdVec3 vec, sgdQuat q ) ; + +sgFloat sgDistSquaredToLineLineSegment ( const sgLineSegment3 seg, const sgLine3 line ) ; +sgdFloat sgdDistSquaredToLineLineSegment ( const sgdLineSegment3 seg, const sgdLine3 line ) ; + + + +/* + Intersection testing. +*/ + +int sgdIsectPlanePlane ( sgdVec3 point, sgdVec3 dir, + sgdVec4 plane1, sgdVec4 plane2 ) ; +int sgdIsectInfLinePlane ( sgdVec3 dst, + sgdVec3 l_org, sgdVec3 l_vec, + sgdVec4 plane ) ; +int sgdIsectInfLineInfLine ( sgdVec3 dst, + sgdVec3 l1_org, sgdVec3 l1_vec, + sgdVec3 l2_org, sgdVec3 l2_vec ) ; +SGDfloat sgdIsectLinesegPlane ( sgdVec3 dst, + sgdVec3 v1, sgdVec3 v2, + sgdVec4 plane ) ; +bool sgdPointInTriangle ( sgdVec3 point, sgdVec3 tri[3] ); + + +/* + TRIANGLE SOLVERS - These work for any triangle. + + SSS == Side-lengths for all three sides. + SAS == Side-lengths for two sides - plus the angle between them. + ASA == Two angles plus the length of the Side between them. + Area == The area of the triangle. +*/ + +SGfloat sgTriangleSolver_ASAtoArea ( SGfloat angA, SGfloat lenB, SGfloat angC ); +SGfloat sgTriangleSolver_SAStoArea ( SGfloat lenA, SGfloat angB, SGfloat lenC ); +SGfloat sgTriangleSolver_SSStoArea ( SGfloat lenA, SGfloat lenB, SGfloat lenC ); +SGfloat sgTriangleSolver_SAAtoArea ( SGfloat lenA, SGfloat angB, SGfloat angA ); +SGfloat sgTriangleSolver_ASStoArea ( SGfloat angB, SGfloat lenA, SGfloat lenB, + int angA_is_obtuse ); + +void sgTriangleSolver_SSStoAAA ( SGfloat lenA, SGfloat lenB, SGfloat lenC, + SGfloat *angA, SGfloat *angB, SGfloat *angC ) ; +void sgTriangleSolver_SAStoASA ( SGfloat lenA, SGfloat angB, SGfloat lenC, + SGfloat *angA, SGfloat *lenB, SGfloat *angC ) ; +void sgTriangleSolver_ASAtoSAS ( SGfloat angA, SGfloat lenB, SGfloat angC, + SGfloat *lenA, SGfloat *angB, SGfloat *lenC ) ; +void sgTriangleSolver_SAAtoASS ( SGfloat lenA, SGfloat angB, SGfloat angA, + SGfloat *angC, SGfloat *lenB, SGfloat *lenC ) ; +void sgTriangleSolver_ASStoSAA ( SGfloat angB, SGfloat lenA, SGfloat lenB, + int angA_is_obtuse, + SGfloat *lenC, SGfloat *angA, SGfloat *angC ) ; + + +SGDfloat sgdTriangleSolver_ASAtoArea ( SGDfloat angA, SGDfloat lenB, SGDfloat angC ); +SGDfloat sgdTriangleSolver_SAStoArea ( SGDfloat lenA, SGDfloat angB, SGDfloat lenC ); +SGDfloat sgdTriangleSolver_SSStoArea ( SGDfloat lenA, SGDfloat lenB, SGDfloat lenC ); +SGDfloat sgdTriangleSolver_SAAtoArea ( SGDfloat lenA, SGDfloat angB, SGDfloat angA ); +SGDfloat sgdTriangleSolver_ASStoArea ( SGDfloat angB, SGDfloat lenA, SGDfloat lenB, + int angA_is_obtuse ); + +void sgdTriangleSolver_SSStoAAA ( SGDfloat lenA, SGDfloat lenB, SGDfloat lenC, + SGDfloat *angA, SGDfloat *angB, SGDfloat *angC ) ; +void sgdTriangleSolver_SAStoASA ( SGDfloat lenA, SGDfloat angB, SGDfloat lenC, + SGDfloat *angA, SGDfloat *lenB, SGDfloat *angC ) ; +void sgdTriangleSolver_ASAtoSAS ( SGDfloat angA, SGDfloat lenB, SGDfloat angC, + SGDfloat *lenA, SGDfloat *angB, SGDfloat *lenC ) ; +void sgdTriangleSolver_SAAtoASS ( SGDfloat lenA, SGDfloat angB, SGDfloat angA, + SGDfloat *angC, SGDfloat *lenB, SGDfloat *lenC ) ; +void sgdTriangleSolver_ASStoSAA ( SGDfloat angB, SGDfloat lenA, SGDfloat lenB, + int angA_is_obtuse, + SGDfloat *lenC, SGDfloat *angA, SGDfloat *angC ) ; + +/* + SPRING-MASS-DAMPER (with simple Euler integrator) +*/ + + +extern sgVec3 _sgGravity ; + +inline void sgSetGravity ( float g ) { sgSetVec3 ( _sgGravity, 0.0f, 0.0f, -g ) ; } +inline void sgSetGravityVec3 ( sgVec3 g ) { sgCopyVec3 ( _sgGravity, g ) ; } +inline float *sgGetGravityVec3 () { return _sgGravity ; } +inline float sgGetGravity () { return - _sgGravity[2] ; } + + +class sgParticle +{ + float ooMass ; /* One-over-mass */ + sgVec3 pos ; + sgVec3 vel ; + sgVec3 force ; + +public: + + sgParticle ( float mass, sgVec3 _pos ) + { + setMass ( mass ) ; + sgCopyVec3 ( pos, _pos ) ; + sgZeroVec3 ( vel ) ; + sgZeroVec3 ( force ) ; + } + + sgParticle ( float mass, float x = 0.0f, float y = 0.0f, float z = 0.0f ) + { + setMass ( mass ) ; + sgSetVec3 ( pos, x, y, z ) ; + sgZeroVec3 ( vel ) ; + sgZeroVec3 ( force ) ; + } + + SGfloat *getPos () { return pos ; } + SGfloat *getVel () { return vel ; } + SGfloat *getForce () { return force ; } + + const SGfloat *getPos () const { return pos ; } + const SGfloat *getVel () const { return vel ; } + const SGfloat *getForce () const { return force ; } + + float getOneOverMass () { return ooMass ; } + float getMass () { return 1.0f / ooMass ; } + + void setPos ( sgVec3 p ) { sgCopyVec3 ( pos , p ) ; } + void setVel ( sgVec3 v ) { sgCopyVec3 ( vel , v ) ; } + void setForce ( sgVec3 f ) { sgCopyVec3 ( force, f ) ; } + + void setPos ( float x, float y, float z ) { sgSetVec3 ( pos ,x,y,z ) ; } + void setVel ( float x, float y, float z ) { sgSetVec3 ( vel ,x,y,z ) ; } + void setForce ( float x, float y, float z ) { sgSetVec3 ( force,x,y,z ) ; } + + void setOneOverMass ( float oom ) { ooMass = oom ; } + + void setMass ( float m ) + { + assert ( m > 0.0f ) ; + ooMass = 1.0f / m ; + } + + void zeroForce () { sgZeroVec3 ( force ) ; } + void addForce ( sgVec3 f ) { sgAddVec3 ( force, f ) ; } + void subForce ( sgVec3 f ) { sgSubVec3 ( force, f ) ; } + void gravityOnly () { sgScaleVec3 ( force, sgGetGravityVec3 (), ooMass ) ; } + + void bounce ( sgVec3 normal, float coefRestitution ) + { + sgVec3 vn, vt ; + sgScaleVec3 ( vn, normal, + sgScalarProductVec3 ( normal, vel ) ) ; + sgSubVec3 ( vt, vel, vn ) ; + sgAddScaledVec3 ( vel, vt, vn, -coefRestitution ) ; + } + + void update ( float dt ) + { + sgAddScaledVec3 ( vel, force, dt * ooMass ) ; + sgAddScaledVec3 ( pos, vel, dt ) ; + } +} ; + + +class sgSpringDamper +{ + sgParticle *p0 ; + sgParticle *p1 ; + + float restLength ; + float stiffness ; + float damping ; + +public: + + sgSpringDamper () + { + p0 = p1 = NULL ; + stiffness = 1.0f ; + damping = 1.0f ; + restLength = 1.0f ; + } + + sgSpringDamper ( sgParticle *_p0, sgParticle *_p1, + float _stiffness, float _damping, + float _restLength = -1.0f ) + { + p0 = _p0 ; + p1 = _p1 ; + stiffness = _stiffness ; + damping = _damping ; + + if ( _restLength < 0.0f ) + { + if ( p0 != NULL && p1 != NULL ) + restLength = sgDistanceVec3 ( p0->getPos(), p1->getPos() ) ; + else + restLength = _restLength ; + } + else + restLength = 1.0f ; + } + + float getRestLength () { return restLength ; } + float getStiffness () { return stiffness ; } + float getDamping () { return damping ; } + + sgParticle *getParticle ( int which ) { return ( which == 0 ) ? p0 : p1 ; } + + + void setParticles ( sgParticle *_p0, sgParticle *_p1 ) { p0 = _p0 ; p1 = _p1 ; } + void setParticle ( int which, sgParticle *p ) { if ( which == 0 ) p0 = p ; else p1 = p ; } + + void setRestLength () { restLength = sgDistanceVec3 ( p0->getPos(), p1->getPos() ) ; } + + void setRestLength ( float l ) { restLength = l ; } + void setStiffness ( float s ) { stiffness = s ; } + void setDamping ( float d ) { damping = d ; } + + void update () + { + sgVec3 dP ; sgSubVec3 ( dP, p0->getPos(), p1->getPos() ) ; + sgVec3 dV ; sgSubVec3 ( dV, p0->getVel(), p1->getVel() ) ; + + float L = sgLengthVec3 ( dP ) ; if ( L == 0.0f ) L = 0.0000001f ; + float H = ( L - restLength ) * stiffness ; + float D = sgScalarProductVec3 ( dV, dP ) * damping / L ; + + sgVec3 F ; sgScaleVec3 ( F, dP, - ( H + D ) / L ) ; + + p0 -> addForce ( F ) ; + p1 -> subForce ( F ) ; + } + +} ; + + +/* + It must be true that (x % NOISE_WRAP_INDEX) == (x & NOISE_MOD_MASK) + so NOISE_WRAP_INDEX must be a power of two, and NOISE_MOD_MASK must be + that power of 2 - 1. as indices are implemented, as unsigned chars, + NOISE_WRAP_INDEX shoud be less than or equal to 256. + There's no good reason to change it from 256, really. + + NOISE_LARGE_PWR2 is a large power of 2, we'll go for 4096, to add to + negative numbers in order to make them positive +*/ + +#define SG_PERLIN_NOISE_WRAP_INDEX 256 +#define SG_PERLIN_NOISE_MOD_MASK 255 +#define SG_PERLIN_NOISE_LARGE_PWR2 4096 + + + +class sgPerlinNoise_1D +{ +private: + + SGfloat gradTable [ SG_PERLIN_NOISE_WRAP_INDEX * 2 + 2 ] ; + +public: + + sgPerlinNoise_1D () ; + + void regenerate () ; + + SGfloat getNoise ( SGfloat x ) ; +} ; + + + +class sgPerlinNoise_2D +{ +private: + + sgVec2 gradTable [ SG_PERLIN_NOISE_WRAP_INDEX * 2 + 2 ] ; + +public: + + sgPerlinNoise_2D () ; + + void regenerate () ; + + SGfloat getNoise ( sgVec2 pos ) ; + SGfloat getNoise ( SGfloat x, SGfloat y ) + { + sgVec2 p ; + sgSetVec2 ( p, x, y ) ; + return getNoise ( p ) ; + } +} ; + + + +class sgPerlinNoise_3D +{ +private: + + sgVec3 gradTable [ SG_PERLIN_NOISE_WRAP_INDEX * 2 + 2 ] ; + +public: + + sgPerlinNoise_3D () ; + + void regenerate () ; + + SGfloat getNoise ( sgVec3 pos ) ; + SGfloat getNoise ( SGfloat x, SGfloat y, SGfloat z ) + { + sgVec3 p ; + sgSetVec3 ( p, x, y, z ) ; + return getNoise ( p ) ; + } +} ; + + + +#endif + diff --git a/include/plib/ul.h b/include/plib/ul.h new file mode 100644 index 0000000..f01ba01 --- /dev/null +++ b/include/plib/ul.h @@ -0,0 +1,851 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: ul.h 2131 2008-03-11 02:23:50Z sjbaker $ +*/ + +// +// UL - utility library +// +// Contains: +// - necessary system includes +// - basic types +// - error message routines +// - high performance clocks +// - ulList +// - ulLinkedList +// - more to come (endian support, version ID) +// + +#ifndef _INCLUDED_UL_H_ +#define _INCLUDED_UL_H_ + +#include +#include +#include +#include +#include +#include + +/**********************\ +* * +* Determine OS type * +* * +\**********************/ + +#if defined(__CYGWIN__) + +#define UL_WIN32 1 +#define UL_CYGWIN 1 /* Windoze AND Cygwin. */ + +#elif defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) + +#define UL_WIN32 1 +#define UL_MSVC 1 /* Windoze AND MSVC. */ + +#elif defined(__BEOS__) + +#define UL_BEOS 1 + +#elif defined( macintosh ) + +#define UL_MACINTOSH 1 + +#elif defined(__APPLE__) + +#define UL_MAC_OSX 1 + +#elif defined(__linux__) + +#define UL_LINUX 1 + +#elif defined(__sgi) + +#define UL_IRIX 1 + +#elif defined(_AIX) + +#define UL_AIX 1 + +#elif defined(SOLARIS) || defined(sun) + +#define UL_SOLARIS 1 + +#elif defined(hpux) + +#define UL_HPUX 1 + +#elif (defined(__unix__) || defined(unix)) && !defined(USG) + +#define UL_BSD 1 + +#endif + + +/* + Add specialised includes/defines... +*/ + +#ifdef UL_WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#define UL_WGL 1 +#endif + +#ifdef UL_CYGWIN +#include +#define UL_WGL 1 +#endif + +#ifdef UL_BEOS +#include +#define UL_GLX 1 +#endif + +#ifdef UL_MACINTOSH +#include +#include +#define UL_AGL 1 +#endif + +#ifdef UL_MAC_OSX +#include +#define UL_CGL 1 +#endif + +#if defined(UL_LINUX) || defined(UL_BSD) || defined(UL_IRIX) || defined(UL_SOLARIS) || defined(UL_AIX) +#include +#include +#include +#define UL_GLX 1 +#endif + +#if defined(UL_BSD) +#include +#define UL_GLX 1 +#endif + +#include +#include +#include +#include +#include + +/* PLIB version macros */ + +#define PLIB_MAJOR_VERSION 1 +#define PLIB_MINOR_VERSION 8 +#define PLIB_TINY_VERSION 5 + +#define PLIB_VERSION (PLIB_MAJOR_VERSION*100 \ + +PLIB_MINOR_VERSION*10 \ + +PLIB_TINY_VERSION) + +/* SGI machines seem to suffer from a lack of FLT_EPSILON so... */ + +#ifndef FLT_EPSILON +#define FLT_EPSILON 1.19209290e-07f +#endif + +#ifndef DBL_EPSILON +#define DBL_EPSILON 1.19209290e-07f +#endif + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +/* SUNWspro 4.2 and earlier need bool to be defined */ + +#if defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500 +typedef int bool ; +const int true = 1 ; +const int false = 0 ; +#endif + +/* Let's define our own "min" and "max" so that different operating systems + * don't complain + */ +#define ulMax(a,b) ((a)>(b)?(a):(b)) +#define ulMin(a,b) ((a)<(b)?(a):(b)) + + +/* + Basic Types +*/ + + +/* + High precision clocks. +*/ + +class ulClock +{ + double start ; + double now ; + double delta ; + double last_time ; + double max_delta ; + +#ifdef UL_WIN32 + static double res ; + static int perf_timer ; + void initPerformanceTimer () ; +#endif + + double getRawTime () const ; + +public: + + ulClock () { reset () ; } + + void reset () + { +#ifdef UL_WIN32 + initPerformanceTimer () ; +#endif + start = getRawTime () ; + now = 0.0 ; + max_delta = 0.2 ; + delta = 0.0000001 ; /* Faked so stoopid programs won't div0 */ + last_time = 0.0 ; + } + + void setMaxDelta ( double maxDelta ) { max_delta = maxDelta ; } + double getMaxDelta () const { return max_delta ; } + void update () ; + double getAbsTime () const { return now ; } + double getDeltaTime () const { return delta ; } + double getFrameRate () const { return 1.0 / delta ; } +} ; + + +inline void ulSleep ( int seconds ) +{ + if ( seconds >= 0 ) + { +#ifdef UL_WIN32 + Sleep ( 1000 * seconds ) ; +#else + sleep ( seconds ) ; +#endif + } +} + + +inline void ulMilliSecondSleep ( int milliseconds ) +{ + if ( milliseconds >= 0 ) + { +#ifdef UL_WIN32 + Sleep ( milliseconds ) ; +#else + usleep ( milliseconds * 1000 ) ; +#endif + } +} + + +/* + This is extern C to enable 'configure.in' to + find it with a C-coded probe. +*/ + +extern "C" void ulInit () ; + +/* + Error handler. +*/ + +enum ulSeverity +{ + UL_DEBUG, // Messages that can safely be ignored. + UL_WARNING, // Messages that are important. + UL_FATAL, // Errors that we cannot recover from. + UL_MAX_SEVERITY +} ; + + +typedef void (*ulErrorCallback) ( enum ulSeverity severity, char* msg ) ; + +void ulSetError ( enum ulSeverity severity, const char *fmt, ... ) ; +char* ulGetError ( void ) ; +void ulClearError ( void ) ; +ulErrorCallback ulGetErrorCallback ( void ) ; +void ulSetErrorCallback ( ulErrorCallback cb ) ; + +/* + Directory Reading +*/ + +#define UL_NAME_MAX 256 +typedef struct _ulDir ulDir ; +struct ulDirEnt +{ + char d_name [ UL_NAME_MAX+1 ]; + bool d_isdir ; +} ; + +int ulIsAbsolutePathName ( const char *pathname ) ; +char *ulGetCWD ( char *result, int maxlength ) ; + +ulDir* ulOpenDir ( const char* dirname ) ; +ulDirEnt* ulReadDir ( ulDir* dir ) ; +void ulCloseDir ( ulDir* dir ) ; + +// file handling + +char* ulMakePath( char* path, const char* dir, const char* fname ); + +bool ulFileExists ( const char *fileName ) ; + +void ulFindFile( char *filenameOutput, const char *path, + const char * tfnameInput, const char *sAPOM ) ; + + +/* + Endian handling +*/ + +static const int _ulEndianTest = 1; +#define ulIsLittleEndian (*((char *) &_ulEndianTest ) != 0) +#define ulIsBigEndian (*((char *) &_ulEndianTest ) == 0) + +inline void ulEndianSwap(unsigned int *x) +{ + *x = (( *x >> 24 ) & 0x000000FF ) | + (( *x >> 8 ) & 0x0000FF00 ) | + (( *x << 8 ) & 0x00FF0000 ) | + (( *x << 24 ) & 0xFF000000 ) ; +} + + +inline void ulEndianSwap(unsigned short *x) +{ + *x = (( *x >> 8 ) & 0x00FF ) | + (( *x << 8 ) & 0xFF00 ) ; +} + + +inline void ulEndianSwap(float *x) { ulEndianSwap((unsigned int *)x); } +inline void ulEndianSwap(int *x) { ulEndianSwap((unsigned int *)x); } +inline void ulEndianSwap(short *x) { ulEndianSwap((unsigned short *)x); } + + +inline unsigned short ulEndianLittle16(unsigned short x) { + if (ulIsLittleEndian) { + return x; + } else { + ulEndianSwap(&x); + return x; + } +} + +inline unsigned int ulEndianLittle32(unsigned int x) { + if (ulIsLittleEndian) { + return x; + } else { + ulEndianSwap(&x); + return x; + } +} + +inline float ulEndianLittleFloat(float x) { + if (ulIsLittleEndian) { + return x; + } else { + ulEndianSwap(&x); + return x; + } +} + +inline void ulEndianLittleArray16(unsigned short *x, int length) { + if (ulIsLittleEndian) { + return; + } else { + for (int i = 0; i < length; i++) { + ulEndianSwap(x++); + } + } +} + +inline void ulEndianLittleArray32(unsigned int *x, int length) { + if (ulIsLittleEndian) { + return; + } else { + for (int i = 0; i < length; i++) { + ulEndianSwap(x++); + } + } +} + +inline void ulEndianLittleArrayFloat(float *x, int length) { + if (ulIsLittleEndian) { + return; + } else { + for (int i = 0; i < length; i++) { + ulEndianSwap(x++); + } + } +} + +inline void ulEndianBigArray16(unsigned short *x, int length) { + if (ulIsBigEndian) { + return; + } else { + for (int i = 0; i < length; i++) { + ulEndianSwap(x++); + } + } +} + +inline void ulEndianBigArray32(unsigned int *x, int length) { + if (ulIsBigEndian) { + return; + } else { + for (int i = 0; i < length; i++) { + ulEndianSwap(x++); + } + } +} + +inline void ulEndianBigArrayFloat(float *x, int length) { + if (ulIsBigEndian) { + return; + } else { + for (int i = 0; i < length; i++) { + ulEndianSwap(x++); + } + } +} + +inline unsigned short ulEndianBig16(unsigned short x) { + if (ulIsBigEndian) { + return x; + } else { + ulEndianSwap(&x); + return x; + } +} + +inline unsigned int ulEndianBig32(unsigned int x) { + if (ulIsBigEndian) { + return x; + } else { + ulEndianSwap(&x); + return x; + } +} + +inline float ulEndianBigFloat(float x) { + if (ulIsBigEndian) { + return x; + } else { + ulEndianSwap(&x); + return x; + } +} + +inline unsigned short ulEndianReadLittle16(FILE *f) { + unsigned short x; + fread(&x, 2, 1, f); + return ulEndianLittle16(x); +} + +inline unsigned int ulEndianReadLittle32(FILE *f) { + unsigned int x; + fread(&x, 4, 1, f); + return ulEndianLittle32(x); +} + +inline float ulEndianReadLittleFloat(FILE *f) { + float x; + fread(&x, 4, 1, f); + return ulEndianLittleFloat(x); +} + +inline unsigned short ulEndianReadBig16(FILE *f) { + unsigned short x; + fread(&x, 2, 1, f); + return ulEndianBig16(x); +} + +inline unsigned int ulEndianReadBig32(FILE *f) { + unsigned int x; + fread(&x, 4, 1, f); + return ulEndianBig32(x); +} + +inline float ulEndianReadBigFloat(FILE *f) { + float x; + fread(&x, 4, 1, f); + return ulEndianBigFloat(x); +} + +inline size_t ulEndianWriteLittle16(FILE *f, unsigned short x) { + x = ulEndianLittle16(x); + return fwrite( &x, 2, 1, f ); +} + +inline size_t ulEndianWriteLittle32(FILE *f, unsigned int x) { + x = ulEndianLittle32(x); + return fwrite( &x, 4, 1, f ); +} + +inline size_t ulEndianWriteLittleFloat(FILE *f, float x) { + x = ulEndianLittleFloat(x); + return fwrite( &x, 4, 1, f ); +} + +inline size_t ulEndianWriteBig16(FILE *f, unsigned short x) { + x = ulEndianBig16(x); + return fwrite( &x, 2, 1, f ); +} + +inline size_t ulEndianWriteBig32(FILE *f, unsigned int x) { + x = ulEndianBig32(x); + return fwrite( &x, 4, 1, f ); +} + +inline size_t ulEndianWriteBigFloat(FILE *f, float x) { + x = ulEndianBigFloat(x); + return fwrite( &x, 4, 1, f ); +} + + +/* + Windoze/BEOS code based on contribution from Sean L. Palmer +*/ + + +#ifdef UL_WIN32 + +class ulDynamicLibrary +{ + HMODULE handle ; + +public: + + ulDynamicLibrary ( const char *libname ) + { + char dllname[1024]; + strcpy ( dllname, libname ) ; + strcat ( dllname, ".dll" ) ; + handle = (HMODULE) LoadLibrary ( dllname ) ; + } + + void *getFuncAddress ( const char *funcname ) + { + return (void *) GetProcAddress ( handle, funcname ) ; //lint !e611 + } + + ~ulDynamicLibrary () + { + if ( handle != NULL ) + FreeLibrary ( handle ) ; + } +} ; + +#elif defined (UL_MACINTOSH) + +class ulDynamicLibrary +{ + CFragConnectionID connection; + OSStatus error; + +public: + + ulDynamicLibrary ( const char *libname ) + { + Str63 pstr; + int sz; + + sz = strlen (libname); + + if (sz < 64) { + + pstr[0] = sz; + memcpy (pstr+1, libname, sz); + + error = GetSharedLibrary (pstr, kPowerPCCFragArch, kReferenceCFrag, + &connection, NULL, NULL); + } + else + error = 1; + } + + ~ulDynamicLibrary () + { + if ( ! error ) + CloseConnection (&connection); + } + + void* getFuncAddress ( const char *funcname ) + { + if ( ! error ) { + + char* addr; + Str255 sym; + int sz; + + sz = strlen (funcname); + if (sz < 256) { + + sym[0] = sz; + memcpy (sym+1, funcname, sz); + + error = FindSymbol (connection, sym, &addr, 0); + if ( ! error ) + return addr; + } + } + + return NULL; + } +}; + +#elif defined (UL_MAC_OSX) + + +class ulDynamicLibrary +{ + + public: + + ulDynamicLibrary ( const char *libname ) + { + } + + ~ulDynamicLibrary () + { + } + + void* getFuncAddress ( const char *funcname ) + { + ulSetError ( UL_WARNING, "ulDynamicLibrary unsuppored on Mac OS X" ); + return NULL; + } +}; + +#elif defined (__BEOS__) + +class ulDynamicLibrary +{ + image_id *handle ; + +public: + + ulDynamicLibrary ( const char *libname ) + { + char addonname[1024] ; + strcpy ( addonname, libname ) ; + strcat ( addonname, ".so" ) ; + handle = new image_id ; + + *handle = load_add_on ( addonname ) ; + + if ( *handle == B_ERROR ) + { + delete handle ; + handle = NULL ; + } + } + + void *getFuncAddress ( const char *funcname ) + { + void *sym = NULL ; + + if ( handle && + get_image_symbol ( handle, "funcname", + B_SYMBOL_TYPE_TEXT, &sym ) == B_NO_ERROR ) + return sym ; + + return NULL ; + } + + ~ulDynamicLibrary () + { + if ( handle != NULL ) + unload_add_on ( handle ) ; + + delete handle ; + } +} ; + +# else + +/* + Linux/UNIX +*/ + +class ulDynamicLibrary +{ + void *handle ; + +public: + + ulDynamicLibrary ( const char *libname ) + { + char dsoname [ 1024 ] ; + strcpy ( dsoname, libname ) ; + strcat ( dsoname, ".so" ) ; + handle = (void *) dlopen ( dsoname, RTLD_NOW | RTLD_GLOBAL ) ; + + if ( handle == NULL ) + ulSetError ( UL_WARNING, "ulDynamicLibrary: %s\n", dlerror() ) ; + } + + void *getFuncAddress ( const char *funcname ) + { + return (handle==NULL) ? NULL : dlsym ( handle, funcname ) ; + } + + ~ulDynamicLibrary () + { + if ( handle != NULL ) + dlclose ( handle ) ; + } +} ; + +#endif + + +class ulList +{ +protected: + unsigned int total ; /* The total number of entities in the list */ + unsigned int limit ; /* The current limit on number of entities */ + unsigned int next ; /* The next entity when we are doing getNext ops */ + + void **entity_list ; /* The list. */ + + void sizeChk (void) ; + +public: + + ulList ( int init_max = 1 ) ; + virtual ~ulList (void) ; + + void *getEntity ( unsigned int n ) + { + next = n + 1 ; + return ( n >= total ) ? (void *) NULL : entity_list [ n ] ; + } + + virtual void addEntity ( void *entity ) ; + virtual void addEntityBefore ( int n, void *entity ) ; + virtual void removeEntity ( unsigned int n ) ; + + void removeAllEntities () ; + + void removeEntity ( void *entity ) + { + removeEntity ( searchForEntity ( entity ) ) ; + } + + virtual void replaceEntity ( unsigned int n, void *new_entity ) ; + + void replaceEntity ( void *old_entity, void *new_entity ) + { + replaceEntity ( searchForEntity ( old_entity ), new_entity ) ; + } + + void *getNextEntity (void) { return getEntity ( next ) ; } + + int getNumEntities (void) const { return total ; } + int searchForEntity ( void *entity ) const ; +} ; + + +typedef bool (*ulIterateFunc)( const void *data, void *user_data ) ; +typedef int (*ulCompareFunc)( const void *data1, const void *data2 ) ; + +/* + Linked list. +*/ + +class ulListNode ; + +class ulLinkedList +{ +protected: + + ulListNode *head ; + ulListNode *tail ; + + int nnodes ; + bool sorted ; + + void unlinkNode ( ulListNode *prev, ulListNode *node ) ; + + bool isValidPosition ( int pos ) const + { + if ( ( pos < 0 ) || ( pos >= nnodes ) ) + { + ulSetError ( UL_WARNING, "ulLinkedList: Invalid 'pos' %u", pos ) ; + return false ; + } + return true ; + } + +public: + + ulLinkedList () + { + head = tail = NULL ; + nnodes = 0 ; + sorted = true ; + } + + ~ulLinkedList () { empty () ; } + + int getNumNodes ( void ) const { return nnodes ; } + bool isSorted ( void ) const { return sorted ; } + + int getNodePosition ( void *data ) const ; + + void insertNode ( void *data, int pos ) ; + void prependNode ( void *data ) { insertNode ( data, 0 ) ; } + void appendNode ( void *data ) ; + + int insertSorted ( void *data, ulCompareFunc comparefn ) ; + + void removeNode ( void *data ) ; + void * removeNode ( int pos ) ; + + void * getNodeData ( int pos ) const ; + + void * forEach ( ulIterateFunc fn, void *user_data = NULL ) const ; + + void empty ( ulIterateFunc destroyfn = NULL, void *user_data = NULL ) ; +} ; + + +extern char *ulStrDup ( const char *s ) ; +extern int ulStrNEqual ( const char *s1, const char *s2, int len ); +extern int ulStrEqual ( const char *s1, const char *s2 ); + +//lint -restore + +#endif + diff --git a/include/plib/ulRTTI.h b/include/plib/ulRTTI.h new file mode 100644 index 0000000..e8c5216 --- /dev/null +++ b/include/plib/ulRTTI.h @@ -0,0 +1,420 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 1998,2002 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net */ + + +/* + Originally written by: Alexandru C. Telea +*/ + +/* + This file provides support for RTTI and generalized (virtual-base to derived + and separate hierarchy branches) casting. There is also support for RT obj + creation from type names. + + In order to enable these features for a class, two things should be done: + + 1) insert the text UL_TYPE_DATA (without ';') in the class-decl. + 2) in the .C file where the class's implementation resides, insert the + following (without';'): + + UL_RTTI_DEF(classname) + if the class has no bases with RTTI + + UL_RTTI_DEFn(classname,b1,...bn) + if the class has bases b1,...bn with RTTI + + Use UL_RTTI_DEF_INST instead of UL_RTTI_DEF if you want to enable RT + obj creation for classname. You should provide then a public default + ctor. + + RTTI is used via a class called ulRTTItypeid. A typeid describes a type of a + class. [..] They should provide all necessary support for any kind of + RTTI/casting [..]. + + [..] + + REMARK: There are two classes related to RTTI: ulRTTItypeid and + ======= ulRTTITypeinfo. A ulRTTItypeid is, as it says, an 'id for a + type'. It actually wraps a ulRTTITypeinfo*, where a + ulRTTITypeinfo contains the actual encoding of a class type. + You can freely create/copy/destroy/manipulate ulRTTItypeid's, + but you should NEVER deal directly with ulRTTITypeinfo. A + ulRTTITypeinfo should actually be created ONLY by the + UL_TYPE_DATA macros, as part of a class definition, since the + ulRTTITypeinfo encodes a type info for an EXISTING class [..]. + All type-related stuff should be therefore handled via + ulRTTItypeid's. +*/ + +#ifndef _UL_RTTI_H_ +#define _UL_RTTI_H_ + +#include +#include "ul.h" + + +class ulRTTITypeinfo +/* Implementation of type-related info */ +{ +private: + + char *n ; /* type name */ + + /* + base types (NULL-ended array of ulRTTITypeinfo's for this's direct bases) + */ + const ulRTTITypeinfo** b ; + + int ns ; /* #subtypes of this type */ + const ulRTTITypeinfo **subtypes ; /* types derived from this type */ + + /* convenience type info for a 'null' type */ + static const ulRTTITypeinfo null_type ; + + void* (*new_obj)() ; /* func to create a new obj of this type */ + void* (*cast)(int,void*) ; /* + func to cast an obj of this type to ith + baseclass of it or to itself + */ + + /* adds a subtype to this's subtypes[] */ + void add_subtype ( const ulRTTITypeinfo * ) ; + + /* dels a subtype from this's subtypes[] */ + void del_subtype ( const ulRTTITypeinfo* ) ; + + friend class ulRTTItypeid ; /* for null_type */ + +public: + + ulRTTITypeinfo ( const char* name, const ulRTTITypeinfo* bb[], + void* (*)(int,void*),void* (*)() ) ; + ~ulRTTITypeinfo () ; + + /* Returns name of this ulRTTITypeinfo */ + const char* getname () const { return n ; } + + /* Compares 2 ulRTTITypeinfo objs */ + bool same ( const ulRTTITypeinfo *p ) const + { + /* + First, try to see if it's the same 'physical' ulRTTITypeinfo (which + should be the case, since we create them per-class and not per-obj). + */ + return ( this == p ) || !strcmp ( n, p->n ) ; + } + + /* true if the arg can be cast to this, else false */ + bool can_cast ( const ulRTTITypeinfo *p ) const + { + return same ( p ) || p->has_base ( this ) ; + } + + /* true if this has the arg as some base, else false */ + bool has_base ( const ulRTTITypeinfo *p ) const + { + for ( int i = 0 ; b[i] != NULL ; i++ ) /* for all bases of this... */ + /* match found, return 1 or no match, search deeper */ + if ( p->same ( b[i] ) || b[i]->has_base ( p ) ) return true ; + return false ; /* no match at all, return false */ + } + + /* get i-th subclass of this, if any, else NULL */ + const ulRTTITypeinfo * subclass ( int i = 0 ) const + { + return ( i >= 0 && i < ns ) ? subtypes[i] : NULL ; + } + + int num_subclasses () const { return ns ; } /* get # subclasses of this */ + + /* + search for a subclass named char*, create obj of it and return it cast to + the ulRTTITypeinfo* type, which is either this or a direct base of this. + */ + void * create ( const ulRTTITypeinfo *, const char * ) const ; + + /* Returns true if this type has a default ctor, else false */ + bool can_create () const { return new_obj != NULL ; } +} ; + + +class ulRTTItypeid +/* Main class for RTTI interface */ +{ +protected: + + /* ulRTTItypeid implementation (the only data-member) */ + const ulRTTITypeinfo* id ; + +public: + + /* Not for application use ! */ + const ulRTTITypeinfo* get_info () const { return id ; } + + ulRTTItypeid ( const ulRTTITypeinfo* p ) : id ( p ) { } + ulRTTItypeid () : id ( &ulRTTITypeinfo::null_type ) { } + + /* Compares 2 ulRTTItypeid objs */ + bool isSame ( ulRTTItypeid i ) const { return id->same ( i.id ) ; } + + /* true if the arg can be cast to this, else false */ + bool canCast ( ulRTTItypeid i ) const { return id->can_cast ( i.id ) ; } + + const char * getName () const { return id->getname () ; } + + /* Return # subclasses of this */ + int getNumSubclasses () const { return id->num_subclasses () ; } + + /* Return ith subclass of this */ + ulRTTItypeid getSubclass ( int i ) const { return id->subclass ( i ) ; } + + /* Return # baseclasses of this */ + int getNumBaseclasses () const + { + int i ; for ( i = 0 ; id->b[i] != NULL ; i++ ) ; + return i ; + } + + /* Return ith baseclass of this */ + ulRTTItypeid getBaseclass ( int i ) const { return id->b[i] ; } + + /* + Tries to create an instance of a subclass of this having of type given + by the ulRTTItypeid arg. If ok, it returns it casted to the class-type of + this and then to void* + */ + void * create ( ulRTTItypeid t ) const + { + return id->create ( id, t.getName () ) ; + } + + /* Returns true if this type is instantiable, else false */ + bool canCreate () const { return id->can_create () ; } +} ; + + +class ulRTTIdyntypeid : public ulRTTItypeid +/* + Class for dynamic type creation from user strings. Useful for creating + typeids at RT for comparison purposes. +*/ +{ +private: + + static const ulRTTITypeinfo *a[] ; + +public: + + ulRTTIdyntypeid ( const char *c ) : + /* create a dummy ulRTTITypeinfo */ + ulRTTItypeid ( new ulRTTITypeinfo ( c, a, NULL, NULL ) ) { } + + ~ulRTTIdyntypeid () { delete id ; /* delete the dummy ulRTTITypeinfo */ } +} ; + + + +/* + Macros +*/ + +/* + 'ulRTTItypeid' + UL_STATIC_TYPE_INFO(T) T=RTTI-class name. + Returns a ulRTTItypeid with T's type. If T + hasn't RTTI, a compile-time error occurs. +*/ + +#define UL_STATIC_TYPE_INFO(T) T::RTTI_sinfo() + + +/* + 'T*' + UL_PTR_CAST(T,p) T=RTTI-class, p=RTTI-class ptr. + Returns p cast to the type T as a T*, if cast is + possible, else returns NULL. If *p or T have no RTTI, + a compile-time error occurs. Note that p can point to + virtual base classes. Casting between separat branches + of a class hierarchy is also supported, as long as all + classes have RTTI. Therefore UL_PTR_CAST is a fully + general and safe operator. If p==NULL, the operator + returns NULL. +*/ + +#define UL_PTR_CAST(T,p) ((p != NULL)? (T*)((p)->RTTI_cast(UL_STATIC_TYPE_INFO(T))) : NULL) + + +/* 'T*' + UL_TYPE_NEW(T,t) T=RTTI-class, t=ulRTTItypeid + Returns a new object of type t cast to the type T as + a T*. t must represent a type identical to or derived + from T. If t is not a type derived from T or not an + instantiable type having a default constructor, NULL is + returned. */ + +#define UL_TYPE_NEW(T,t) ((T*)t.create(T)) + + + +/* + Definition of TYPE_DATA for a RTTI-class: introduces one static + ulRTTITypeinfo data-member and a couple of virtuals. +*/ + +#define UL_TYPE_DATA \ + protected: \ + static const ulRTTITypeinfo RTTI_obj; \ + static void* RTTI_scast(int,void*); \ + static void* RTTI_new(); \ + virtual ulRTTItypeid RTTI_vinfo() const { return &RTTI_obj; }\ + public: \ + static ulRTTItypeid RTTI_sinfo() { return &RTTI_obj; }\ + virtual void* RTTI_cast(ulRTTItypeid); + + + +/* + Definition of auxiliary data-structs supporting RTTI for a class: defines + the static ulRTTITypeinfo object of that class and its associated virtuals. +*/ + +/* Auxiliary definition of the construction method: */ +#define UL_RTTI_NEW(cls) void* cls::RTTI_new() { return new cls; } \ + const ulRTTITypeinfo cls::RTTI_obj(#cls,RTTI_base_ ## cls,cls::RTTI_scast,cls::RTTI_new); + +#define UL_RTTI_NO_NEW(cls) const ulRTTITypeinfo cls::RTTI_obj(#cls,RTTI_base_ ## cls,cls::RTTI_scast,NULL); + + + +/* + Top-level macros: +*/ + +#define UL_RTTI_DEF_BASE(cls) \ + static const ulRTTITypeinfo* RTTI_base_ ## cls [] = { NULL }; \ + void* cls::RTTI_cast(ulRTTItypeid t) \ + { \ + if (t.isSame(&RTTI_obj)) return this; \ + return NULL; \ + } \ + void* cls::RTTI_scast(int i,void* p) \ + { cls* ptr = (cls*)p; return ptr; } + + +#define UL_RTTI_DEF1_BASE(cls,b1) \ + static const ulRTTITypeinfo* RTTI_base_ ## cls [] = \ + { UL_STATIC_TYPE_INFO(b1).get_info(), NULL }; \ + void* cls::RTTI_cast(ulRTTItypeid t) \ + { \ + if (t.isSame(&RTTI_obj)) return this; \ + void* ptr; \ + if ((ptr=b1::RTTI_cast(t))) return ptr; \ + return NULL; \ + } \ + void* cls::RTTI_scast(int i,void* p) \ + { cls* ptr = (cls*)p; \ + switch(i) \ + { case 0: return (b1*)ptr; } \ + return ptr; \ + } + + +#define UL_RTTI_DEF2_BASE(cls,b1,b2) \ + static const ulRTTITypeinfo* RTTI_base_ ## cls [] = \ + { UL_STATIC_TYPE_INFO(b1).get_info(), \ + UL_STATIC_TYPE_INFO(b2).get_info(), NULL }; \ + void* cls::RTTI_cast(ulRTTItypeid t) \ + { \ + if (t.isSame(&RTTI_obj)) return this; \ + void* ptr; \ + if ((ptr=b1::RTTI_cast(t))) return ptr; \ + if ((ptr=b2::RTTI_cast(t))) return ptr; \ + return NULL; \ + } \ + void* cls::RTTI_scast(int i,void* p) \ + { cls* ptr = (cls*)p; \ + switch(i) \ + { case 0: return (b1*)ptr; \ + case 1: return (b2*)ptr; \ + } \ + return ptr; \ + } + +#define UL_RTTI_DEF3_BASE(cls,b1,b2,b3) \ + static const ulRTTITypeinfo* RTTI_base_ ## cls [] = \ + { UL_STATIC_TYPE_INFO(b1).get_info(), \ + UL_STATIC_TYPE_INFO(b2).get_info(), \ + UL_STATIC_TYPE_INFO(b3).get_info(), NULL }; \ + void* cls::RTTI_cast(ulRTTItypeid t) \ + { \ + if (t.isSame(&RTTI_obj)) return this; \ + void* ptr; \ + if ((ptr=b1::RTTI_cast(t))) return ptr; \ + if ((ptr=b2::RTTI_cast(t))) return ptr; \ + if ((ptr=b3::RTTI_cast(t))) return ptr; \ + return NULL; \ + } \ + void* cls::RTTI_scast(int i,void* p) \ + { cls* ptr = (cls*)p; \ + switch(i) \ + { case 0: return (b1*)ptr; \ + case 1: return (b2*)ptr; \ + case 2: return (b3*)ptr; \ + } \ + return ptr; \ + } + + + +#define UL_RTTI_DEF_INST(cls) \ + UL_RTTI_DEF_BASE(cls) \ + UL_RTTI_NEW(cls) + +#define UL_RTTI_DEF(cls) \ + UL_RTTI_DEF_BASE(cls) \ + UL_RTTI_NO_NEW(cls) + +#define UL_RTTI_DEF1_INST(cls,b1) \ + UL_RTTI_DEF1_BASE(cls,b1) \ + UL_RTTI_NEW(cls) + +#define UL_RTTI_DEF1(cls,b1) \ + UL_RTTI_DEF1_BASE(cls,b1) \ + UL_RTTI_NO_NEW(cls) + +#define UL_RTTI_DEF2_INST(cls,b1,b2) \ + UL_RTTI_DEF2_BASE(cls,b1,b2) \ + UL_RTTI_NEW(cls) + +#define UL_RTTI_DEF2(cls,b1,b2) \ + UL_RTTI_DEF2_BASE(cls,b1,b2) \ + UL_RTTI_NO_NEW(cls) + +#define UL_RTTI_DEF3_INST(cls,b1,b2,b3) \ + UL_RTTI_DEF3_BASE(cls,b1,b2,b3) \ + UL_RTTI_NEW(cls) + +#define UL_RTTI_DEF3(cls,b1,b2,b3) \ + UL_RTTI_DEF3_BASE(cls,b1,b2,b3) \ + UL_RTTI_NO_NEW(cls) + + +#endif + diff --git a/lib/libfreetype.a b/lib/libfreetype.a new file mode 100644 index 0000000..39f213f Binary files /dev/null and b/lib/libfreetype.a differ diff --git a/lib/libfreetype.la b/lib/libfreetype.la new file mode 100755 index 0000000..cbb29eb --- /dev/null +++ b/lib/libfreetype.la @@ -0,0 +1,41 @@ +# libfreetype.la - a libtool library file +# Generated by libtool (GNU libtool) 2.4.2 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='' + +# Names of this library. +library_names='' + +# The name of the static archive. +old_library='libfreetype.a' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags=' ' + +# Libraries that this one depends upon. +dependency_libs=' -lz' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libfreetype. +current=16 +age=10 +revision=1 + +# Is this an already installed library? +installed=yes + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/Users/jenkins/jenkins-root/workspace/Mac-FreeType/dist/lib' diff --git a/lib/libplibfnt.a b/lib/libplibfnt.a new file mode 100644 index 0000000..2c1a88b Binary files /dev/null and b/lib/libplibfnt.a differ diff --git a/lib/libplibjs.a b/lib/libplibjs.a new file mode 100644 index 0000000..809d20b Binary files /dev/null and b/lib/libplibjs.a differ diff --git a/lib/libplibnet.a b/lib/libplibnet.a new file mode 100644 index 0000000..e0337cf Binary files /dev/null and b/lib/libplibnet.a differ diff --git a/lib/libplibpu.a b/lib/libplibpu.a new file mode 100644 index 0000000..6a410b7 Binary files /dev/null and b/lib/libplibpu.a differ diff --git a/lib/libplibpuaux.a b/lib/libplibpuaux.a new file mode 100644 index 0000000..2a9954a Binary files /dev/null and b/lib/libplibpuaux.a differ diff --git a/lib/libplibsg.a b/lib/libplibsg.a new file mode 100644 index 0000000..78f19c7 Binary files /dev/null and b/lib/libplibsg.a differ diff --git a/lib/libplibul.a b/lib/libplibul.a new file mode 100644 index 0000000..51b5e22 Binary files /dev/null and b/lib/libplibul.a differ