initial commit

This commit is contained in:
Gero Müller 2011-01-04 18:11:59 +01:00
commit cb7368c138
99 changed files with 29055 additions and 0 deletions

6
CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
cmake_minimum_required (VERSION 2.6)
project (GREMLIN C CXX)
add_subdirectory (libs/glfw)
add_subdirectory (libs/enet)
add_subdirectory (src)

12
libs/enet/CMakeLists.txt Normal file
View File

@ -0,0 +1,12 @@
include_directories (include)
add_library (enet callbacks.c
compress.c
host.c
list.c
packet.c
peer.c
protocol.c
unix.c
win32.c
)

86
libs/enet/ChangeLog Normal file
View File

@ -0,0 +1,86 @@
ENet 1.3.0 (June 5, 2010):
* enet_host_create() now requires the channel limit to be specified as
a parameter
* enet_host_connect() now accepts a data parameter which is supplied
to the receiving receiving host in the event data field for a connect event
* added an adaptive order-2 PPM range coder as a built-in compressor option
which can be set with enet_host_compress_with_range_coder()
* added support for packet compression configurable with a callback
* improved session number handling to not rely on the packet checksum
field, saving 4 bytes per packet unless the checksum option is used
* removed the dependence on the rand callback for session number handling
Caveats: This version is not protocol compatible with the 1.2 series or
earlier. The enet_host_connect and enet_host_create API functions require
supplying additional parameters.
ENet 1.2.2 (June 5, 2010):
* checksum functionality is now enabled by setting a checksum callback
inside ENetHost instead of being a configure script option
* added totalSentData, totalSentPackets, totalReceivedData, and
totalReceivedPackets counters inside ENetHost for getting usage
statistics
* added enet_host_channel_limit() for limiting the maximum number of
channels allowed by connected peers
* now uses dispatch queues for event dispatch rather than potentially
unscalable array walking
* added no_memory callback that is called when a malloc attempt fails,
such that if no_memory returns rather than aborts (the default behavior),
then the error is propagated to the return value of the API calls
* now uses packed attribute for protocol structures on platforms with
strange alignment rules
* improved autoconf build system contributed by Nathan Brink allowing
for easier building as a shared library
Caveats: If you were using the compile-time option that enabled checksums,
make sure to set the checksum callback inside ENetHost to enet_crc32 to
regain the old behavior. The ENetCallbacks structure has added new fields,
so make sure to clear the structure to zero before use if
using enet_initialize_with_callbacks().
ENet 1.2.1 (November 12, 2009):
* fixed bug that could cause disconnect events to be dropped
* added thin wrapper around select() for portable usage
* added ENET_SOCKOPT_REUSEADDR socket option
* factored enet_socket_bind()/enet_socket_listen() out of enet_socket_create()
* added contributed Code::Blocks build file
ENet 1.2 (February 12, 2008):
* fixed bug in VERIFY_CONNECT acknowledgement that could cause connect
attempts to occasionally timeout
* fixed acknowledgements to check both the outgoing and sent queues
when removing acknowledged packets
* fixed accidental bit rot in the MSVC project file
* revised sequence number overflow handling to address some possible
disconnect bugs
* added enet_host_check_events() for getting only local queued events
* factored out socket option setting into enet_socket_set_option() so
that socket options are now set separately from enet_socket_create()
Caveats: While this release is superficially protocol compatible with 1.1,
differences in the sequence number overflow handling can potentially cause
random disconnects.
ENet 1.1 (June 6, 2007):
* optional CRC32 just in case someone needs a stronger checksum than UDP
provides (--enable-crc32 configure option)
* the size of packet headers are half the size they used to be (so less
overhead when sending small packets)
* enet_peer_disconnect_later() that waits till all queued outgoing
packets get sent before issuing an actual disconnect
* freeCallback field in individual packets for notification of when a
packet is about to be freed
* ENET_PACKET_FLAG_NO_ALLOCATE for supplying pre-allocated data to a
packet (can be used in concert with freeCallback to support some custom
allocation schemes that the normal memory allocation callbacks would
normally not allow)
* enet_address_get_host_ip() for printing address numbers
* promoted the enet_socket_*() functions to be part of the API now
* a few stability/crash fixes

7
libs/enet/LICENSE Normal file
View File

@ -0,0 +1,7 @@
Copyright (c) 2002-2010 Lee Salzman
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

15
libs/enet/README Normal file
View File

@ -0,0 +1,15 @@
Please visit the ENet homepage at http://enet.bespin.org for installation
and usage instructions.
If you obtained this package from CVS, the quick description on how to build
is:
# Generate the build system.
autoreconf -vfi
# Compile and install the library.
./configure && make && make install

47
libs/enet/callbacks.c Normal file
View File

@ -0,0 +1,47 @@
/**
@file callbacks.c
@brief ENet callback functions
*/
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
static ENetCallbacks callbacks = { malloc, free, abort };
int
enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits)
{
if (version < ENET_VERSION_CREATE (1, 3, 0))
return -1;
if (inits -> malloc != NULL || inits -> free != NULL)
{
if (inits -> malloc == NULL || inits -> free == NULL)
return -1;
callbacks.malloc = inits -> malloc;
callbacks.free = inits -> free;
}
if (inits -> no_memory != NULL)
callbacks.no_memory = inits -> no_memory;
return enet_initialize ();
}
void *
enet_malloc (size_t size)
{
void * memory = callbacks.malloc (size);
if (memory == NULL)
callbacks.no_memory ();
return memory;
}
void
enet_free (void * memory)
{
callbacks.free (memory);
}

654
libs/enet/compress.c Normal file
View File

@ -0,0 +1,654 @@
/**
@file compress.c
@brief An adaptive order-2 PPM range coder
*/
#define ENET_BUILDING_LIB 1
#include <string.h>
#include "enet/enet.h"
typedef struct _ENetSymbol
{
/* binary indexed tree of symbols */
enet_uint8 value;
enet_uint8 count;
enet_uint16 under;
enet_uint16 left, right;
/* context defined by this symbol */
enet_uint16 symbols;
enet_uint16 escapes;
enet_uint16 total;
enet_uint16 parent;
} ENetSymbol;
/* adaptation constants tuned aggressively for small packet sizes rather than large file compression */
enum
{
ENET_RANGE_CODER_TOP = 1<<24,
ENET_RANGE_CODER_BOTTOM = 1<<16,
ENET_CONTEXT_SYMBOL_DELTA = 3,
ENET_CONTEXT_SYMBOL_MINIMUM = 1,
ENET_CONTEXT_ESCAPE_MINIMUM = 1,
ENET_SUBCONTEXT_ORDER = 2,
ENET_SUBCONTEXT_SYMBOL_DELTA = 2,
ENET_SUBCONTEXT_ESCAPE_DELTA = 5
};
/* context exclusion roughly halves compression speed, so disable for now */
#undef ENET_CONTEXT_EXCLUSION
typedef struct _ENetRangeCoder
{
/* only allocate enough symbols for reasonable MTUs, would need to be larger for large file compression */
ENetSymbol symbols[4096];
} ENetRangeCoder;
void *
enet_range_coder_create (void)
{
ENetRangeCoder * rangeCoder = (ENetRangeCoder *) enet_malloc (sizeof (ENetRangeCoder));
if (rangeCoder == NULL)
return NULL;
return rangeCoder;
}
void
enet_range_coder_destroy (void * context)
{
ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
if (rangeCoder == NULL)
return;
enet_free (rangeCoder);
}
#define ENET_SYMBOL_CREATE(symbol, value_, count_) \
{ \
symbol = & rangeCoder -> symbols [nextSymbol ++]; \
symbol -> value = value_; \
symbol -> count = count_; \
symbol -> under = count_; \
symbol -> left = 0; \
symbol -> right = 0; \
symbol -> symbols = 0; \
symbol -> escapes = 0; \
symbol -> total = 0; \
symbol -> parent = 0; \
}
#define ENET_CONTEXT_CREATE(context, escapes_, minimum) \
{ \
ENET_SYMBOL_CREATE (context, 0, 0); \
(context) -> escapes = escapes_; \
(context) -> total = escapes_ + 256*minimum; \
(context) -> symbols = 0; \
}
static enet_uint16
enet_symbol_rescale (ENetSymbol * symbol)
{
enet_uint16 total = 0;
for (;;)
{
symbol -> count -= symbol->count >> 1;
symbol -> under = symbol -> count;
if (symbol -> left)
symbol -> under += enet_symbol_rescale (symbol + symbol -> left);
total += symbol -> under;
if (! symbol -> right) break;
symbol += symbol -> right;
}
return total;
}
#define ENET_CONTEXT_RESCALE(context, minimum) \
{ \
(context) -> total = (context) -> symbols ? enet_symbol_rescale ((context) + (context) -> symbols) : 0; \
(context) -> escapes -= (context) -> escapes >> 1; \
(context) -> total += (context) -> escapes + 256*minimum; \
}
#define ENET_RANGE_CODER_OUTPUT(value) \
{ \
if (outData >= outEnd) \
return 0; \
* outData ++ = value; \
}
#define ENET_RANGE_CODER_ENCODE(under, count, total) \
{ \
encodeRange /= (total); \
encodeLow += (under) * encodeRange; \
encodeRange *= (count); \
for (;;) \
{ \
if((encodeLow ^ (encodeLow + encodeRange)) >= ENET_RANGE_CODER_TOP) \
{ \
if(encodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
encodeRange = -encodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
} \
ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
encodeRange <<= 8; \
encodeLow <<= 8; \
} \
}
#define ENET_RANGE_CODER_FLUSH \
{ \
while (encodeLow) \
{ \
ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
encodeLow <<= 8; \
} \
}
#define ENET_RANGE_CODER_FREE_SYMBOLS \
{ \
if (nextSymbol >= sizeof (rangeCoder -> symbols) / sizeof (ENetSymbol) - ENET_SUBCONTEXT_ORDER ) \
{ \
nextSymbol = 0; \
ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); \
predicted = 0; \
order = 0; \
} \
}
#define ENET_CONTEXT_ENCODE(context, symbol_, value_, under_, count_, update, minimum) \
{ \
under_ = value*minimum; \
count_ = minimum; \
if (! (context) -> symbols) \
{ \
ENET_SYMBOL_CREATE (symbol_, value_, update); \
(context) -> symbols = symbol_ - (context); \
} \
else \
{ \
ENetSymbol * node = (context) + (context) -> symbols; \
for (;;) \
{ \
if (value_ < node -> value) \
{ \
node -> under += update; \
if (node -> left) { node += node -> left; continue; } \
ENET_SYMBOL_CREATE (symbol_, value_, update); \
node -> left = symbol_ - node; \
} \
else \
if (value_ > node -> value) \
{ \
under_ += node -> under; \
if (node -> right) { node += node -> right; continue; } \
ENET_SYMBOL_CREATE (symbol_, value_, update); \
node -> right = symbol_ - node; \
} \
else \
{ \
count_ += node -> count; \
under_ += node -> under - node -> count; \
node -> under += update; \
node -> count += update; \
symbol_ = node; \
} \
break; \
} \
} \
}
#ifdef ENET_CONTEXT_EXCLUSION
static const ENetSymbol emptyContext = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
#define ENET_CONTEXT_WALK(context, body) \
{ \
const ENetSymbol * node = (context) + (context) -> symbols; \
const ENetSymbol * stack [256]; \
size_t stackSize = 0; \
while (node -> left) \
{ \
stack [stackSize ++] = node; \
node += node -> left; \
} \
for (;;) \
{ \
body; \
if (node -> right) \
{ \
node += node -> right; \
while (node -> left) \
{ \
stack [stackSize ++] = node; \
node += node -> left; \
} \
} \
else \
if (stackSize <= 0) \
break; \
else \
node = stack [-- stackSize]; \
} \
}
#define ENET_CONTEXT_ENCODE_EXCLUDE(context, value_, under, total, minimum) \
ENET_CONTEXT_WALK(context, { \
if (node -> value != value_) \
{ \
enet_uint16 parentCount = rangeCoder -> symbols [node -> parent].count + minimum; \
if (node -> value < value_) \
under -= parentCount; \
total -= parentCount; \
} \
})
#endif
size_t
enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit)
{
ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
const enet_uint8 * inData, * inEnd;
enet_uint32 encodeLow = 0, encodeRange = ~0;
ENetSymbol * root;
enet_uint16 predicted = 0;
size_t order = 0, nextSymbol = 0;
if (rangeCoder == NULL || inBufferCount <= 0 || inLimit <= 0)
return 0;
inData = (const enet_uint8 *) inBuffers -> data;
inEnd = & inData [inBuffers -> dataLength];
inBuffers ++;
inBufferCount --;
ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
for (;;)
{
ENetSymbol * subcontext, * symbol;
#ifdef ENET_CONTEXT_EXCLUSION
const ENetSymbol * childContext = & emptyContext;
#endif
enet_uint8 value;
enet_uint16 count, under, * parent = & predicted, total;
if (inData >= inEnd)
{
if (inBufferCount <= 0)
break;
inData = (const enet_uint8 *) inBuffers -> data;
inEnd = & inData [inBuffers -> dataLength];
inBuffers ++;
inBufferCount --;
}
value = * inData ++;
for (subcontext = & rangeCoder -> symbols [predicted];
subcontext != root;
#ifdef ENET_CONTEXT_EXCLUSION
childContext = subcontext,
#endif
subcontext = & rangeCoder -> symbols [subcontext -> parent])
{
ENET_CONTEXT_ENCODE (subcontext, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
* parent = symbol - rangeCoder -> symbols;
parent = & symbol -> parent;
total = subcontext -> total;
#ifdef ENET_CONTEXT_EXCLUSION
if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, 0);
#endif
if (count > 0)
{
ENET_RANGE_CODER_ENCODE (subcontext -> escapes + under, count, total);
}
else
{
if (subcontext -> escapes > 0 && subcontext -> escapes < total)
ENET_RANGE_CODER_ENCODE (0, subcontext -> escapes, total);
subcontext -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
subcontext -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
}
subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
ENET_CONTEXT_RESCALE (subcontext, 0);
if (count > 0) goto nextInput;
}
ENET_CONTEXT_ENCODE (root, symbol, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM);
* parent = symbol - rangeCoder -> symbols;
parent = & symbol -> parent;
total = root -> total;
#ifdef ENET_CONTEXT_EXCLUSION
if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM);
#endif
ENET_RANGE_CODER_ENCODE (root -> escapes + under, count, total);
root -> total += ENET_CONTEXT_SYMBOL_DELTA;
if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
nextInput:
if (order >= ENET_SUBCONTEXT_ORDER)
predicted = rangeCoder -> symbols [predicted].parent;
else
order ++;
ENET_RANGE_CODER_FREE_SYMBOLS;
}
ENET_RANGE_CODER_FLUSH;
return (size_t) (outData - outStart);
}
#define ENET_RANGE_CODER_SEED \
{ \
if (inData < inEnd) decodeCode |= * inData ++ << 24; \
if (inData < inEnd) decodeCode |= * inData ++ << 16; \
if (inData < inEnd) decodeCode |= * inData ++ << 8; \
if (inData < inEnd) decodeCode |= * inData ++; \
}
#define ENET_RANGE_CODER_READ(total) ((decodeCode - decodeLow) / (decodeRange /= (total)))
#define ENET_RANGE_CODER_DECODE(under, count, total) \
{ \
decodeLow += (under) * decodeRange; \
decodeRange *= (count); \
for (;;) \
{ \
if((decodeLow ^ (decodeLow + decodeRange)) >= ENET_RANGE_CODER_TOP) \
{ \
if(decodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
decodeRange = -decodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
} \
decodeCode <<= 8; \
if (inData < inEnd) \
decodeCode |= * inData ++; \
decodeRange <<= 8; \
decodeLow <<= 8; \
} \
}
#define ENET_CONTEXT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, createRoot, visitNode, createRight, createLeft) \
{ \
under_ = 0; \
count_ = minimum; \
if (! (context) -> symbols) \
{ \
createRoot; \
} \
else \
{ \
ENetSymbol * node = (context) + (context) -> symbols; \
for (;;) \
{ \
enet_uint16 after = under_ + node -> under + (node -> value + 1)*minimum, before = node -> count + minimum; \
visitNode; \
if (code >= after) \
{ \
under_ += node -> under; \
if (node -> right) { node += node -> right; continue; } \
createRight; \
} \
else \
if (code < after - before) \
{ \
node -> under += update; \
if (node -> left) { node += node -> left; continue; } \
createLeft; \
} \
else \
{ \
value_ = node -> value; \
count_ += node -> count; \
under_ = after - before; \
node -> under += update; \
node -> count += update; \
symbol_ = node; \
} \
break; \
} \
} \
}
#define ENET_CONTEXT_TRY_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, return 0, exclude (node -> value, after, before), return 0, return 0)
#define ENET_CONTEXT_ROOT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, \
{ \
value_ = code / minimum; \
under_ = code - code%minimum; \
ENET_SYMBOL_CREATE (symbol_, value_, update); \
(context) -> symbols = symbol_ - (context); \
}, \
exclude (node -> value, after, before), \
{ \
value_ = node->value + 1 + (code - after)/minimum; \
under_ = code - (code - after)%minimum; \
ENET_SYMBOL_CREATE (symbol_, value_, update); \
node -> right = symbol_ - node; \
}, \
{ \
value_ = node->value - 1 - (after - before - code - 1)/minimum; \
under_ = code - (after - before - code - 1)%minimum; \
ENET_SYMBOL_CREATE (symbol_, value_, update); \
node -> left = symbol_ - node; \
}) \
#ifdef ENET_CONTEXT_EXCLUSION
typedef struct _ENetExclude
{
enet_uint8 value;
enet_uint16 under;
} ENetExclude;
#define ENET_CONTEXT_DECODE_EXCLUDE(context, total, minimum) \
{ \
enet_uint16 under = 0; \
nextExclude = excludes; \
ENET_CONTEXT_WALK (context, { \
under += rangeCoder -> symbols [node -> parent].count + minimum; \
nextExclude -> value = node -> value; \
nextExclude -> under = under; \
nextExclude ++; \
}); \
total -= under; \
}
#define ENET_CONTEXT_EXCLUDED(value_, after, before) \
{ \
size_t low = 0, high = nextExclude - excludes; \
for(;;) \
{ \
size_t mid = (low + high) >> 1; \
const ENetExclude * exclude = & excludes [mid]; \
if (value_ < exclude -> value) \
{ \
if (low + 1 < high) \
{ \
high = mid; \
continue; \
} \
if (exclude > excludes) \
after -= exclude [-1].under; \
} \
else \
{ \
if (value_ > exclude -> value) \
{ \
if (low + 1 < high) \
{ \
low = mid; \
continue; \
} \
} \
else \
before = 0; \
after -= exclude -> under; \
} \
break; \
} \
}
#endif
#define ENET_CONTEXT_NOT_EXCLUDED(value_, after, before)
size_t
enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit)
{
ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
const enet_uint8 * inEnd = & inData [inLimit];
enet_uint32 decodeLow = 0, decodeCode = 0, decodeRange = ~0;
ENetSymbol * root;
enet_uint16 predicted = 0;
size_t order = 0, nextSymbol = 0;
#ifdef ENET_CONTEXT_EXCLUSION
ENetExclude excludes [256];
ENetExclude * nextExclude = excludes;
#endif
if (rangeCoder == NULL || inLimit <= 0)
return 0;
ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
ENET_RANGE_CODER_SEED;
for (;;)
{
ENetSymbol * subcontext, * symbol, * patch;
#ifdef ENET_CONTEXT_EXCLUSION
const ENetSymbol * childContext = & emptyContext;
#endif
enet_uint8 value = 0;
enet_uint16 code, under, count, bottom, * parent = & predicted, total;
for (subcontext = & rangeCoder -> symbols [predicted];
subcontext != root;
#ifdef ENET_CONTEXT_EXCLUSION
childContext = subcontext,
#endif
subcontext = & rangeCoder -> symbols [subcontext -> parent])
{
if (subcontext -> escapes <= 0)
continue;
total = subcontext -> total;
#ifdef ENET_CONTEXT_EXCLUSION
if (childContext -> total > 0)
ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, 0);
#endif
if (subcontext -> escapes >= total)
continue;
code = ENET_RANGE_CODER_READ (total);
if (code < subcontext -> escapes)
{
ENET_RANGE_CODER_DECODE (0, subcontext -> escapes, total);
continue;
}
code -= subcontext -> escapes;
#ifdef ENET_CONTEXT_EXCLUSION
if (childContext -> total > 0)
{
ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED);
}
else
#endif
{
ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED);
}
bottom = symbol - rangeCoder -> symbols;
ENET_RANGE_CODER_DECODE (subcontext -> escapes + under, count, total);
subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
ENET_CONTEXT_RESCALE (subcontext, 0);
goto patchContexts;
}
total = root -> total;
#ifdef ENET_CONTEXT_EXCLUSION
if (childContext -> total > 0)
ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM);
#endif
code = ENET_RANGE_CODER_READ (total);
if (code < root -> escapes)
{
ENET_RANGE_CODER_DECODE (0, root -> escapes, total);
break;
}
code -= root -> escapes;
#ifdef ENET_CONTEXT_EXCLUSION
if (childContext -> total > 0)
{
ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED);
}
else
#endif
{
ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED);
}
bottom = symbol - rangeCoder -> symbols;
ENET_RANGE_CODER_DECODE (root -> escapes + under, count, total);
root -> total += ENET_CONTEXT_SYMBOL_DELTA;
if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
patchContexts:
for (patch = & rangeCoder -> symbols [predicted];
patch != subcontext;
patch = & rangeCoder -> symbols [patch -> parent])
{
ENET_CONTEXT_ENCODE (patch, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
* parent = symbol - rangeCoder -> symbols;
parent = & symbol -> parent;
if (count <= 0)
{
patch -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
patch -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
}
patch -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || patch -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
ENET_CONTEXT_RESCALE (patch, 0);
}
* parent = bottom;
ENET_RANGE_CODER_OUTPUT (value);
if (order >= ENET_SUBCONTEXT_ORDER)
predicted = rangeCoder -> symbols [predicted].parent;
else
order ++;
ENET_RANGE_CODER_FREE_SYMBOLS;
}
return (size_t) (outData - outStart);
}
/** @defgroup host ENet host functions
@{
*/
/** Sets the packet compressor the host should use to the default range coder.
@param host host to enable the range coder for
@returns 0 on success, < 0 on failure
*/
int
enet_host_compress_with_range_coder (ENetHost * host)
{
ENetCompressor compressor;
memset (& compressor, 0, sizeof (compressor));
compressor.context = enet_range_coder_create();
if (compressor.context == NULL)
return -1;
compressor.compress = enet_range_coder_compress;
compressor.decompress = enet_range_coder_decompress;
compressor.destroy = enet_range_coder_destroy;
enet_host_compress (host, & compressor);
return 0;
}
/** @} */

479
libs/enet/host.c Normal file
View File

@ -0,0 +1,479 @@
/**
@file host.c
@brief ENet host management functions
*/
#define ENET_BUILDING_LIB 1
#include <string.h>
#include <time.h>
#include "enet/enet.h"
/** @defgroup host ENet host functions
@{
*/
/** Creates a host for communicating to peers.
@param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host.
@param peerCount the maximum number of peers that should be allocated for the host.
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
@param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
@param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
@returns the host on success and NULL on failure
@remarks ENet will strategically drop packets on specific sides of a connection between hosts
to ensure the host's bandwidth is not overwhelmed. The bandwidth parameters also determine
the window size of a connection which limits the amount of reliable packets that may be in transit
at any given time.
*/
ENetHost *
enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
{
ENetHost * host;
ENetPeer * currentPeer;
if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
return NULL;
host = (ENetHost *) enet_malloc (sizeof (ENetHost));
if (host == NULL)
return NULL;
host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer));
if (host -> peers == NULL)
{
enet_free (host);
return NULL;
}
memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
{
if (host -> socket != ENET_SOCKET_NULL)
enet_socket_destroy (host -> socket);
enet_free (host -> peers);
enet_free (host);
return NULL;
}
enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
if (address != NULL)
host -> address = * address;
if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
else
if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
host -> randomSeed = (enet_uint32) time(NULL) + (enet_uint32) (size_t) host;
host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16);
host -> channelLimit = channelLimit;
host -> incomingBandwidth = incomingBandwidth;
host -> outgoingBandwidth = outgoingBandwidth;
host -> bandwidthThrottleEpoch = 0;
host -> recalculateBandwidthLimits = 0;
host -> mtu = ENET_HOST_DEFAULT_MTU;
host -> peerCount = peerCount;
host -> commandCount = 0;
host -> bufferCount = 0;
host -> checksum = NULL;
host -> receivedAddress.host = ENET_HOST_ANY;
host -> receivedAddress.port = 0;
host -> receivedData = NULL;
host -> receivedDataLength = 0;
host -> totalSentData = 0;
host -> totalSentPackets = 0;
host -> totalReceivedData = 0;
host -> totalReceivedPackets = 0;
host -> compressor.context = NULL;
host -> compressor.compress = NULL;
host -> compressor.decompress = NULL;
host -> compressor.destroy = NULL;
enet_list_clear (& host -> dispatchQueue);
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
currentPeer -> host = host;
currentPeer -> incomingPeerID = currentPeer - host -> peers;
currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF;
currentPeer -> data = NULL;
enet_list_clear (& currentPeer -> acknowledgements);
enet_list_clear (& currentPeer -> sentReliableCommands);
enet_list_clear (& currentPeer -> sentUnreliableCommands);
enet_list_clear (& currentPeer -> outgoingReliableCommands);
enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
enet_list_clear (& currentPeer -> dispatchedCommands);
enet_peer_reset (currentPeer);
}
return host;
}
/** Destroys the host and all resources associated with it.
@param host pointer to the host to destroy
*/
void
enet_host_destroy (ENetHost * host)
{
ENetPeer * currentPeer;
enet_socket_destroy (host -> socket);
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
enet_peer_reset (currentPeer);
}
if (host -> compressor.context != NULL && host -> compressor.destroy)
(* host -> compressor.destroy) (host -> compressor.context);
enet_free (host -> peers);
enet_free (host);
}
/** Initiates a connection to a foreign host.
@param host host seeking the connection
@param address destination for the connection
@param channelCount number of channels to allocate
@param data user data supplied to the receiving host
@returns a peer representing the foreign host on success, NULL on failure
@remarks The peer returned will have not completed the connection until enet_host_service()
notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
*/
ENetPeer *
enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data)
{
ENetPeer * currentPeer;
ENetChannel * channel;
ENetProtocol command;
if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
else
if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
break;
}
if (currentPeer >= & host -> peers [host -> peerCount])
return NULL;
currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
if (currentPeer -> channels == NULL)
return NULL;
currentPeer -> channelCount = channelCount;
currentPeer -> state = ENET_PEER_STATE_CONNECTING;
currentPeer -> address = * address;
currentPeer -> connectID = ++ host -> randomSeed;
if (host -> outgoingBandwidth == 0)
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
else
currentPeer -> windowSize = (host -> outgoingBandwidth /
ENET_PEER_WINDOW_SIZE_SCALE) *
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
else
if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
for (channel = currentPeer -> channels;
channel < & currentPeer -> channels [channelCount];
++ channel)
{
channel -> outgoingReliableSequenceNumber = 0;
channel -> outgoingUnreliableSequenceNumber = 0;
channel -> incomingReliableSequenceNumber = 0;
enet_list_clear (& channel -> incomingReliableCommands);
enet_list_clear (& channel -> incomingUnreliableCommands);
channel -> usedReliableWindows = 0;
memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
}
command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF;
command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
command.connect.incomingSessionID = currentPeer -> incomingSessionID;
command.connect.outgoingSessionID = currentPeer -> outgoingSessionID;
command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu);
command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
command.connect.connectID = currentPeer -> connectID;
command.connect.data = ENET_HOST_TO_NET_32 (data);
enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
return currentPeer;
}
/** Queues a packet to be sent to all peers associated with the host.
@param host host on which to broadcast the packet
@param channelID channel on which to broadcast
@param packet packet to broadcast
*/
void
enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
{
ENetPeer * currentPeer;
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
continue;
enet_peer_send (currentPeer, channelID, packet);
}
if (packet -> referenceCount == 0)
enet_packet_destroy (packet);
}
/** Sets the packet compressor the host should use to compress and decompress packets.
@param host host to enable or disable compression for
@param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
*/
void
enet_host_compress (ENetHost * host, const ENetCompressor * compressor)
{
if (host -> compressor.context != NULL && host -> compressor.destroy)
(* host -> compressor.destroy) (host -> compressor.context);
if (compressor)
host -> compressor = * compressor;
else
host -> compressor.context = NULL;
}
/** Limits the maximum allowed channels of future incoming connections.
@param host host to limit
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
*/
void
enet_host_channel_limit (ENetHost * host, size_t channelLimit)
{
if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
else
if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
host -> channelLimit = channelLimit;
}
/** Adjusts the bandwidth limits of a host.
@param host host to adjust
@param incomingBandwidth new incoming bandwidth
@param outgoingBandwidth new outgoing bandwidth
@remarks the incoming and outgoing bandwidth parameters are identical in function to those
specified in enet_host_create().
*/
void
enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
{
host -> incomingBandwidth = incomingBandwidth;
host -> outgoingBandwidth = outgoingBandwidth;
host -> recalculateBandwidthLimits = 1;
}
void
enet_host_bandwidth_throttle (ENetHost * host)
{
enet_uint32 timeCurrent = enet_time_get (),
elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
peersTotal = 0,
dataTotal = 0,
peersRemaining,
bandwidth,
throttle = 0,
bandwidthLimit = 0;
int needsAdjustment;
ENetPeer * peer;
ENetProtocol command;
if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
return;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
continue;
++ peersTotal;
dataTotal += peer -> outgoingDataTotal;
}
if (peersTotal == 0)
return;
peersRemaining = peersTotal;
needsAdjustment = 1;
if (host -> outgoingBandwidth == 0)
bandwidth = ~0;
else
bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
while (peersRemaining > 0 && needsAdjustment != 0)
{
needsAdjustment = 0;
if (dataTotal < bandwidth)
throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
else
throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
enet_uint32 peerBandwidth;
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> incomingBandwidth == 0 ||
peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
continue;
peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
continue;
peer -> packetThrottleLimit = (peerBandwidth *
ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
if (peer -> packetThrottleLimit == 0)
peer -> packetThrottleLimit = 1;
if (peer -> packetThrottle > peer -> packetThrottleLimit)
peer -> packetThrottle = peer -> packetThrottleLimit;
peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
needsAdjustment = 1;
-- peersRemaining;
bandwidth -= peerBandwidth;
dataTotal -= peerBandwidth;
}
}
if (peersRemaining > 0)
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
continue;
peer -> packetThrottleLimit = throttle;
if (peer -> packetThrottle > peer -> packetThrottleLimit)
peer -> packetThrottle = peer -> packetThrottleLimit;
}
if (host -> recalculateBandwidthLimits)
{
host -> recalculateBandwidthLimits = 0;
peersRemaining = peersTotal;
bandwidth = host -> incomingBandwidth;
needsAdjustment = 1;
if (bandwidth == 0)
bandwidthLimit = 0;
else
while (peersRemaining > 0 && needsAdjustment != 0)
{
needsAdjustment = 0;
bandwidthLimit = bandwidth / peersRemaining;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> incomingBandwidthThrottleEpoch == timeCurrent)
continue;
if (peer -> outgoingBandwidth > 0 &&
peer -> outgoingBandwidth >= bandwidthLimit)
continue;
peer -> incomingBandwidthThrottleEpoch = timeCurrent;
needsAdjustment = 1;
-- peersRemaining;
bandwidth -= peer -> outgoingBandwidth;
}
}
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
continue;
command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF;
command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
else
command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
}
}
host -> bandwidthThrottleEpoch = timeCurrent;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
peer -> incomingDataTotal = 0;
peer -> outgoingDataTotal = 0;
}
}
/** @} */

View File

@ -0,0 +1,27 @@
/**
@file callbacks.h
@brief ENet callbacks
*/
#ifndef __ENET_CALLBACKS_H__
#define __ENET_CALLBACKS_H__
#include <stdlib.h>
typedef struct _ENetCallbacks
{
void * (ENET_CALLBACK * malloc) (size_t size);
void (ENET_CALLBACK * free) (void * memory);
void (ENET_CALLBACK * no_memory) (void);
} ENetCallbacks;
/** @defgroup callbacks ENet internal callbacks
@{
@ingroup private
*/
extern void * enet_malloc (size_t);
extern void enet_free (void *);
/** @} */
#endif /* __ENET_CALLBACKS_H__ */

View File

@ -0,0 +1,540 @@
/**
@file enet.h
@brief ENet public header file
*/
#ifndef __ENET_ENET_H__
#define __ENET_ENET_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdlib.h>
#ifdef WIN32
#include "enet/win32.h"
#else
#include "enet/unix.h"
#endif
#include "enet/types.h"
#include "enet/protocol.h"
#include "enet/list.h"
#include "enet/callbacks.h"
#define ENET_VERSION_MAJOR 1
#define ENET_VERSION_MINOR 3
#define ENET_VERSION_PATCH 0
#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
#define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH)
typedef enet_uint32 ENetVersion;
typedef enum _ENetSocketType
{
ENET_SOCKET_TYPE_STREAM = 1,
ENET_SOCKET_TYPE_DATAGRAM = 2
} ENetSocketType;
typedef enum _ENetSocketWait
{
ENET_SOCKET_WAIT_NONE = 0,
ENET_SOCKET_WAIT_SEND = (1 << 0),
ENET_SOCKET_WAIT_RECEIVE = (1 << 1)
} ENetSocketWait;
typedef enum _ENetSocketOption
{
ENET_SOCKOPT_NONBLOCK = 1,
ENET_SOCKOPT_BROADCAST = 2,
ENET_SOCKOPT_RCVBUF = 3,
ENET_SOCKOPT_SNDBUF = 4,
ENET_SOCKOPT_REUSEADDR = 5
} ENetSocketOption;
enum
{
ENET_HOST_ANY = 0, /**< specifies the default server host */
ENET_HOST_BROADCAST = 0xFFFFFFFF, /**< specifies a subnet-wide broadcast */
ENET_PORT_ANY = 0 /**< specifies that a port should be automatically chosen */
};
/**
* Portable internet address structure.
*
* The host must be specified in network byte-order, and the port must be in host
* byte-order. The constant ENET_HOST_ANY may be used to specify the default
* server host. The constant ENET_HOST_BROADCAST may be used to specify the
* broadcast address (255.255.255.255). This makes sense for enet_host_connect,
* but not for enet_host_create. Once a server responds to a broadcast, the
* address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
*/
typedef struct _ENetAddress
{
enet_uint32 host;
enet_uint16 port;
} ENetAddress;
/**
* Packet flag bit constants.
*
* The host must be specified in network byte-order, and the port must be in
* host byte-order. The constant ENET_HOST_ANY may be used to specify the
* default server host.
@sa ENetPacket
*/
typedef enum _ENetPacketFlag
{
/** packet must be received by the target peer and resend attempts should be
* made until the packet is delivered */
ENET_PACKET_FLAG_RELIABLE = (1 << 0),
/** packet will not be sequenced with other packets
* not supported for reliable packets
*/
ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1),
/** packet will not allocate data, and user must supply it instead */
ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2)
} ENetPacketFlag;
struct _ENetPacket;
typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
/**
* ENet packet structure.
*
* An ENet data packet that may be sent to or received from a peer. The shown
* fields should only be read and never modified. The data field contains the
* allocated data for the packet. The dataLength fields specifies the length
* of the allocated data. The flags field is either 0 (specifying no flags),
* or a bitwise-or of any combination of the following flags:
*
* ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer
* and resend attempts should be made until the packet is delivered
*
* ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets
* (not supported for reliable packets)
*
* ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead
@sa ENetPacketFlag
*/
typedef struct _ENetPacket
{
size_t referenceCount; /**< internal use only */
enet_uint32 flags; /**< bitwise-or of ENetPacketFlag constants */
enet_uint8 * data; /**< allocated data for packet */
size_t dataLength; /**< length of data */
ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */
} ENetPacket;
typedef struct _ENetAcknowledgement
{
ENetListNode acknowledgementList;
enet_uint32 sentTime;
ENetProtocol command;
} ENetAcknowledgement;
typedef struct _ENetOutgoingCommand
{
ENetListNode outgoingCommandList;
enet_uint16 reliableSequenceNumber;
enet_uint16 unreliableSequenceNumber;
enet_uint32 sentTime;
enet_uint32 roundTripTimeout;
enet_uint32 roundTripTimeoutLimit;
enet_uint32 fragmentOffset;
enet_uint16 fragmentLength;
enet_uint16 sendAttempts;
ENetProtocol command;
ENetPacket * packet;
} ENetOutgoingCommand;
typedef struct _ENetIncomingCommand
{
ENetListNode incomingCommandList;
enet_uint16 reliableSequenceNumber;
enet_uint16 unreliableSequenceNumber;
ENetProtocol command;
enet_uint32 fragmentCount;
enet_uint32 fragmentsRemaining;
enet_uint32 * fragments;
ENetPacket * packet;
} ENetIncomingCommand;
typedef enum _ENetPeerState
{
ENET_PEER_STATE_DISCONNECTED = 0,
ENET_PEER_STATE_CONNECTING = 1,
ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2,
ENET_PEER_STATE_CONNECTION_PENDING = 3,
ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4,
ENET_PEER_STATE_CONNECTED = 5,
ENET_PEER_STATE_DISCONNECT_LATER = 6,
ENET_PEER_STATE_DISCONNECTING = 7,
ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8,
ENET_PEER_STATE_ZOMBIE = 9
} ENetPeerState;
#ifndef ENET_BUFFER_MAXIMUM
#define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS)
#endif
enum
{
ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024,
ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000,
ENET_HOST_DEFAULT_MTU = 1400,
ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500,
ENET_PEER_DEFAULT_PACKET_THROTTLE = 32,
ENET_PEER_PACKET_THROTTLE_SCALE = 32,
ENET_PEER_PACKET_THROTTLE_COUNTER = 7,
ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2,
ENET_PEER_PACKET_THROTTLE_DECELERATION = 2,
ENET_PEER_PACKET_THROTTLE_INTERVAL = 5000,
ENET_PEER_PACKET_LOSS_SCALE = (1 << 16),
ENET_PEER_PACKET_LOSS_INTERVAL = 10000,
ENET_PEER_WINDOW_SIZE_SCALE = 64 * 1024,
ENET_PEER_TIMEOUT_LIMIT = 32,
ENET_PEER_TIMEOUT_MINIMUM = 5000,
ENET_PEER_TIMEOUT_MAXIMUM = 30000,
ENET_PEER_PING_INTERVAL = 500,
ENET_PEER_UNSEQUENCED_WINDOWS = 64,
ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 1024,
ENET_PEER_FREE_UNSEQUENCED_WINDOWS = 32,
ENET_PEER_RELIABLE_WINDOWS = 16,
ENET_PEER_RELIABLE_WINDOW_SIZE = 0x1000,
ENET_PEER_FREE_RELIABLE_WINDOWS = 8
};
typedef struct _ENetChannel
{
enet_uint16 outgoingReliableSequenceNumber;
enet_uint16 outgoingUnreliableSequenceNumber;
enet_uint16 usedReliableWindows;
enet_uint16 reliableWindows [ENET_PEER_RELIABLE_WINDOWS];
enet_uint16 incomingReliableSequenceNumber;
ENetList incomingReliableCommands;
ENetList incomingUnreliableCommands;
} ENetChannel;
/**
* An ENet peer which data packets may be sent or received from.
*
* No fields should be modified unless otherwise specified.
*/
typedef struct _ENetPeer
{
ENetListNode dispatchList;
struct _ENetHost * host;
enet_uint16 outgoingPeerID;
enet_uint16 incomingPeerID;
enet_uint32 connectID;
enet_uint8 outgoingSessionID;
enet_uint8 incomingSessionID;
ENetAddress address; /**< Internet address of the peer */
void * data; /**< Application private data, may be freely modified */
ENetPeerState state;
ENetChannel * channels;
size_t channelCount; /**< Number of channels allocated for communication with peer */
enet_uint32 incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */
enet_uint32 outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */
enet_uint32 incomingBandwidthThrottleEpoch;
enet_uint32 outgoingBandwidthThrottleEpoch;
enet_uint32 incomingDataTotal;
enet_uint32 outgoingDataTotal;
enet_uint32 lastSendTime;
enet_uint32 lastReceiveTime;
enet_uint32 nextTimeout;
enet_uint32 earliestTimeout;
enet_uint32 packetLossEpoch;
enet_uint32 packetsSent;
enet_uint32 packetsLost;
enet_uint32 packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */
enet_uint32 packetLossVariance;
enet_uint32 packetThrottle;
enet_uint32 packetThrottleLimit;
enet_uint32 packetThrottleCounter;
enet_uint32 packetThrottleEpoch;
enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration;
enet_uint32 packetThrottleInterval;
enet_uint32 lastRoundTripTime;
enet_uint32 lowestRoundTripTime;
enet_uint32 lastRoundTripTimeVariance;
enet_uint32 highestRoundTripTimeVariance;
enet_uint32 roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */
enet_uint32 roundTripTimeVariance;
enet_uint32 mtu;
enet_uint32 windowSize;
enet_uint32 reliableDataInTransit;
enet_uint16 outgoingReliableSequenceNumber;
ENetList acknowledgements;
ENetList sentReliableCommands;
ENetList sentUnreliableCommands;
ENetList outgoingReliableCommands;
ENetList outgoingUnreliableCommands;
ENetList dispatchedCommands;
int needsDispatch;
enet_uint16 incomingUnsequencedGroup;
enet_uint16 outgoingUnsequencedGroup;
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
enet_uint32 eventData;
} ENetPeer;
/** An ENet packet compressor for compressing UDP packets before socket sends or receives.
*/
typedef struct _ENetCompressor
{
/** Context data for the compressor. Must be non-NULL. */
void * context;
/** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
size_t (ENET_CALLBACK * compress) (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit);
/** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
size_t (ENET_CALLBACK * decompress) (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit);
/** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */
void (ENET_CALLBACK * destroy) (void * context);
} ENetCompressor;
/** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */
typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * buffers, size_t bufferCount);
/** An ENet host for communicating with peers.
*
* No fields should be modified unless otherwise stated.
@sa enet_host_create()
@sa enet_host_destroy()
@sa enet_host_connect()
@sa enet_host_service()
@sa enet_host_flush()
@sa enet_host_broadcast()
@sa enet_host_compress()
@sa enet_host_compress_with_range_coder()
@sa enet_host_channel_limit()
@sa enet_host_bandwidth_limit()
@sa enet_host_bandwidth_throttle()
*/
typedef struct _ENetHost
{
ENetSocket socket;
ENetAddress address; /**< Internet address of the host */
enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */
enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */
enet_uint32 bandwidthThrottleEpoch;
enet_uint32 mtu;
enet_uint32 randomSeed;
int recalculateBandwidthLimits;
ENetPeer * peers; /**< array of peers allocated for this host */
size_t peerCount; /**< number of peers allocated for this host */
size_t channelLimit; /**< maximum number of channels allowed for connected peers */
enet_uint32 serviceTime;
ENetList dispatchQueue;
int continueSending;
size_t packetSize;
enet_uint16 headerFlags;
ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
size_t commandCount;
ENetBuffer buffers [ENET_BUFFER_MAXIMUM];
size_t bufferCount;
ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */
ENetCompressor compressor;
enet_uint8 packetData [2][ENET_PROTOCOL_MAXIMUM_MTU];
ENetAddress receivedAddress;
enet_uint8 * receivedData;
size_t receivedDataLength;
enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */
enet_uint32 totalSentPackets; /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */
enet_uint32 totalReceivedData; /**< total data received, user should reset to 0 as needed to prevent overflow */
enet_uint32 totalReceivedPackets; /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */
} ENetHost;
/**
* An ENet event type, as specified in @ref ENetEvent.
*/
typedef enum _ENetEventType
{
/** no event occurred within the specified time limit */
ENET_EVENT_TYPE_NONE = 0,
/** a connection request initiated by enet_host_connect has completed.
* The peer field contains the peer which successfully connected.
*/
ENET_EVENT_TYPE_CONNECT = 1,
/** a peer has disconnected. This event is generated on a successful
* completion of a disconnect initiated by enet_pper_disconnect, if
* a peer has timed out, or if a connection request intialized by
* enet_host_connect has timed out. The peer field contains the peer
* which disconnected. The data field contains user supplied data
* describing the disconnection, or 0, if none is available.
*/
ENET_EVENT_TYPE_DISCONNECT = 2,
/** a packet has been received from a peer. The peer field specifies the
* peer which sent the packet. The channelID field specifies the channel
* number upon which the packet was received. The packet field contains
* the packet that was received; this packet must be destroyed with
* enet_packet_destroy after use.
*/
ENET_EVENT_TYPE_RECEIVE = 3
} ENetEventType;
/**
* An ENet event as returned by enet_host_service().
@sa enet_host_service
*/
typedef struct _ENetEvent
{
ENetEventType type; /**< type of the event */
ENetPeer * peer; /**< peer that generated a connect, disconnect or receive event */
enet_uint8 channelID; /**< channel on the peer that generated the event, if appropriate */
enet_uint32 data; /**< data associated with the event, if appropriate */
ENetPacket * packet; /**< packet associated with the event, if appropriate */
} ENetEvent;
/** @defgroup global ENet global functions
@{
*/
/**
Initializes ENet globally. Must be called prior to using any functions in
ENet.
@returns 0 on success, < 0 on failure
*/
ENET_API int enet_initialize (void);
/**
Initializes ENet globally and supplies user-overridden callbacks. Must be called prior to using any functions in ENet. Do not use enet_initialize() if you use this variant. Make sure the ENetCallbacks structure is zeroed out so that any additional callbacks added in future versions will be properly ignored.
@param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use
@param inits user-overriden callbacks where any NULL callbacks will use ENet's defaults
@returns 0 on success, < 0 on failure
*/
ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits);
/**
Shuts down ENet globally. Should be called when a program that has
initialized ENet exits.
*/
ENET_API void enet_deinitialize (void);
/** @} */
/** @defgroup private ENet private implementation functions */
/**
Returns the wall-time in milliseconds. Its initial value is unspecified
unless otherwise set.
*/
ENET_API enet_uint32 enet_time_get (void);
/**
Sets the current wall-time in milliseconds.
*/
ENET_API void enet_time_set (enet_uint32);
/** @defgroup socket ENet socket functions
@{
*/
ENET_API ENetSocket enet_socket_create (ENetSocketType);
ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *);
ENET_API int enet_socket_listen (ENetSocket, int);
ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *);
ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int);
ENET_API void enet_socket_destroy (ENetSocket);
ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
/** @} */
/** @defgroup Address ENet address functions
@{
*/
/** Attempts to resolve the host named by the parameter hostName and sets
the host field in the address parameter if successful.
@param address destination to store resolved address
@param hostName host name to lookup
@retval 0 on success
@retval < 0 on failure
@returns the address of the given hostName in address on success
*/
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
/** Gives the printable form of the ip address specified in the address parameter.
@param address address printed
@param hostName destination for name, must not be NULL
@param nameLength maximum length of hostName.
@returns the null-terminated name of the host in hostName on success
@retval 0 on success
@retval < 0 on failure
*/
ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength);
/** Attempts to do a reverse lookup of the host field in the address parameter.
@param address address used for reverse lookup
@param hostName destination for name, must not be NULL
@param nameLength maximum length of hostName.
@returns the null-terminated name of the host in hostName on success
@retval 0 on success
@retval < 0 on failure
*/
ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
/** @} */
ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
ENET_API void enet_packet_destroy (ENetPacket *);
ENET_API int enet_packet_resize (ENetPacket *, size_t);
extern enet_uint32 enet_crc32 (const ENetBuffer *, size_t);
ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32);
ENET_API void enet_host_destroy (ENetHost *);
ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32);
ENET_API int enet_host_check_events (ENetHost *, ENetEvent *);
ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
ENET_API void enet_host_flush (ENetHost *);
ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);
ENET_API void enet_host_compress (ENetHost *, const ENetCompressor *);
ENET_API int enet_host_compress_with_range_coder (ENetHost * host);
ENET_API void enet_host_channel_limit (ENetHost *, size_t);
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
extern void enet_host_bandwidth_throttle (ENetHost *);
ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
ENET_API void enet_peer_ping (ENetPeer *);
ENET_API void enet_peer_reset (ENetPeer *);
ENET_API void enet_peer_disconnect (ENetPeer *, enet_uint32);
ENET_API void enet_peer_disconnect_now (ENetPeer *, enet_uint32);
ENET_API void enet_peer_disconnect_later (ENetPeer *, enet_uint32);
ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
extern int enet_peer_throttle (ENetPeer *, enet_uint32);
extern void enet_peer_reset_queues (ENetPeer *);
extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *);
extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16);
extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32);
extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *);
extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *);
ENET_API void * enet_range_coder_create (void);
ENET_API void enet_range_coder_destroy (void *);
ENET_API size_t enet_range_coder_compress (void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t);
ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, enet_uint8 *, size_t);
extern size_t enet_protocol_command_size (enet_uint8);
#ifdef __cplusplus
}
#endif
#endif /* __ENET_ENET_H__ */

View File

@ -0,0 +1,43 @@
/**
@file list.h
@brief ENet list management
*/
#ifndef __ENET_LIST_H__
#define __ENET_LIST_H__
#include <stdlib.h>
typedef struct _ENetListNode
{
struct _ENetListNode * next;
struct _ENetListNode * previous;
} ENetListNode;
typedef ENetListNode * ENetListIterator;
typedef struct _ENetList
{
ENetListNode sentinel;
} ENetList;
extern void enet_list_clear (ENetList *);
extern ENetListIterator enet_list_insert (ENetListIterator, void *);
extern void * enet_list_remove (ENetListIterator);
extern ENetListIterator enet_list_move (ENetListIterator, void *, void *);
extern size_t enet_list_size (ENetList *);
#define enet_list_begin(list) ((list) -> sentinel.next)
#define enet_list_end(list) (& (list) -> sentinel)
#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list))
#define enet_list_next(iterator) ((iterator) -> next)
#define enet_list_previous(iterator) ((iterator) -> previous)
#define enet_list_front(list) ((void *) (list) -> sentinel.next)
#define enet_list_back(list) ((void *) (list) -> sentinel.previous)
#endif /* __ENET_LIST_H__ */

View File

@ -0,0 +1,196 @@
/**
@file protocol.h
@brief ENet protocol
*/
#ifndef __ENET_PROTOCOL_H__
#define __ENET_PROTOCOL_H__
#include "enet/types.h"
enum
{
ENET_PROTOCOL_MINIMUM_MTU = 576,
ENET_PROTOCOL_MAXIMUM_MTU = 4096,
ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768,
ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1,
ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255,
ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF
};
typedef enum _ENetProtocolCommand
{
ENET_PROTOCOL_COMMAND_NONE = 0,
ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1,
ENET_PROTOCOL_COMMAND_CONNECT = 2,
ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3,
ENET_PROTOCOL_COMMAND_DISCONNECT = 4,
ENET_PROTOCOL_COMMAND_PING = 5,
ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6,
ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7,
ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8,
ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9,
ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10,
ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
ENET_PROTOCOL_COMMAND_COUNT = 12,
ENET_PROTOCOL_COMMAND_MASK = 0x0F
} ENetProtocolCommand;
typedef enum _ENetProtocolFlag
{
ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14),
ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15),
ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME,
ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12),
ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12
} ENetProtocolFlag;
#ifdef _MSC_VER_
#pragma pack(push, 1)
#define ENET_PACKED
#elif defined(__GNUC__)
#define ENET_PACKED __attribute__ ((packed))
#else
#define ENET_PACKED
#endif
typedef struct _ENetProtocolHeader
{
enet_uint16 peerID;
enet_uint16 sentTime;
} ENET_PACKED ENetProtocolHeader;
typedef struct _ENetProtocolCommandHeader
{
enet_uint8 command;
enet_uint8 channelID;
enet_uint16 reliableSequenceNumber;
} ENET_PACKED ENetProtocolCommandHeader;
typedef struct _ENetProtocolAcknowledge
{
ENetProtocolCommandHeader header;
enet_uint16 receivedReliableSequenceNumber;
enet_uint16 receivedSentTime;
} ENET_PACKED ENetProtocolAcknowledge;
typedef struct _ENetProtocolConnect
{
ENetProtocolCommandHeader header;
enet_uint16 outgoingPeerID;
enet_uint8 incomingSessionID;
enet_uint8 outgoingSessionID;
enet_uint32 mtu;
enet_uint32 windowSize;
enet_uint32 channelCount;
enet_uint32 incomingBandwidth;
enet_uint32 outgoingBandwidth;
enet_uint32 packetThrottleInterval;
enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration;
enet_uint32 connectID;
enet_uint32 data;
} ENET_PACKED ENetProtocolConnect;
typedef struct _ENetProtocolVerifyConnect
{
ENetProtocolCommandHeader header;
enet_uint16 outgoingPeerID;
enet_uint8 incomingSessionID;
enet_uint8 outgoingSessionID;
enet_uint32 mtu;
enet_uint32 windowSize;
enet_uint32 channelCount;
enet_uint32 incomingBandwidth;
enet_uint32 outgoingBandwidth;
enet_uint32 packetThrottleInterval;
enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration;
enet_uint32 connectID;
} ENET_PACKED ENetProtocolVerifyConnect;
typedef struct _ENetProtocolBandwidthLimit
{
ENetProtocolCommandHeader header;
enet_uint32 incomingBandwidth;
enet_uint32 outgoingBandwidth;
} ENET_PACKED ENetProtocolBandwidthLimit;
typedef struct _ENetProtocolThrottleConfigure
{
ENetProtocolCommandHeader header;
enet_uint32 packetThrottleInterval;
enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration;
} ENET_PACKED ENetProtocolThrottleConfigure;
typedef struct _ENetProtocolDisconnect
{
ENetProtocolCommandHeader header;
enet_uint32 data;
} ENET_PACKED ENetProtocolDisconnect;
typedef struct _ENetProtocolPing
{
ENetProtocolCommandHeader header;
} ENET_PACKED ENetProtocolPing;
typedef struct _ENetProtocolSendReliable
{
ENetProtocolCommandHeader header;
enet_uint16 dataLength;
} ENET_PACKED ENetProtocolSendReliable;
typedef struct _ENetProtocolSendUnreliable
{
ENetProtocolCommandHeader header;
enet_uint16 unreliableSequenceNumber;
enet_uint16 dataLength;
} ENET_PACKED ENetProtocolSendUnreliable;
typedef struct _ENetProtocolSendUnsequenced
{
ENetProtocolCommandHeader header;
enet_uint16 unsequencedGroup;
enet_uint16 dataLength;
} ENET_PACKED ENetProtocolSendUnsequenced;
typedef struct _ENetProtocolSendFragment
{
ENetProtocolCommandHeader header;
enet_uint16 startSequenceNumber;
enet_uint16 dataLength;
enet_uint32 fragmentCount;
enet_uint32 fragmentNumber;
enet_uint32 totalLength;
enet_uint32 fragmentOffset;
} ENET_PACKED ENetProtocolSendFragment;
typedef union _ENetProtocol
{
ENetProtocolCommandHeader header;
ENetProtocolAcknowledge acknowledge;
ENetProtocolConnect connect;
ENetProtocolVerifyConnect verifyConnect;
ENetProtocolDisconnect disconnect;
ENetProtocolPing ping;
ENetProtocolSendReliable sendReliable;
ENetProtocolSendUnreliable sendUnreliable;
ENetProtocolSendUnsequenced sendUnsequenced;
ENetProtocolSendFragment sendFragment;
ENetProtocolBandwidthLimit bandwidthLimit;
ENetProtocolThrottleConfigure throttleConfigure;
} ENET_PACKED ENetProtocol;
#ifdef _MSC_VER_
#pragma pack(pop)
#endif
#endif /* __ENET_PROTOCOL_H__ */

View File

@ -0,0 +1,18 @@
/**
@file time.h
@brief ENet time constants and macros
*/
#ifndef __ENET_TIME_H__
#define __ENET_TIME_H__
#define ENET_TIME_OVERFLOW 86400000
#define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW)
#define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW)
#define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b))
#define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b))
#define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b))
#endif /* __ENET_TIME_H__ */

View File

@ -0,0 +1,13 @@
/**
@file types.h
@brief type definitions for ENet
*/
#ifndef __ENET_TYPES_H__
#define __ENET_TYPES_H__
typedef unsigned char enet_uint8; /**< unsigned 8-bit type */
typedef unsigned short enet_uint16; /**< unsigned 16-bit type */
typedef unsigned int enet_uint32; /**< unsigned 32-bit type */
#endif /* __ENET_TYPES_H__ */

View File

@ -0,0 +1,45 @@
/**
@file unix.h
@brief ENet Unix header
*/
#ifndef __ENET_UNIX_H__
#define __ENET_UNIX_H__
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
typedef int ENetSocket;
enum
{
ENET_SOCKET_NULL = -1
};
#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */
#define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */
#define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */
#define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */
typedef struct
{
void * data;
size_t dataLength;
} ENetBuffer;
#define ENET_CALLBACK
#define ENET_API extern
typedef fd_set ENetSocketSet;
#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
#endif /* __ENET_UNIX_H__ */

View File

@ -0,0 +1,12 @@
/**
@file utility.h
@brief ENet utility header
*/
#ifndef __ENET_UTILITY_H__
#define __ENET_UTILITY_H__
#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
#endif /* __ENET_UTILITY_H__ */

View File

@ -0,0 +1,58 @@
/**
@file win32.h
@brief ENet Win32 header
*/
#ifndef __ENET_WIN32_H__
#define __ENET_WIN32_H__
#ifdef ENET_BUILDING_LIB
#pragma warning (disable: 4996) // 'strncpy' was declared deprecated
#pragma warning (disable: 4267) // size_t to int conversion
#pragma warning (disable: 4244) // 64bit to 32bit int
#pragma warning (disable: 4018) // signed/unsigned mismatch
#endif
#include <stdlib.h>
#include <winsock2.h>
typedef SOCKET ENetSocket;
enum
{
ENET_SOCKET_NULL = INVALID_SOCKET
};
#define ENET_HOST_TO_NET_16(value) (htons (value))
#define ENET_HOST_TO_NET_32(value) (htonl (value))
#define ENET_NET_TO_HOST_16(value) (ntohs (value))
#define ENET_NET_TO_HOST_32(value) (ntohl (value))
typedef struct
{
size_t dataLength;
void * data;
} ENetBuffer;
#define ENET_CALLBACK __cdecl
#if defined ENET_DLL
#if defined ENET_BUILDING_LIB
#define ENET_API __declspec( dllexport )
#else
#define ENET_API __declspec( dllimport )
#endif /* ENET_BUILDING_LIB */
#else /* !ENET_DLL */
#define ENET_API extern
#endif /* ENET_DLL */
typedef fd_set ENetSocketSet;
#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
#endif /* __ENET_WIN32_H__ */

75
libs/enet/list.c Normal file
View File

@ -0,0 +1,75 @@
/**
@file list.c
@brief ENet linked list functions
*/
#define ENET_BUILDING_LIB 1
#include "enet/list.h"
/**
@defgroup list ENet linked list utility functions
@ingroup private
@{
*/
void
enet_list_clear (ENetList * list)
{
list -> sentinel.next = & list -> sentinel;
list -> sentinel.previous = & list -> sentinel;
}
ENetListIterator
enet_list_insert (ENetListIterator position, void * data)
{
ENetListIterator result = (ENetListIterator) data;
result -> previous = position -> previous;
result -> next = position;
result -> previous -> next = result;
position -> previous = result;
return result;
}
void *
enet_list_remove (ENetListIterator position)
{
position -> previous -> next = position -> next;
position -> next -> previous = position -> previous;
return position;
}
ENetListIterator
enet_list_move (ENetListIterator position, void * dataFirst, void * dataLast)
{
ENetListIterator first = (ENetListIterator) dataFirst,
last = (ENetListIterator) dataLast;
first -> previous -> next = last -> next;
last -> next -> previous = first -> previous;
first -> previous = position -> previous;
last -> next = position;
first -> previous -> next = first;
position -> previous = last;
return first;
}
size_t
enet_list_size (ENetList * list)
{
size_t size = 0;
ENetListIterator position;
for (position = enet_list_begin (list);
position != enet_list_end (list);
position = enet_list_next (position))
++ size;
return size;
}
/** @} */

157
libs/enet/packet.c Normal file
View File

@ -0,0 +1,157 @@
/**
@file packet.c
@brief ENet packet management functions
*/
#include <string.h>
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
/** @defgroup Packet ENet packet functions
@{
*/
/** Creates a packet that may be sent to a peer.
@param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL.
@param dataLength size of the data allocated for this packet
@param flags flags for this packet as described for the ENetPacket structure.
@returns the packet on success, NULL on failure
*/
ENetPacket *
enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
{
ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
if (packet == NULL)
return NULL;
if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
packet -> data = (enet_uint8 *) data;
else
{
packet -> data = (enet_uint8 *) enet_malloc (dataLength);
if (packet -> data == NULL)
{
enet_free (packet);
return NULL;
}
if (data != NULL)
memcpy (packet -> data, data, dataLength);
}
packet -> referenceCount = 0;
packet -> flags = flags;
packet -> dataLength = dataLength;
packet -> freeCallback = NULL;
return packet;
}
/** Destroys the packet and deallocates its data.
@param packet packet to be destroyed
*/
void
enet_packet_destroy (ENetPacket * packet)
{
if (packet -> freeCallback != NULL)
(* packet -> freeCallback) (packet);
if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
enet_free (packet -> data);
enet_free (packet);
}
/** Attempts to resize the data in the packet to length specified in the
dataLength parameter
@param packet packet to resize
@param dataLength new size for the packet data
@returns 0 on success, < 0 on failure
*/
int
enet_packet_resize (ENetPacket * packet, size_t dataLength)
{
enet_uint8 * newData;
if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
{
packet -> dataLength = dataLength;
return 0;
}
newData = (enet_uint8 *) enet_malloc (dataLength);
if (newData == NULL)
return -1;
memcpy (newData, packet -> data, packet -> dataLength);
enet_free (packet -> data);
packet -> data = newData;
packet -> dataLength = dataLength;
return 0;
}
static int initializedCRC32 = 0;
static enet_uint32 crcTable [256];
static enet_uint32
reflect_crc (int val, int bits)
{
int result = 0, bit;
for (bit = 0; bit < bits; bit ++)
{
if(val & 1) result |= 1 << (bits - 1 - bit);
val >>= 1;
}
return result;
}
static void
initialize_crc32 ()
{
int byte;
for (byte = 0; byte < 256; ++ byte)
{
enet_uint32 crc = reflect_crc (byte, 8) << 24;
int offset;
for(offset = 0; offset < 8; ++ offset)
{
if (crc & 0x80000000)
crc = (crc << 1) ^ 0x04c11db7;
else
crc <<= 1;
}
crcTable [byte] = reflect_crc (crc, 32);
}
initializedCRC32 = 1;
}
enet_uint32
enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
{
enet_uint32 crc = 0xFFFFFFFF;
if (! initializedCRC32) initialize_crc32 ();
while (bufferCount -- > 0)
{
const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
* dataEnd = & data [buffers -> dataLength];
while (data < dataEnd)
{
crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++];
}
++ buffers;
}
return ENET_HOST_TO_NET_32 (~ crc);
}
/** @} */

816
libs/enet/peer.c Normal file
View File

@ -0,0 +1,816 @@
/**
@file peer.c
@brief ENet peer management functions
*/
#include <string.h>
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
/** @defgroup peer ENet peer functions
@{
*/
/** Configures throttle parameter for a peer.
Unreliable packets are dropped by ENet in response to the varying conditions
of the Internet connection to the peer. The throttle represents a probability
that an unreliable packet should not be dropped and thus sent by ENet to the peer.
The lowest mean round trip time from the sending of a reliable packet to the
receipt of its acknowledgement is measured over an amount of time specified by
the interval parameter in milliseconds. If a measured round trip time happens to
be significantly less than the mean round trip time measured over the interval,
then the throttle probability is increased to allow more traffic by an amount
specified in the acceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE
constant. If a measured round trip time happens to be significantly greater than
the mean round trip time measured over the interval, then the throttle probability
is decreased to limit traffic by an amount specified in the deceleration parameter, which
is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant. When the throttle has
a value of ENET_PEER_PACKET_THROTTLE_SCALE, on unreliable packets are dropped by
ENet, and so 100% of all unreliable packets will be sent. When the throttle has a
value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable
packets will be sent. Intermediate values for the throttle represent intermediate
probabilities between 0% and 100% of unreliable packets being sent. The bandwidth
limits of the local and foreign hosts are taken into account to determine a
sensible limit for the throttle probability above which it should not raise even in
the best of conditions.
@param peer peer to configure
@param interval interval, in milliseconds, over which to measure lowest mean RTT; the default value is ENET_PEER_PACKET_THROTTLE_INTERVAL.
@param acceleration rate at which to increase the throttle probability as mean RTT declines
@param deceleration rate at which to decrease the throttle probability as mean RTT increases
*/
void
enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration)
{
ENetProtocol command;
peer -> packetThrottleInterval = interval;
peer -> packetThrottleAcceleration = acceleration;
peer -> packetThrottleDeceleration = deceleration;
command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF;
command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval);
command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration);
command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (deceleration);
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
}
int
enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
{
if (peer -> lastRoundTripTime <= peer -> lastRoundTripTimeVariance)
{
peer -> packetThrottle = peer -> packetThrottleLimit;
}
else
if (rtt < peer -> lastRoundTripTime)
{
peer -> packetThrottle += peer -> packetThrottleAcceleration;
if (peer -> packetThrottle > peer -> packetThrottleLimit)
peer -> packetThrottle = peer -> packetThrottleLimit;
return 1;
}
else
if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
{
if (peer -> packetThrottle > peer -> packetThrottleDeceleration)
peer -> packetThrottle -= peer -> packetThrottleDeceleration;
else
peer -> packetThrottle = 0;
return -1;
}
return 0;
}
/** Queues a packet to be sent.
@param peer destination for the packet
@param channelID channel on which to send
@param packet packet to send
@retval 0 on success
@retval < 0 on failure
*/
int
enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
{
ENetChannel * channel = & peer -> channels [channelID];
ENetProtocol command;
size_t fragmentLength;
if (peer -> state != ENET_PEER_STATE_CONNECTED ||
channelID >= peer -> channelCount)
return -1;
fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
if (packet -> dataLength > fragmentLength)
{
enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
fragmentNumber,
fragmentOffset;
ENetList fragments;
ENetOutgoingCommand * fragment;
enet_list_clear (& fragments);
for (fragmentNumber = 0,
fragmentOffset = 0;
fragmentOffset < packet -> dataLength;
++ fragmentNumber,
fragmentOffset += fragmentLength)
{
if (packet -> dataLength - fragmentOffset < fragmentLength)
fragmentLength = packet -> dataLength - fragmentOffset;
fragment = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
if (fragment == NULL)
{
while (! enet_list_empty (& fragments))
{
fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
enet_free (fragment);
}
return -1;
}
fragment -> fragmentOffset = fragmentOffset;
fragment -> fragmentLength = fragmentLength;
fragment -> packet = packet;
fragment -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
fragment -> command.header.channelID = channelID;
fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber;
fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
fragment -> command.sendFragment.fragmentCount = fragmentCount;
fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
enet_list_insert (enet_list_end (& fragments), fragment);
}
packet -> referenceCount += fragmentNumber;
while (! enet_list_empty (& fragments))
{
fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
enet_peer_setup_outgoing_command (peer, fragment);
}
return 0;
}
command.header.channelID = channelID;
if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
{
command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
}
else
if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED)
{
command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1);
command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
}
else
if (channel -> outgoingUnreliableSequenceNumber >= 0xFFFF)
{
command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
}
else
{
command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
}
if (enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength) == NULL)
return -1;
return 0;
}
/** Attempts to dequeue any incoming queued packet.
@param peer peer to dequeue packets from
@param channelID holds the channel ID of the channel the packet was received on success
@returns a pointer to the packet, or NULL if there are no available incoming queued packets
*/
ENetPacket *
enet_peer_receive (ENetPeer * peer, enet_uint8 * channelID)
{
ENetIncomingCommand * incomingCommand;
ENetPacket * packet;
if (enet_list_empty (& peer -> dispatchedCommands))
return NULL;
incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (& peer -> dispatchedCommands));
if (channelID != NULL)
* channelID = incomingCommand -> command.header.channelID;
packet = incomingCommand -> packet;
-- packet -> referenceCount;
if (incomingCommand -> fragments != NULL)
enet_free (incomingCommand -> fragments);
enet_free (incomingCommand);
return packet;
}
static void
enet_peer_reset_outgoing_commands (ENetList * queue)
{
ENetOutgoingCommand * outgoingCommand;
while (! enet_list_empty (queue))
{
outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue));
if (outgoingCommand -> packet != NULL)
{
-- outgoingCommand -> packet -> referenceCount;
if (outgoingCommand -> packet -> referenceCount == 0)
enet_packet_destroy (outgoingCommand -> packet);
}
enet_free (outgoingCommand);
}
}
static void
enet_peer_reset_incoming_commands (ENetList * queue)
{
ENetIncomingCommand * incomingCommand;
while (! enet_list_empty (queue))
{
incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue));
if (incomingCommand -> packet != NULL)
{
-- incomingCommand -> packet -> referenceCount;
if (incomingCommand -> packet -> referenceCount == 0)
enet_packet_destroy (incomingCommand -> packet);
}
if (incomingCommand -> fragments != NULL)
enet_free (incomingCommand -> fragments);
enet_free (incomingCommand);
}
}
void
enet_peer_reset_queues (ENetPeer * peer)
{
ENetChannel * channel;
if (peer -> needsDispatch)
{
enet_list_remove (& peer -> dispatchList);
peer -> needsDispatch = 0;
}
while (! enet_list_empty (& peer -> acknowledgements))
enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements)));
enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
if (peer -> channels != NULL && peer -> channelCount > 0)
{
for (channel = peer -> channels;
channel < & peer -> channels [peer -> channelCount];
++ channel)
{
enet_peer_reset_incoming_commands (& channel -> incomingReliableCommands);
enet_peer_reset_incoming_commands (& channel -> incomingUnreliableCommands);
}
enet_free (peer -> channels);
}
peer -> channels = NULL;
peer -> channelCount = 0;
}
/** Forcefully disconnects a peer.
@param peer peer to forcefully disconnect
@remarks The foreign host represented by the peer is not notified of the disconnection and will timeout
on its connection to the local host.
*/
void
enet_peer_reset (ENetPeer * peer)
{
peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID;
peer -> connectID = 0;
peer -> state = ENET_PEER_STATE_DISCONNECTED;
peer -> incomingBandwidth = 0;
peer -> outgoingBandwidth = 0;
peer -> incomingBandwidthThrottleEpoch = 0;
peer -> outgoingBandwidthThrottleEpoch = 0;
peer -> incomingDataTotal = 0;
peer -> outgoingDataTotal = 0;
peer -> lastSendTime = 0;
peer -> lastReceiveTime = 0;
peer -> nextTimeout = 0;
peer -> earliestTimeout = 0;
peer -> packetLossEpoch = 0;
peer -> packetsSent = 0;
peer -> packetsLost = 0;
peer -> packetLoss = 0;
peer -> packetLossVariance = 0;
peer -> packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE;
peer -> packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE;
peer -> packetThrottleCounter = 0;
peer -> packetThrottleEpoch = 0;
peer -> packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION;
peer -> packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION;
peer -> packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL;
peer -> lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
peer -> lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
peer -> lastRoundTripTimeVariance = 0;
peer -> highestRoundTripTimeVariance = 0;
peer -> roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
peer -> roundTripTimeVariance = 0;
peer -> mtu = peer -> host -> mtu;
peer -> reliableDataInTransit = 0;
peer -> outgoingReliableSequenceNumber = 0;
peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
peer -> incomingUnsequencedGroup = 0;
peer -> outgoingUnsequencedGroup = 0;
peer -> eventData = 0;
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
enet_peer_reset_queues (peer);
}
/** Sends a ping request to a peer.
@param peer destination for the ping request
@remarks ping requests factor into the mean round trip time as designated by the
roundTripTime field in the ENetPeer structure. Enet automatically pings all connected
peers at regular intervals, however, this function may be called to ensure more
frequent ping requests.
*/
void
enet_peer_ping (ENetPeer * peer)
{
ENetProtocol command;
if (peer -> state != ENET_PEER_STATE_CONNECTED)
return;
command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF;
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
}
/** Force an immediate disconnection from a peer.
@param peer peer to disconnect
@param data data describing the disconnection
@remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not
guarenteed to receive the disconnect notification, and is reset immediately upon
return from this function.
*/
void
enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data)
{
ENetProtocol command;
if (peer -> state == ENET_PEER_STATE_DISCONNECTED)
return;
if (peer -> state != ENET_PEER_STATE_ZOMBIE &&
peer -> state != ENET_PEER_STATE_DISCONNECTING)
{
enet_peer_reset_queues (peer);
command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
command.header.channelID = 0xFF;
command.disconnect.data = ENET_HOST_TO_NET_32 (data);
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
enet_host_flush (peer -> host);
}
enet_peer_reset (peer);
}
/** Request a disconnection from a peer.
@param peer peer to request a disconnection
@param data data describing the disconnection
@remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
once the disconnection is complete.
*/
void
enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
{
ENetProtocol command;
if (peer -> state == ENET_PEER_STATE_DISCONNECTING ||
peer -> state == ENET_PEER_STATE_DISCONNECTED ||
peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT ||
peer -> state == ENET_PEER_STATE_ZOMBIE)
return;
enet_peer_reset_queues (peer);
command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT;
command.header.channelID = 0xFF;
command.disconnect.data = ENET_HOST_TO_NET_32 (data);
if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
else
command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
peer -> state = ENET_PEER_STATE_DISCONNECTING;
else
{
enet_host_flush (peer -> host);
enet_peer_reset (peer);
}
}
/** Request a disconnection from a peer, but only after all queued outgoing packets are sent.
@param peer peer to request a disconnection
@param data data describing the disconnection
@remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
once the disconnection is complete.
*/
void
enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
{
if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) &&
! (enet_list_empty (& peer -> outgoingReliableCommands) &&
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
enet_list_empty (& peer -> sentReliableCommands)))
{
peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
peer -> eventData = data;
}
else
enet_peer_disconnect (peer, data);
}
ENetAcknowledgement *
enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint16 sentTime)
{
ENetAcknowledgement * acknowledgement;
if (command -> header.channelID < peer -> channelCount)
{
ENetChannel * channel = & peer -> channels [command -> header.channelID];
enet_uint16 reliableWindow = command -> header.reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE,
currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
if (reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1 && reliableWindow <= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS)
return NULL;
}
acknowledgement = (ENetAcknowledgement *) enet_malloc (sizeof (ENetAcknowledgement));
if (acknowledgement == NULL)
return NULL;
peer -> outgoingDataTotal += sizeof (ENetProtocolAcknowledge);
acknowledgement -> sentTime = sentTime;
acknowledgement -> command = * command;
enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement);
return acknowledgement;
}
void
enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand)
{
ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID];
peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength;
if (outgoingCommand -> command.header.channelID == 0xFF)
{
++ peer -> outgoingReliableSequenceNumber;
outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber;
outgoingCommand -> unreliableSequenceNumber = 0;
}
else
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
{
++ channel -> outgoingReliableSequenceNumber;
channel -> outgoingUnreliableSequenceNumber = 0;
outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
outgoingCommand -> unreliableSequenceNumber = 0;
}
else
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED)
{
++ peer -> outgoingUnsequencedGroup;
outgoingCommand -> reliableSequenceNumber = 0;
outgoingCommand -> unreliableSequenceNumber = 0;
}
else
{
++ channel -> outgoingUnreliableSequenceNumber;
outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber;
}
outgoingCommand -> sendAttempts = 0;
outgoingCommand -> sentTime = 0;
outgoingCommand -> roundTripTimeout = 0;
outgoingCommand -> roundTripTimeoutLimit = 0;
outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber);
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
else
enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
}
ENetOutgoingCommand *
enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 offset, enet_uint16 length)
{
ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
if (outgoingCommand == NULL)
return NULL;
outgoingCommand -> command = * command;
outgoingCommand -> fragmentOffset = offset;
outgoingCommand -> fragmentLength = length;
outgoingCommand -> packet = packet;
if (packet != NULL)
++ packet -> referenceCount;
enet_peer_setup_outgoing_command (peer, outgoingCommand);
return outgoingCommand;
}
void
enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel)
{
ENetListIterator currentCommand;
for (currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands);
currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
currentCommand = enet_list_next (currentCommand))
{
ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE &&
incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber)
break;
}
if (currentCommand == enet_list_begin (& channel -> incomingUnreliableCommands))
return;
enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingUnreliableCommands), enet_list_previous (currentCommand));
if (! peer -> needsDispatch)
{
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
peer -> needsDispatch = 1;
}
}
void
enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel)
{
ENetListIterator currentCommand;
for (currentCommand = enet_list_begin (& channel -> incomingReliableCommands);
currentCommand != enet_list_end (& channel -> incomingReliableCommands);
currentCommand = enet_list_next (currentCommand))
{
ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
if (incomingCommand -> fragmentsRemaining > 0 ||
incomingCommand -> reliableSequenceNumber != (enet_uint16) (channel -> incomingReliableSequenceNumber + 1))
break;
channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber;
if (incomingCommand -> fragmentCount > 0)
channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1;
}
if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands))
return;
enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand));
if (! peer -> needsDispatch)
{
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
peer -> needsDispatch = 1;
}
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
}
ENetIncomingCommand *
enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount)
{
static ENetIncomingCommand dummyCommand;
ENetChannel * channel = & peer -> channels [command -> header.channelID];
enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber;
enet_uint16 reliableWindow, currentWindow;
ENetIncomingCommand * incomingCommand;
ENetListIterator currentCommand;
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
goto freePacket;
if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED)
{
reliableSequenceNumber = command -> header.reliableSequenceNumber;
reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
goto freePacket;
}
switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
{
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber)
goto freePacket;
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
currentCommand != enet_list_end (& channel -> incomingReliableCommands);
currentCommand = enet_list_previous (currentCommand))
{
incomingCommand = (ENetIncomingCommand *) currentCommand;
if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
{
if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
continue;
}
else
if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
break;
if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber)
{
if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
break;
goto freePacket;
}
}
break;
case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber);
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
currentCommand = enet_list_previous (currentCommand))
{
incomingCommand = (ENetIncomingCommand *) currentCommand;
if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE)
continue;
if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
{
if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
continue;
}
else
if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
break;
if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
break;
if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber)
continue;
if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber)
{
if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber)
break;
goto freePacket;
}
}
break;
case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
currentCommand = enet_list_end (& channel -> incomingUnreliableCommands);
break;
default:
goto freePacket;
}
incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand));
if (incomingCommand == NULL)
goto notifyError;
incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber;
incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF;
incomingCommand -> command = * command;
incomingCommand -> fragmentCount = fragmentCount;
incomingCommand -> fragmentsRemaining = fragmentCount;
incomingCommand -> packet = packet;
incomingCommand -> fragments = NULL;
if (fragmentCount > 0)
{
incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32));
if (incomingCommand -> fragments == NULL)
{
enet_free (incomingCommand);
goto notifyError;
}
memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32));
}
if (packet != NULL)
++ packet -> referenceCount;
enet_list_insert (enet_list_next (currentCommand), incomingCommand);
switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
{
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
enet_peer_dispatch_incoming_reliable_commands (peer, channel);
break;
default:
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
break;
}
return incomingCommand;
freePacket:
if (fragmentCount > 0)
goto notifyError;
if (packet != NULL && packet -> referenceCount == 0)
enet_packet_destroy (packet);
return & dummyCommand;
notifyError:
if (packet != NULL && packet -> referenceCount == 0)
enet_packet_destroy (packet);
return NULL;
}
/** @} */

1671
libs/enet/protocol.c Normal file

File diff suppressed because it is too large Load Diff

439
libs/enet/unix.c Normal file
View File

@ -0,0 +1,439 @@
/**
@file unix.c
@brief ENet Unix system specific functions
*/
#ifndef WIN32
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#define HAS_SOCKLEN_T
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
#ifdef HAS_FCNTL
#include <fcntl.h>
#endif
#ifdef __APPLE__
#undef HAS_POLL
#endif
#ifdef HAS_POLL
#include <sys/poll.h>
#endif
#ifndef HAS_SOCKLEN_T
typedef int socklen_t;
#endif
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
static enet_uint32 timeBase = 0;
int
enet_initialize (void)
{
return 0;
}
void
enet_deinitialize (void)
{
}
enet_uint32
enet_time_get (void)
{
struct timeval timeVal;
gettimeofday (& timeVal, NULL);
return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
}
void
enet_time_set (enet_uint32 newTimeBase)
{
struct timeval timeVal;
gettimeofday (& timeVal, NULL);
timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
}
int
enet_address_set_host (ENetAddress * address, const char * name)
{
struct hostent * hostEntry = NULL;
#ifdef HAS_GETHOSTBYNAME_R
struct hostent hostData;
char buffer [2048];
int errnum;
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
#else
hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
#endif
#else
hostEntry = gethostbyname (name);
#endif
if (hostEntry == NULL ||
hostEntry -> h_addrtype != AF_INET)
{
#ifdef HAS_INET_PTON
if (! inet_pton (AF_INET, name, & address -> host))
#else
if (! inet_aton (name, (struct in_addr *) & address -> host))
#endif
return -1;
return 0;
}
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
return 0;
}
int
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
{
#ifdef HAS_INET_NTOP
if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
#else
char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
if (addr != NULL)
strncpy (name, addr, nameLength);
else
#endif
return -1;
return 0;
}
int
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
{
struct in_addr in;
struct hostent * hostEntry = NULL;
#ifdef HAS_GETHOSTBYADDR_R
struct hostent hostData;
char buffer [2048];
int errnum;
in.s_addr = address -> host;
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
#else
hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
#endif
#else
in.s_addr = address -> host;
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
#endif
if (hostEntry == NULL)
return enet_address_get_host_ip (address, name, nameLength);
strncpy (name, hostEntry -> h_name, nameLength);
return 0;
}
int
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
if (address != NULL)
{
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
}
else
{
sin.sin_port = 0;
sin.sin_addr.s_addr = INADDR_ANY;
}
return bind (socket,
(struct sockaddr *) & sin,
sizeof (struct sockaddr_in));
}
int
enet_socket_listen (ENetSocket socket, int backlog)
{
return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
}
ENetSocket
enet_socket_create (ENetSocketType type)
{
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
}
int
enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
{
int result = -1;
switch (option)
{
case ENET_SOCKOPT_NONBLOCK:
#ifdef HAS_FCNTL
result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL));
#else
result = ioctl (socket, FIONBIO, & value);
#endif
break;
case ENET_SOCKOPT_BROADCAST:
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_REUSEADDR:
result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_RCVBUF:
result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_SNDBUF:
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
break;
default:
break;
}
return result == -1 ? -1 : 0;
}
int
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
}
ENetSocket
enet_socket_accept (ENetSocket socket, ENetAddress * address)
{
int result;
struct sockaddr_in sin;
socklen_t sinLength = sizeof (struct sockaddr_in);
result = accept (socket,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL);
if (result == -1)
return ENET_SOCKET_NULL;
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
return result;
}
void
enet_socket_destroy (ENetSocket socket)
{
close (socket);
}
int
enet_socket_send (ENetSocket socket,
const ENetAddress * address,
const ENetBuffer * buffers,
size_t bufferCount)
{
struct msghdr msgHdr;
struct sockaddr_in sin;
int sentLength;
memset (& msgHdr, 0, sizeof (struct msghdr));
if (address != NULL)
{
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
msgHdr.msg_name = & sin;
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
}
msgHdr.msg_iov = (struct iovec *) buffers;
msgHdr.msg_iovlen = bufferCount;
sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
if (sentLength == -1)
{
if (errno == EWOULDBLOCK)
return 0;
return -1;
}
return sentLength;
}
int
enet_socket_receive (ENetSocket socket,
ENetAddress * address,
ENetBuffer * buffers,
size_t bufferCount)
{
struct msghdr msgHdr;
struct sockaddr_in sin;
int recvLength;
memset (& msgHdr, 0, sizeof (struct msghdr));
if (address != NULL)
{
msgHdr.msg_name = & sin;
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
}
msgHdr.msg_iov = (struct iovec *) buffers;
msgHdr.msg_iovlen = bufferCount;
recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
if (recvLength == -1)
{
if (errno == EWOULDBLOCK)
return 0;
return -1;
}
#ifdef HAS_MSGHDR_FLAGS
if (msgHdr.msg_flags & MSG_TRUNC)
return -1;
#endif
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
return recvLength;
}
int
enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
{
struct timeval timeVal;
timeVal.tv_sec = timeout / 1000;
timeVal.tv_usec = (timeout % 1000) * 1000;
return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
}
int
enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
{
#ifdef HAS_POLL
struct pollfd pollSocket;
int pollCount;
pollSocket.fd = socket;
pollSocket.events = 0;
if (* condition & ENET_SOCKET_WAIT_SEND)
pollSocket.events |= POLLOUT;
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
pollSocket.events |= POLLIN;
pollCount = poll (& pollSocket, 1, timeout);
if (pollCount < 0)
return -1;
* condition = ENET_SOCKET_WAIT_NONE;
if (pollCount == 0)
return 0;
if (pollSocket.revents & POLLOUT)
* condition |= ENET_SOCKET_WAIT_SEND;
if (pollSocket.revents & POLLIN)
* condition |= ENET_SOCKET_WAIT_RECEIVE;
return 0;
#else
fd_set readSet, writeSet;
struct timeval timeVal;
int selectCount;
timeVal.tv_sec = timeout / 1000;
timeVal.tv_usec = (timeout % 1000) * 1000;
FD_ZERO (& readSet);
FD_ZERO (& writeSet);
if (* condition & ENET_SOCKET_WAIT_SEND)
FD_SET (socket, & writeSet);
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
FD_SET (socket, & readSet);
selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
if (selectCount < 0)
return -1;
* condition = ENET_SOCKET_WAIT_NONE;
if (selectCount == 0)
return 0;
if (FD_ISSET (socket, & writeSet))
* condition |= ENET_SOCKET_WAIT_SEND;
if (FD_ISSET (socket, & readSet))
* condition |= ENET_SOCKET_WAIT_RECEIVE;
return 0;
#endif
}
#endif

348
libs/enet/win32.c Normal file
View File

@ -0,0 +1,348 @@
/**
@file win32.c
@brief ENet Win32 system specific functions
*/
#ifdef WIN32
#include <time.h>
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
static enet_uint32 timeBase = 0;
int
enet_initialize (void)
{
WORD versionRequested = MAKEWORD (1, 1);
WSADATA wsaData;
if (WSAStartup (versionRequested, & wsaData))
return -1;
if (LOBYTE (wsaData.wVersion) != 1||
HIBYTE (wsaData.wVersion) != 1)
{
WSACleanup ();
return -1;
}
timeBeginPeriod (1);
return 0;
}
void
enet_deinitialize (void)
{
timeEndPeriod (1);
WSACleanup ();
}
enet_uint32
enet_time_get (void)
{
return (enet_uint32) timeGetTime () - timeBase;
}
void
enet_time_set (enet_uint32 newTimeBase)
{
timeBase = (enet_uint32) timeGetTime () - newTimeBase;
}
int
enet_address_set_host (ENetAddress * address, const char * name)
{
struct hostent * hostEntry;
hostEntry = gethostbyname (name);
if (hostEntry == NULL ||
hostEntry -> h_addrtype != AF_INET)
{
unsigned long host = inet_addr (name);
if (host == INADDR_NONE)
return -1;
address -> host = host;
return 0;
}
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
return 0;
}
int
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
{
char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
if (addr == NULL)
return -1;
strncpy (name, addr, nameLength);
return 0;
}
int
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
{
struct in_addr in;
struct hostent * hostEntry;
in.s_addr = address -> host;
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
if (hostEntry == NULL)
return enet_address_get_host_ip (address, name, nameLength);
strncpy (name, hostEntry -> h_name, nameLength);
return 0;
}
int
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
if (address != NULL)
{
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
}
else
{
sin.sin_port = 0;
sin.sin_addr.s_addr = INADDR_ANY;
}
return bind (socket,
(struct sockaddr *) & sin,
sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
}
int
enet_socket_listen (ENetSocket socket, int backlog)
{
return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
}
ENetSocket
enet_socket_create (ENetSocketType type)
{
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
}
int
enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
{
int result = SOCKET_ERROR;
switch (option)
{
case ENET_SOCKOPT_NONBLOCK:
{
u_long nonBlocking = (u_long) value;
result = ioctlsocket (socket, FIONBIO, & nonBlocking);
break;
}
case ENET_SOCKOPT_BROADCAST:
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_REUSEADDR:
result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_RCVBUF:
result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_SNDBUF:
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
break;
default:
break;
}
return result == SOCKET_ERROR ? -1 : 0;
}
int
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
}
ENetSocket
enet_socket_accept (ENetSocket socket, ENetAddress * address)
{
SOCKET result;
struct sockaddr_in sin;
int sinLength = sizeof (struct sockaddr_in);
result = accept (socket,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL);
if (result == INVALID_SOCKET)
return ENET_SOCKET_NULL;
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
return result;
}
void
enet_socket_destroy (ENetSocket socket)
{
closesocket (socket);
}
int
enet_socket_send (ENetSocket socket,
const ENetAddress * address,
const ENetBuffer * buffers,
size_t bufferCount)
{
struct sockaddr_in sin;
DWORD sentLength;
if (address != NULL)
{
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
}
if (WSASendTo (socket,
(LPWSABUF) buffers,
(DWORD) bufferCount,
& sentLength,
0,
address != NULL ? (struct sockaddr *) & sin : 0,
address != NULL ? sizeof (struct sockaddr_in) : 0,
NULL,
NULL) == SOCKET_ERROR)
{
if (WSAGetLastError () == WSAEWOULDBLOCK)
return 0;
return -1;
}
return (int) sentLength;
}
int
enet_socket_receive (ENetSocket socket,
ENetAddress * address,
ENetBuffer * buffers,
size_t bufferCount)
{
INT sinLength = sizeof (struct sockaddr_in);
DWORD flags = 0,
recvLength;
struct sockaddr_in sin;
if (WSARecvFrom (socket,
(LPWSABUF) buffers,
(DWORD) bufferCount,
& recvLength,
& flags,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL,
NULL,
NULL) == SOCKET_ERROR)
{
switch (WSAGetLastError ())
{
case WSAEWOULDBLOCK:
case WSAECONNRESET:
return 0;
}
return -1;
}
if (flags & MSG_PARTIAL)
return -1;
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
return (int) recvLength;
}
int
enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
{
struct timeval timeVal;
timeVal.tv_sec = timeout / 1000;
timeVal.tv_usec = (timeout % 1000) * 1000;
return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
}
int
enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
{
fd_set readSet, writeSet;
struct timeval timeVal;
int selectCount;
timeVal.tv_sec = timeout / 1000;
timeVal.tv_usec = (timeout % 1000) * 1000;
FD_ZERO (& readSet);
FD_ZERO (& writeSet);
if (* condition & ENET_SOCKET_WAIT_SEND)
FD_SET (socket, & writeSet);
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
FD_SET (socket, & readSet);
selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
if (selectCount < 0)
return -1;
* condition = ENET_SOCKET_WAIT_NONE;
if (selectCount == 0)
return 0;
if (FD_ISSET (socket, & writeSet))
* condition |= ENET_SOCKET_WAIT_SEND;
if (FD_ISSET (socket, & readSet))
* condition |= ENET_SOCKET_WAIT_RECEIVE;
return 0;
}
#endif

60
libs/glfw/CMakeLists.txt Normal file
View File

@ -0,0 +1,60 @@
include_directories (include)
include_directories (lib)
SET(commonSources
lib/enable.c
lib/fullscreen.c
lib/glext.c
lib/image.c
lib/init.c
lib/input.c
lib/joystick.c
lib/stream.c
lib/tga.c
lib/thread.c
lib/time.c
lib/window.c
)
IF(APPLE)
SET(platformSources
lib/macosx/macosx_enable.c
lib/macosx/macosx_fullscreen.c
lib/macosx/macosx_glext.c
lib/macosx/macosx_init.c
lib/macosx/macosx_joystick.c
lib/macosx/macosx_thread.c
lib/macosx/macosx_time.c
lib/macosx/macosx_window.c
)
include_directories (lib/macosx)
ELSE()
IF(WIN32)
SET(platformSources
lib/win32/win32_dllmain.c
lib/win32/win32_enable.c
lib/win32/win32_fullscreen.c
lib/win32/win32_glext.c
lib/win32/win32_init.c
lib/win32/win32_joystick.c
lib/win32/win32_thread.c
lib/win32/win32_time.c
lib/win32/win32_window.c
)
include_directories (lib/win32)
ELSE()
SET(platformSources
lib/x11/x11_enable.c
lib/x11/x11_fullscreen.c
lib/x11/x11_glext.c
lib/x11/x11_init.c
lib/x11/x11_joystick.c
lib/x11/x11_keysym2unicode.c
lib/x11/x11_thread.c
lib/x11/x11_time.c
lib/x11/x11_window.c
)
include_directories (lib/x11)
add_definitions(-D_GLFW_HAS_PTHREAD)
ENDIF()
ENDIF()
add_library (glfw ${commonSources} ${platformSources})

486
libs/glfw/include/GL/glfw.h Normal file
View File

@ -0,0 +1,486 @@
//========================================================================
// GLFW - An OpenGL framework
// File: glfw.h
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef __glfw_h_
#define __glfw_h_
#ifdef __cplusplus
extern "C" {
#endif
//========================================================================
// Global definitions
//========================================================================
// We need a NULL pointer from time to time
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif // NULL
// ------------------- BEGIN SYSTEM/COMPILER SPECIFIC --------------------
// Please report any probles that you find with your compiler, which may
// be solved in this section! There are several compilers that I have not
// been able to test this file with yet.
// First: If we are we on Windows, we want a single define for it (_WIN32)
// (Note: For Cygwin the compiler flag -mwin32 should be used, but to
// make sure that things run smoothly for Cygwin users, we add __CYGWIN__
// to the list of "valid Win32 identifiers", which removes the need for
// -mwin32)
#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__))
#define _WIN32
#endif // _WIN32
// In order for extension support to be portable, we need to define an
// OpenGL function call method. We use the keyword APIENTRY, which is
// defined for Win32. (Note: Windows also needs this for <GL/gl.h>)
#ifndef APIENTRY
#ifdef _WIN32
#define APIENTRY __stdcall
#else
#define APIENTRY
#endif
#define GL_APIENTRY_DEFINED
#endif // APIENTRY
// The following three defines are here solely to make some Windows-based
// <GL/gl.h> files happy. Theoretically we could include <windows.h>, but
// it has the major drawback of severely polluting our namespace.
// Under Windows, we need WINGDIAPI defined
#if !defined(WINGDIAPI) && defined(_WIN32)
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)
// Microsoft Visual C++, Borland C++ Builder and Pelles C
#define WINGDIAPI __declspec(dllimport)
#elif defined(__LCC__)
// LCC-Win32
#define WINGDIAPI __stdcall
#else
// Others (e.g. MinGW, Cygwin)
#define WINGDIAPI extern
#endif
#define GL_WINGDIAPI_DEFINED
#endif // WINGDIAPI
// Some <GL/glu.h> files also need CALLBACK defined
#if !defined(CALLBACK) && defined(_WIN32)
#if defined(_MSC_VER)
// Microsoft Visual C++
#if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS)
#define CALLBACK __stdcall
#else
#define CALLBACK
#endif
#else
// Other Windows compilers
#define CALLBACK __stdcall
#endif
#define GLU_CALLBACK_DEFINED
#endif // CALLBACK
// Microsoft Visual C++, Borland C++ and Pelles C <GL/glu.h> needs wchar_t
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)) && !defined(_WCHAR_T_DEFINED)
typedef unsigned short wchar_t;
#define _WCHAR_T_DEFINED
#endif // _WCHAR_T_DEFINED
// ---------------- GLFW related system specific defines -----------------
#if defined(_WIN32) && defined(GLFW_BUILD_DLL)
// We are building a Win32 DLL
#define GLFWAPI __declspec(dllexport)
#define GLFWAPIENTRY __stdcall
#define GLFWCALL __stdcall
#elif defined(_WIN32) && defined(GLFW_DLL)
// We are calling a Win32 DLL
#if defined(__LCC__)
#define GLFWAPI extern
#else
#define GLFWAPI __declspec(dllimport)
#endif
#define GLFWAPIENTRY __stdcall
#define GLFWCALL __stdcall
#else
// We are either building/calling a static lib or we are non-win32
#define GLFWAPIENTRY
#define GLFWAPI
#define GLFWCALL
#endif
// -------------------- END SYSTEM/COMPILER SPECIFIC ---------------------
// Include standard OpenGL headers: GLFW uses GL_FALSE/GL_TRUE, and it is
// convenient for the user to only have to include <GL/glfw.h>. This also
// solves the problem with Windows <GL/gl.h> and <GL/glu.h> needing some
// special defines which normally requires the user to include <windows.h>
// (which is not a nice solution for portable programs).
#if defined(__APPLE_CC__)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
//========================================================================
// GLFW version
//========================================================================
#define GLFW_VERSION_MAJOR 2
#define GLFW_VERSION_MINOR 6
#define GLFW_VERSION_REVISION 0
//========================================================================
// Input handling definitions
//========================================================================
// Key and button state/action definitions
#define GLFW_RELEASE 0
#define GLFW_PRESS 1
// Keyboard key definitions: 8-bit ISO-8859-1 (Latin 1) encoding is used
// for printable keys (such as A-Z, 0-9 etc), and values above 256
// represent special (non-printable) keys (e.g. F1, Page Up etc).
#define GLFW_KEY_UNKNOWN -1
#define GLFW_KEY_SPACE 32
#define GLFW_KEY_SPECIAL 256
#define GLFW_KEY_ESC (GLFW_KEY_SPECIAL+1)
#define GLFW_KEY_F1 (GLFW_KEY_SPECIAL+2)
#define GLFW_KEY_F2 (GLFW_KEY_SPECIAL+3)
#define GLFW_KEY_F3 (GLFW_KEY_SPECIAL+4)
#define GLFW_KEY_F4 (GLFW_KEY_SPECIAL+5)
#define GLFW_KEY_F5 (GLFW_KEY_SPECIAL+6)
#define GLFW_KEY_F6 (GLFW_KEY_SPECIAL+7)
#define GLFW_KEY_F7 (GLFW_KEY_SPECIAL+8)
#define GLFW_KEY_F8 (GLFW_KEY_SPECIAL+9)
#define GLFW_KEY_F9 (GLFW_KEY_SPECIAL+10)
#define GLFW_KEY_F10 (GLFW_KEY_SPECIAL+11)
#define GLFW_KEY_F11 (GLFW_KEY_SPECIAL+12)
#define GLFW_KEY_F12 (GLFW_KEY_SPECIAL+13)
#define GLFW_KEY_F13 (GLFW_KEY_SPECIAL+14)
#define GLFW_KEY_F14 (GLFW_KEY_SPECIAL+15)
#define GLFW_KEY_F15 (GLFW_KEY_SPECIAL+16)
#define GLFW_KEY_F16 (GLFW_KEY_SPECIAL+17)
#define GLFW_KEY_F17 (GLFW_KEY_SPECIAL+18)
#define GLFW_KEY_F18 (GLFW_KEY_SPECIAL+19)
#define GLFW_KEY_F19 (GLFW_KEY_SPECIAL+20)
#define GLFW_KEY_F20 (GLFW_KEY_SPECIAL+21)
#define GLFW_KEY_F21 (GLFW_KEY_SPECIAL+22)
#define GLFW_KEY_F22 (GLFW_KEY_SPECIAL+23)
#define GLFW_KEY_F23 (GLFW_KEY_SPECIAL+24)
#define GLFW_KEY_F24 (GLFW_KEY_SPECIAL+25)
#define GLFW_KEY_F25 (GLFW_KEY_SPECIAL+26)
#define GLFW_KEY_UP (GLFW_KEY_SPECIAL+27)
#define GLFW_KEY_DOWN (GLFW_KEY_SPECIAL+28)
#define GLFW_KEY_LEFT (GLFW_KEY_SPECIAL+29)
#define GLFW_KEY_RIGHT (GLFW_KEY_SPECIAL+30)
#define GLFW_KEY_LSHIFT (GLFW_KEY_SPECIAL+31)
#define GLFW_KEY_RSHIFT (GLFW_KEY_SPECIAL+32)
#define GLFW_KEY_LCTRL (GLFW_KEY_SPECIAL+33)
#define GLFW_KEY_RCTRL (GLFW_KEY_SPECIAL+34)
#define GLFW_KEY_LALT (GLFW_KEY_SPECIAL+35)
#define GLFW_KEY_RALT (GLFW_KEY_SPECIAL+36)
#define GLFW_KEY_TAB (GLFW_KEY_SPECIAL+37)
#define GLFW_KEY_ENTER (GLFW_KEY_SPECIAL+38)
#define GLFW_KEY_BACKSPACE (GLFW_KEY_SPECIAL+39)
#define GLFW_KEY_INSERT (GLFW_KEY_SPECIAL+40)
#define GLFW_KEY_DEL (GLFW_KEY_SPECIAL+41)
#define GLFW_KEY_PAGEUP (GLFW_KEY_SPECIAL+42)
#define GLFW_KEY_PAGEDOWN (GLFW_KEY_SPECIAL+43)
#define GLFW_KEY_HOME (GLFW_KEY_SPECIAL+44)
#define GLFW_KEY_END (GLFW_KEY_SPECIAL+45)
#define GLFW_KEY_KP_0 (GLFW_KEY_SPECIAL+46)
#define GLFW_KEY_KP_1 (GLFW_KEY_SPECIAL+47)
#define GLFW_KEY_KP_2 (GLFW_KEY_SPECIAL+48)
#define GLFW_KEY_KP_3 (GLFW_KEY_SPECIAL+49)
#define GLFW_KEY_KP_4 (GLFW_KEY_SPECIAL+50)
#define GLFW_KEY_KP_5 (GLFW_KEY_SPECIAL+51)
#define GLFW_KEY_KP_6 (GLFW_KEY_SPECIAL+52)
#define GLFW_KEY_KP_7 (GLFW_KEY_SPECIAL+53)
#define GLFW_KEY_KP_8 (GLFW_KEY_SPECIAL+54)
#define GLFW_KEY_KP_9 (GLFW_KEY_SPECIAL+55)
#define GLFW_KEY_KP_DIVIDE (GLFW_KEY_SPECIAL+56)
#define GLFW_KEY_KP_MULTIPLY (GLFW_KEY_SPECIAL+57)
#define GLFW_KEY_KP_SUBTRACT (GLFW_KEY_SPECIAL+58)
#define GLFW_KEY_KP_ADD (GLFW_KEY_SPECIAL+59)
#define GLFW_KEY_KP_DECIMAL (GLFW_KEY_SPECIAL+60)
#define GLFW_KEY_KP_EQUAL (GLFW_KEY_SPECIAL+61)
#define GLFW_KEY_KP_ENTER (GLFW_KEY_SPECIAL+62)
#define GLFW_KEY_LAST GLFW_KEY_KP_ENTER
// Mouse button definitions
#define GLFW_MOUSE_BUTTON_1 0
#define GLFW_MOUSE_BUTTON_2 1
#define GLFW_MOUSE_BUTTON_3 2
#define GLFW_MOUSE_BUTTON_4 3
#define GLFW_MOUSE_BUTTON_5 4
#define GLFW_MOUSE_BUTTON_6 5
#define GLFW_MOUSE_BUTTON_7 6
#define GLFW_MOUSE_BUTTON_8 7
#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8
// Mouse button aliases
#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1
#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2
#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3
// Joystick identifiers
#define GLFW_JOYSTICK_1 0
#define GLFW_JOYSTICK_2 1
#define GLFW_JOYSTICK_3 2
#define GLFW_JOYSTICK_4 3
#define GLFW_JOYSTICK_5 4
#define GLFW_JOYSTICK_6 5
#define GLFW_JOYSTICK_7 6
#define GLFW_JOYSTICK_8 7
#define GLFW_JOYSTICK_9 8
#define GLFW_JOYSTICK_10 9
#define GLFW_JOYSTICK_11 10
#define GLFW_JOYSTICK_12 11
#define GLFW_JOYSTICK_13 12
#define GLFW_JOYSTICK_14 13
#define GLFW_JOYSTICK_15 14
#define GLFW_JOYSTICK_16 15
#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16
//========================================================================
// Other definitions
//========================================================================
// glfwOpenWindow modes
#define GLFW_WINDOW 0x00010001
#define GLFW_FULLSCREEN 0x00010002
// glfwGetWindowParam tokens
#define GLFW_OPENED 0x00020001
#define GLFW_ACTIVE 0x00020002
#define GLFW_ICONIFIED 0x00020003
#define GLFW_ACCELERATED 0x00020004
#define GLFW_RED_BITS 0x00020005
#define GLFW_GREEN_BITS 0x00020006
#define GLFW_BLUE_BITS 0x00020007
#define GLFW_ALPHA_BITS 0x00020008
#define GLFW_DEPTH_BITS 0x00020009
#define GLFW_STENCIL_BITS 0x0002000A
// The following constants are used for both glfwGetWindowParam
// and glfwOpenWindowHint
#define GLFW_REFRESH_RATE 0x0002000B
#define GLFW_ACCUM_RED_BITS 0x0002000C
#define GLFW_ACCUM_GREEN_BITS 0x0002000D
#define GLFW_ACCUM_BLUE_BITS 0x0002000E
#define GLFW_ACCUM_ALPHA_BITS 0x0002000F
#define GLFW_AUX_BUFFERS 0x00020010
#define GLFW_STEREO 0x00020011
#define GLFW_WINDOW_NO_RESIZE 0x00020012
#define GLFW_FSAA_SAMPLES 0x00020013
// glfwEnable/glfwDisable tokens
#define GLFW_MOUSE_CURSOR 0x00030001
#define GLFW_STICKY_KEYS 0x00030002
#define GLFW_STICKY_MOUSE_BUTTONS 0x00030003
#define GLFW_SYSTEM_KEYS 0x00030004
#define GLFW_KEY_REPEAT 0x00030005
#define GLFW_AUTO_POLL_EVENTS 0x00030006
// glfwWaitThread wait modes
#define GLFW_WAIT 0x00040001
#define GLFW_NOWAIT 0x00040002
// glfwGetJoystickParam tokens
#define GLFW_PRESENT 0x00050001
#define GLFW_AXES 0x00050002
#define GLFW_BUTTONS 0x00050003
// glfwReadImage/glfwLoadTexture2D flags
#define GLFW_NO_RESCALE_BIT 0x00000001 // Only for glfwReadImage
#define GLFW_ORIGIN_UL_BIT 0x00000002
#define GLFW_BUILD_MIPMAPS_BIT 0x00000004 // Only for glfwLoadTexture2D
#define GLFW_ALPHA_MAP_BIT 0x00000008
// Time spans longer than this (seconds) are considered to be infinity
#define GLFW_INFINITY 100000.0
//========================================================================
// Typedefs
//========================================================================
// The video mode structure used by glfwGetVideoModes()
typedef struct {
int Width, Height;
int RedBits, BlueBits, GreenBits;
} GLFWvidmode;
// Image/texture information
typedef struct {
int Width, Height;
int Format;
int BytesPerPixel;
unsigned char *Data;
} GLFWimage;
// Thread ID
typedef int GLFWthread;
// Mutex object
typedef void * GLFWmutex;
// Condition variable object
typedef void * GLFWcond;
// Function pointer types
typedef void (GLFWCALL * GLFWwindowsizefun)(int,int);
typedef int (GLFWCALL * GLFWwindowclosefun)(void);
typedef void (GLFWCALL * GLFWwindowrefreshfun)(void);
typedef void (GLFWCALL * GLFWmousebuttonfun)(int,int);
typedef void (GLFWCALL * GLFWmouseposfun)(int,int);
typedef void (GLFWCALL * GLFWmousewheelfun)(int);
typedef void (GLFWCALL * GLFWkeyfun)(int,int);
typedef void (GLFWCALL * GLFWcharfun)(int,int);
typedef void (GLFWCALL * GLFWthreadfun)(void *);
//========================================================================
// Prototypes
//========================================================================
/*! @file glfw.h
*/
// GLFW initialization, termination and version querying
/*! @fn glfwInit
*/
GLFWAPI int GLFWAPIENTRY glfwInit( void );
GLFWAPI void GLFWAPIENTRY glfwTerminate( void );
GLFWAPI void GLFWAPIENTRY glfwGetVersion( int *major, int *minor, int *rev );
// Window handling
GLFWAPI int GLFWAPIENTRY glfwOpenWindow( int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int mode );
GLFWAPI void GLFWAPIENTRY glfwOpenWindowHint( int target, int hint );
GLFWAPI void GLFWAPIENTRY glfwCloseWindow( void );
GLFWAPI void GLFWAPIENTRY glfwSetWindowTitle( const char *title );
GLFWAPI void GLFWAPIENTRY glfwGetWindowSize( int *width, int *height );
GLFWAPI void GLFWAPIENTRY glfwSetWindowSize( int width, int height );
GLFWAPI void GLFWAPIENTRY glfwSetWindowPos( int x, int y );
GLFWAPI void GLFWAPIENTRY glfwIconifyWindow( void );
GLFWAPI void GLFWAPIENTRY glfwRestoreWindow( void );
GLFWAPI void GLFWAPIENTRY glfwSwapBuffers( void );
GLFWAPI void GLFWAPIENTRY glfwSwapInterval( int interval );
GLFWAPI int GLFWAPIENTRY glfwGetWindowParam( int param );
GLFWAPI void GLFWAPIENTRY glfwSetWindowSizeCallback( GLFWwindowsizefun cbfun );
GLFWAPI void GLFWAPIENTRY glfwSetWindowCloseCallback( GLFWwindowclosefun cbfun );
GLFWAPI void GLFWAPIENTRY glfwSetWindowRefreshCallback( GLFWwindowrefreshfun cbfun );
// Video mode functions
GLFWAPI int GLFWAPIENTRY glfwGetVideoModes( GLFWvidmode *list, int maxcount );
GLFWAPI void GLFWAPIENTRY glfwGetDesktopMode( GLFWvidmode *mode );
// Input handling
GLFWAPI void GLFWAPIENTRY glfwPollEvents( void );
GLFWAPI void GLFWAPIENTRY glfwWaitEvents( void );
GLFWAPI int GLFWAPIENTRY glfwGetKey( int key );
GLFWAPI int GLFWAPIENTRY glfwGetMouseButton( int button );
GLFWAPI void GLFWAPIENTRY glfwGetMousePos( int *xpos, int *ypos );
GLFWAPI void GLFWAPIENTRY glfwSetMousePos( int xpos, int ypos );
GLFWAPI int GLFWAPIENTRY glfwGetMouseWheel( void );
GLFWAPI void GLFWAPIENTRY glfwSetMouseWheel( int pos );
GLFWAPI void GLFWAPIENTRY glfwSetKeyCallback( GLFWkeyfun cbfun );
GLFWAPI void GLFWAPIENTRY glfwSetCharCallback( GLFWcharfun cbfun );
GLFWAPI void GLFWAPIENTRY glfwSetMouseButtonCallback( GLFWmousebuttonfun cbfun );
GLFWAPI void GLFWAPIENTRY glfwSetMousePosCallback( GLFWmouseposfun cbfun );
GLFWAPI void GLFWAPIENTRY glfwSetMouseWheelCallback( GLFWmousewheelfun cbfun );
// Joystick input
GLFWAPI int GLFWAPIENTRY glfwGetJoystickParam( int joy, int param );
GLFWAPI int GLFWAPIENTRY glfwGetJoystickPos( int joy, float *pos, int numaxes );
GLFWAPI int GLFWAPIENTRY glfwGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons );
// Time
GLFWAPI double GLFWAPIENTRY glfwGetTime( void );
GLFWAPI void GLFWAPIENTRY glfwSetTime( double time );
GLFWAPI void GLFWAPIENTRY glfwSleep( double time );
// Extension support
GLFWAPI int GLFWAPIENTRY glfwExtensionSupported( const char *extension );
GLFWAPI void* GLFWAPIENTRY glfwGetProcAddress( const char *procname );
GLFWAPI void GLFWAPIENTRY glfwGetGLVersion( int *major, int *minor, int *rev );
// Threading support
GLFWAPI GLFWthread GLFWAPIENTRY glfwCreateThread( GLFWthreadfun fun, void *arg );
GLFWAPI void GLFWAPIENTRY glfwDestroyThread( GLFWthread ID );
GLFWAPI int GLFWAPIENTRY glfwWaitThread( GLFWthread ID, int waitmode );
GLFWAPI GLFWthread GLFWAPIENTRY glfwGetThreadID( void );
GLFWAPI GLFWmutex GLFWAPIENTRY glfwCreateMutex( void );
GLFWAPI void GLFWAPIENTRY glfwDestroyMutex( GLFWmutex mutex );
GLFWAPI void GLFWAPIENTRY glfwLockMutex( GLFWmutex mutex );
GLFWAPI void GLFWAPIENTRY glfwUnlockMutex( GLFWmutex mutex );
GLFWAPI GLFWcond GLFWAPIENTRY glfwCreateCond( void );
GLFWAPI void GLFWAPIENTRY glfwDestroyCond( GLFWcond cond );
GLFWAPI void GLFWAPIENTRY glfwWaitCond( GLFWcond cond, GLFWmutex mutex, double timeout );
GLFWAPI void GLFWAPIENTRY glfwSignalCond( GLFWcond cond );
GLFWAPI void GLFWAPIENTRY glfwBroadcastCond( GLFWcond cond );
GLFWAPI int GLFWAPIENTRY glfwGetNumberOfProcessors( void );
// Enable/disable functions
GLFWAPI void GLFWAPIENTRY glfwEnable( int token );
GLFWAPI void GLFWAPIENTRY glfwDisable( int token );
// Image/texture I/O support
GLFWAPI int GLFWAPIENTRY glfwReadImage( const char *name, GLFWimage *img, int flags );
GLFWAPI int GLFWAPIENTRY glfwReadMemoryImage( const void *data, long size, GLFWimage *img, int flags );
GLFWAPI void GLFWAPIENTRY glfwFreeImage( GLFWimage *img );
GLFWAPI int GLFWAPIENTRY glfwLoadTexture2D( const char *name, int flags );
GLFWAPI int GLFWAPIENTRY glfwLoadMemoryTexture2D( const void *data, long size, int flags );
GLFWAPI int GLFWAPIENTRY glfwLoadTextureImage2D( GLFWimage *img, int flags );
#ifdef __cplusplus
}
#endif
#endif // __glfw_h_

View File

@ -0,0 +1,128 @@
##########################################################################
# Makefile for GLFW on AmigaOS using GCC.
#-------------------------------------------------------------------------
# To compile GLFW using this makefile, run:
# make -f Makefile.amigaos.gcc
##########################################################################
##########################################################################
# Default: Build static library version of GLFW
##########################################################################
default: libglfw.a
##########################################################################
# GLFW version
##########################################################################
VERMAJOR = 2
VERMINOR = 4
##########################################################################
# Compiler settings
##########################################################################
CC = gcc
CFLAGS = -c -I. -I.. -Wall -Os -m68020 -m68881
# Some modules should be optimized for speed (e.g. image decoding)
CFLAGS_SPEED = -c -I. -I.. -Wall -O3 -ffast-math -m68020 -m68881
##########################################################################
# Library builder settings
##########################################################################
MKLIB = ar
LIBFLAGS = -rcs
##########################################################################
# Object files which are part of the GLFW library
##########################################################################
OBJS = \
enable.o \
fullscreen.o \
glext.o \
image.o \
init.o \
input.o \
joystick.o \
tga.o \
thread.o \
time.o \
window.o \
amigaos_enable.o \
amigaos_fullscreen.o \
amigaos_glext.o \
amigaos_init.o \
amigaos_joystick.o \
amigaos_thread.o \
amigaos_time.o \
amigaos_window.o
##########################################################################
# Rule for building library
##########################################################################
libglfw.a: $(OBJS)
$(MKLIB) $(LIBFLAGS) $@ $(OBJS)
##########################################################################
# Rules for building library object files
##########################################################################
enable.o: ../enable.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../enable.c
fullscreen.o: ../fullscreen.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../fullscreen.c
glext.o: ../glext.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../glext.c
image.o: ../image.c ../internal.h platform.h
$(CC) $(CFLAGS_SPEED) -o $@ ../image.c
init.o: ../init.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../init.c
input.o: ../input.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../input.c
joystick.o: ../joystick.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../joystick.c
tga.o: ../tga.c ../internal.h platform.h
$(CC) $(CFLAGS_SPEED) -o $@ ../tga.c
thread.o: ../thread.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../thread.c
time.o: ../time.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../time.c
window.o: ../window.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../window.c
amigaos_enable.o: amigaos_enable.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_enable.c
amigaos_fullscreen.o: amigaos_fullscreen.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_fullscreen.c
amigaos_glext.o: amigaos_glext.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_glext.c
amigaos_init.o: amigaos_init.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_init.c
amigaos_joystick.o: amigaos_joystick.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_joystick.c
amigaos_thread.o: amigaos_thread.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_thread.c
amigaos_time.o: amigaos_time.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_time.c
amigaos_window.o: amigaos_window.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_window.c

View File

@ -0,0 +1,128 @@
##########################################################################
# Makefile for GLFW on AmigaOS using VBCC.
#-------------------------------------------------------------------------
# To compile GLFW using this makefile, run:
# make -f Makefile.amigaos.vbcc
##########################################################################
##########################################################################
# Default: Build static library version of GLFW
##########################################################################
default: glfw.lib
##########################################################################
# GLFW version
##########################################################################
VERMAJOR = 2
VERMINOR = 4
##########################################################################
# Compiler settings
##########################################################################
CC = vc
CFLAGS = -c -I. -I/ -c99 -cpu=68020 -fpu=68881 -O1
# Some modules should be optimized for speed (e.g. image decoding)
CFLAGS_SPEED = -c -I. -I/ -c99 -cpu=68020 -fpu=68881 -O1
##########################################################################
# Library builder settings
##########################################################################
MKLIB = join
LIBFLAGS = as
##########################################################################
# Object files which are part of the GLFW library
##########################################################################
OBJS = \
enable.o \
fullscreen.o \
glext.o \
image.o \
init.o \
input.o \
joystick.o \
tga.o \
thread.o \
time.o \
window.o \
amigaos_enable.o \
amigaos_fullscreen.o \
amigaos_glext.o \
amigaos_init.o \
amigaos_joystick.o \
amigaos_thread.o \
amigaos_time.o \
amigaos_window.o
##########################################################################
# Rule for building library
##########################################################################
glfw.lib: $(OBJS)
$(MKLIB) $(OBJS) $(LIBFLAGS) $@
##########################################################################
# Rules for building library object files
##########################################################################
enable.o: /enable.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ /enable.c
fullscreen.o: /fullscreen.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ /fullscreen.c
glext.o: /glext.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ /glext.c
image.o: /image.c /internal.h platform.h
$(CC) $(CFLAGS_SPEED) -o $@ /image.c
init.o: /init.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ /init.c
input.o: /input.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ /input.c
joystick.o: /joystick.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ /joystick.c
tga.o: /tga.c /internal.h platform.h
$(CC) $(CFLAGS_SPEED) -o $@ /tga.c
thread.o: /thread.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ /thread.c
time.o: /time.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ /time.c
window.o: /window.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ /window.c
amigaos_enable.o: amigaos_enable.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_enable.c
amigaos_fullscreen.o: amigaos_fullscreen.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_fullscreen.c
amigaos_glext.o: amigaos_glext.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_glext.c
amigaos_init.o: amigaos_init.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_init.c
amigaos_joystick.o: amigaos_joystick.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_joystick.c
amigaos_thread.o: amigaos_thread.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_thread.c
amigaos_time.o: amigaos_time.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_time.c
amigaos_window.o: amigaos_window.c /internal.h platform.h
$(CC) $(CFLAGS) -o $@ amigaos_window.c

View File

@ -0,0 +1,94 @@
#ifndef SDI_COMPILER_H
#define SDI_COMPILER_H
/* Includeheader
Name: SDI_compiler.h
Versionstring: $VER: SDI_compiler.h 1.5 (29.07.2000)
Author: SDI
Distribution: PD
Description: defines to hide compiler stuff
1.1 25.06.98 : created from data made by Gunter Nikl
1.2 17.11.99 : added VBCC
1.3 29.02.00 : fixed VBCC REG define
1.4 30.03.00 : fixed SAVEDS for VBCC
1.5 29.07.00 : added #undef statements (needed e.g. for AmiTCP together with vbcc)
*/
#ifdef ASM
#undef ASM
#endif
#ifdef REG
#undef REG
#endif
#ifdef LREG
#undef LREG
#endif
#ifdef CONST
#undef CONST
#endif
#ifdef SAVEDS
#undef SAVEDS
#endif
#ifdef INLINE
#undef INLINE
#endif
#ifdef REGARGS
#undef REGARGS
#endif
#ifdef STDARGS
#undef STDARGS
#endif
/* first "exceptions" */
#if defined(__MAXON__)
#define STDARGS
#define REGARGS
#define SAVEDS
#define INLINE inline
#elif defined(__VBCC__)
#define STDARGS
#define REGARGS
#define INLINE
#define REG(reg,arg) __reg(#reg) arg
#elif defined(__STORM__)
#define STDARGS
#define REGARGS
#define INLINE inline
#elif defined(__SASC)
#define ASM(arg) arg __asm
#elif defined(__GNUC__)
#define REG(reg,arg) arg __asm(#reg)
#define LREG(reg,arg) register REG(reg,arg)
#endif
/* then "common" ones */
#if !defined(ASM)
#define ASM(arg) arg
#endif
#if !defined(REG)
#define REG(reg,arg) register __##reg arg
#endif
#if !defined(LREG)
#define LREG(reg,arg) register arg
#endif
#if !defined(CONST)
#define CONST const
#endif
#if !defined(SAVEDS)
#define SAVEDS __saveds
#endif
#if !defined(INLINE)
#define INLINE __inline
#endif
#if !defined(REGARGS)
#define REGARGS __regargs
#endif
#if !defined(STDARGS)
#define STDARGS __stdargs
#endif
#endif /* SDI_COMPILER_H */

View File

@ -0,0 +1,51 @@
//========================================================================
// GLFW - An OpenGL framework
// File: amigaos_enable.c
// Platforms: AmigaOS, MorphOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformEnableSystemKeys() - Enable system keys
// _glfwPlatformDisableSystemKeys() - Disable system keys
//========================================================================
void _glfwPlatformEnableSystemKeys( void )
{
// Not supported under AmigaOS (yet)
}
void _glfwPlatformDisableSystemKeys( void )
{
// Not supported under AmigaOS (yet)
}

View File

@ -0,0 +1,319 @@
//========================================================================
// GLFW - An OpenGL framework
// File: amigaos_fullscreen.c
// Platforms: AmigaOS, MorphOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwBPP2RGB() - Convert BPP to RGB bits (based on "best guess")
//========================================================================
static void _glfwBPP2RGB( int bpp, int *r, int *g, int *b )
{
int delta;
// Special case: bpp = 32
if( bpp == 32 ) bpp = 24;
// Convert "bits per pixel" to red, green & blue sizes
*r = *g = *b = bpp / 3;
delta = bpp - (*r * 3);
if( delta >= 1 )
{
*g = *g + 1;
}
if( delta == 2 )
{
*r = *r + 1;
}
}
//========================================================================
// _glfwGetModeIDInfo() - Return video mode information about a ModeID
//========================================================================
void _glfwGetModeIDInfo( ULONG ModeID, int *w, int *h, int *r, int *g,
int *b, int *refresh )
{
struct DimensionInfo dimsInfo;
struct DisplayInfo dispInfo;
struct MonitorInfo monInfo;
// Get various display info
(void) GetDisplayInfoData( NULL,
(BYTE*) &dimsInfo,
sizeof(struct DimensionInfo),
DTAG_DIMS,
ModeID );
(void) GetDisplayInfoData( NULL,
(BYTE*) &dispInfo,
sizeof(struct DisplayInfo),
DTAG_DISP,
ModeID );
(void) GetDisplayInfoData( NULL,
(BYTE*) &monInfo,
sizeof(struct MonitorInfo),
DTAG_MNTR,
ModeID );
// Extract nominal width & height
if( w != NULL && h != NULL )
{
*w = (int) (dimsInfo.Nominal.MaxX - dimsInfo.Nominal.MinX) + 1;
*h = (int) (dimsInfo.Nominal.MaxY - dimsInfo.Nominal.MinY) + 1;
}
// Extract color bits
if( r != NULL && g != NULL && g != NULL )
{
*r = (int) dispInfo.RedBits;
*g = (int) dispInfo.GreenBits;
*b = (int) dispInfo.BlueBits;
// If depth < sum of RGB bits, we're probably not true color,
// which means that DisplayInfo red/green/blue bits do not refer
// to actual pixel color depth => use pixel depth info instead
if( dimsInfo.MaxDepth < (*r + *g + *b) )
{
_glfwBPP2RGB( dimsInfo.MaxDepth, r, g, b );
}
}
// Extract refresh rate
if( refresh != NULL )
{
*refresh = (int) (1.0 / ((double) monInfo.TotalRows *
(double) monInfo.TotalColorClocks *
280.0e-9) + 0.5 );
}
}
//========================================================================
// _glfwGetClosestVideoMode()
//========================================================================
int _glfwGetClosestVideoMode( int *w, int *h, int *r, int *g, int *b,
int refresh )
{
int modeID;
// Find best mode
modeID = BestModeID(
BIDTAG_NominalWidth, *w,
BIDTAG_NominalHeight, *h,
BIDTAG_Depth, *r + *g + *b,
BIDTAG_RedBits, *r,
BIDTAG_GreenBits, *g,
BIDTAG_BlueBits, *b,
TAG_DONE, 0
);
// Did we get a proper mode?
if( !modeID )
{
return 0;
}
// Get actual display info
_glfwGetModeIDInfo( modeID, w, h, r, g, b, NULL );
return modeID;
}
//========================================================================
// _glfwOpenScreen() - Open an AmigaOS screen
//========================================================================
int _glfwOpenScreen( int *width, int *height, int *r, int *g, int *b,
int refresh )
{
int bpp, modeID;
// Calculate BPP
bpp = *r + *g + *b;
// If colorbits < 8 (e.g. 0) or >= 24, default to 24 bpp
if( bpp < 8 || bpp >= 24 )
{
*r = *g = *b = 8;
}
// Find best matching video mode
modeID = _glfwGetClosestVideoMode( width, height, r, g, b, refresh );
// Open screen
_glfwWin.Screen = OpenScreenTags(
NULL,
SA_Width, *width,
SA_Height, *height,
SA_DisplayID, modeID,
SA_Type, CUSTOMSCREEN,
SA_SysFont, 1,
SA_ShowTitle, FALSE,
TAG_DONE, 0
);
// Did we succeed?
if( !_glfwWin.Screen )
{
printf( "Failed to open Amiga screen\n" );
return GL_FALSE;
}
// Remember Mode ID
_glfwWin.ModeID = modeID;
/*
// Debugging information
printf( "Amiga Screen opened:\n" );
printf( " ModeID: 0x%08X\n", modeID );
printf( " Dimensions: %d x %d\n", *width, *height );
printf( " Color bits: %d : %d : %d\n", *r, *g, *b );
*/
return GL_TRUE;
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformGetVideoModes() - List available video modes
//========================================================================
int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )
{
ULONG modeID;
int w, h, r, g, b, bpp, m1, m2, i, j, count;
count = 0;
modeID = INVALID_ID;
do
{
// Enumarate all ModeIDs with NextDisplayInfo
modeID = NextDisplayInfo( modeID );
if( modeID != INVALID_ID )
{
// Get related video mode information
_glfwGetModeIDInfo( modeID, &w, &h, &r, &g, &b, NULL );
// Convert RGB to BPP
bpp = r + g + b;
// We only support true-color modes, which means at least 15
// bits per pixel (reasonable?) - Sorry, AGA users!
if( bpp >= 15 )
{
// Mode "code" for this mode
m1 = (bpp << 25) | (w*h);
// Insert mode in list (sorted), and avoid duplicates
for( i = 0; i < count; i ++ )
{
// Mode "code" for already listed mode
bpp = list[i].RedBits + list[i].GreenBits +
list[i].BlueBits;
m2 = (bpp << 25) | (list[i].Width * list[i].Height);
if( m1 <= m2 )
{
break;
}
}
// New entry at the end of the list?
if( i >= count )
{
list[count].Width = w;
list[count].Height = h;
list[count].RedBits = r;
list[count].GreenBits = g;
list[count].BlueBits = b;
count ++;
}
// Insert new entry in the list?
else if( m1 < m2 )
{
for( j = count; j > i; j -- )
{
list[j] = list[j-1];
}
list[i].Width = w;
list[i].Height = h;
list[i].RedBits = r;
list[i].GreenBits = g;
list[i].BlueBits = b;
count ++;
}
}
}
}
while( modeID != INVALID_ID && count < maxcount );
return count;
}
//========================================================================
// _glfwPlatformGetDesktopMode() - Get the desktop video mode
//========================================================================
void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )
{
struct Screen *pubscreen;
ULONG modeID;
// Get default public screen screen handle
pubscreen = LockPubScreen( NULL );
// Get screen width and height (use actual screen size rather than
// ModeID nominal size)
mode->Width = (int) pubscreen->Width;
mode->Height = (int) pubscreen->Height;
// Get ModeID for public screen
modeID = GetVPModeID( &pubscreen->ViewPort );
// Release workbench screen
UnlockPubScreen( NULL, pubscreen );
// Get color bits information
_glfwGetModeIDInfo( modeID, NULL, NULL, &mode->RedBits,
&mode->GreenBits, &mode->BlueBits, NULL );
}

View File

@ -0,0 +1,61 @@
//========================================================================
// GLFW - An OpenGL framework
// File: amigaos_glext.c
// Platforms: AmigaOS, MorphOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformExtensionSupported() - Check if an OpenGL extension is
// available at runtime
//========================================================================
int _glfwPlatformExtensionSupported( const char *extension )
{
// There are no AmigaOS specific ways to check for extensions
return GL_FALSE;
}
//========================================================================
// _glfwPlatformGetProcAddress() - Get the function pointer to an OpenGL
// function
//========================================================================
void * _glfwPlatformGetProcAddress( const char *procname )
{
#ifdef _GLFW_STORMMESA
// StormMesa does not support this
return NULL;
#endif
}

View File

@ -0,0 +1,284 @@
//========================================================================
// GLFW - An OpenGL framework
// File: amigaos_init.c
// Platforms: AmigaOS, MorphOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwInitLibraries() - Load shared libraries
//========================================================================
static int _glfwInitLibraries( void )
{
// Note: exec.library & dos.library are always opened (by C startup)
// Start by clearing all handles
GfxBase = NULL;
IntuitionBase = NULL;
KeymapBase = NULL;
UtilityBase = NULL;
// graphics.library
GfxBase = (struct GfxBase *) OpenLibrary( "graphics.library", 40 );
if( !GfxBase )
{
return 0;
}
// intuition.library
IntuitionBase = (struct IntuitionBase *) OpenLibrary( "intuition.library", 40 );
if( !IntuitionBase )
{
return 0;
}
// keymap.library
KeymapBase = OpenLibrary( "keymap.library", 40 );
if( !KeymapBase )
{
return 0;
}
// Utility.library
UtilityBase = (struct UtilityBase *) OpenLibrary( "utility.library", 40 );
if( !UtilityBase )
{
return 0;
}
return 1;
}
//========================================================================
// _glfwTerminateLibraries() - Unload shared libraries
//========================================================================
static void _glfwTerminateLibraries( void )
{
// Close graphics.library
if( GfxBase )
{
CloseLibrary( (struct Library *) GfxBase );
GfxBase = NULL;
}
// Close intuition.library
if( IntuitionBase )
{
CloseLibrary( (struct Library *) IntuitionBase );
IntuitionBase = NULL;
}
// Close keymap.library
if( KeymapBase )
{
CloseLibrary( KeymapBase );
KeymapBase = NULL;
}
// Close utility.library
if( UtilityBase )
{
CloseLibrary( (struct Library *) UtilityBase );
UtilityBase = NULL;
}
}
//========================================================================
// _glfwInitThreads() - Initialize GLFW thread package
//========================================================================
static int _glfwInitThreads( void )
{
int waitSig;
// Allocate a signal to use for waiting (glfwWaitThread and
// glfwWaitCond)
waitSig = AllocSignal( -1 );
if( waitSig == -1 )
{
return 0;
}
// Initialize critical section handle
memset( &_glfwThrd.CriticalSection,0,sizeof(struct SignalSemaphore) );
InitSemaphore( &_glfwThrd.CriticalSection );
// The first thread (the main thread) has ID 0
_glfwThrd.NextID = 0;
// The first condition variable has ID 0xFFFFFFFF
_glfwThrd.NextCondID = 0xFFFFFFFF;
// Fill out information about the main thread (this thread)
_glfwThrd.First.Previous = NULL;
_glfwThrd.First.Next = NULL;
_glfwThrd.First.ID = _glfwThrd.NextID ++;
_glfwThrd.First.Function = NULL;
_glfwThrd.First.Arg = NULL;
_glfwThrd.First.AmiTask = FindTask( NULL );
_glfwThrd.First.AmiProc = (struct Process *) _glfwThrd.First.AmiTask;
_glfwThrd.First.WaitFor = NULL;
_glfwThrd.First.WaitSig = waitSig;
// Store GLFW thread struct pointer in task user data
_glfwThrd.First.AmiTask->tc_UserData = (APTR) &_glfwThrd.First;
return 1;
}
//========================================================================
// _glfwTerminateThreads() - Terminate GLFW thread package
//========================================================================
static void _glfwTerminateThreads( void )
{
_GLFWthread *t, *t_next;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Kill all threads (NOTE: THE USER SHOULD WAIT FOR ALL THREADS TO
// DIE, _BEFORE_ CALLING glfwTerminate()!!!)
t = _glfwThrd.First.Next;
while( t != NULL )
{
// Get pointer to next thread
t_next = t->Next;
// Simply murder the process, no mercy!
// ?? How about Process resources ??
RemTask( t->AmiTask );
// Free memory allocated for this thread
free( (void *) t );
// Select next thread in list
t = t_next;
}
// Free waiting signal for main thread
FreeSignal( _glfwThrd.First.WaitSig );
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
}
//========================================================================
// _glfwTerminate_atexit() - Terminate GLFW when exiting application
//========================================================================
void _glfwTerminate_atexit( void )
{
glfwTerminate();
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformInit() - Initialize various GLFW state
//========================================================================
int _glfwPlatformInit( void )
{
// Load shared libraries
if( !_glfwInitLibraries() )
{
_glfwTerminateLibraries();
return GL_FALSE;
}
// Initialize thread package
if( !_glfwInitThreads() )
{
_glfwTerminateLibraries();
return GL_FALSE;
}
// Start the timer
if( !_glfwInitTimer() )
{
_glfwTerminateThreads();
_glfwTerminateLibraries();
return GL_FALSE;
}
// Initialize joysticks
_glfwInitJoysticks();
// Install atexit() routine
atexit( _glfwTerminate_atexit );
return GL_TRUE;
}
//========================================================================
// _glfwPlatformTerminate() - Close window and kill all threads
//========================================================================
int _glfwPlatformTerminate( void )
{
// Only the main thread is allowed to do this...
if( FindTask( NULL ) != _glfwThrd.First.AmiTask )
{
return GL_FALSE;
}
// Close OpenGL window
glfwCloseWindow();
// Terminate joysticks
_glfwTerminateJoysticks();
// Kill timer
_glfwTerminateTimer();
// Kill thread package
_glfwTerminateThreads();
// Unload shared libraries
_glfwTerminateLibraries();
return GL_TRUE;
}

View File

@ -0,0 +1,359 @@
//========================================================================
// GLFW - An OpenGL framework
// File: amigaos_joystick.c
// Platforms: AmigaOS, MorphOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwSendJoyReadRequest() - Send joystick read request
//========================================================================
static void _glfwSendJoyReadRequest( void )
{
// Send read request
_glfwJoy.GameIO->io_Command = GPD_READEVENT;
_glfwJoy.GameIO->io_Flags = 0;
_glfwJoy.GameIO->io_Data = (APTR) &_glfwJoy.GameEvent;
_glfwJoy.GameIO->io_Length = sizeof(struct InputEvent);
SendIO( (struct IORequest *) _glfwJoy.GameIO );
}
//========================================================================
// _glfwInitJoysticks() - Initialize joystick interface
//========================================================================
void _glfwInitJoysticks( void )
{
unsigned char controller_type = 0;
struct GamePortTrigger game_trigger;
// Start by clearing all handles
_glfwJoy.GameMP = NULL;
_glfwJoy.GameIO = NULL;
_glfwJoy.Present = 0;
_glfwJoy.GameDeviceOpen = 0;
// Create gameport.device message port
if( !(_glfwJoy.GameMP = CreatePort( NULL, 0 )) )
{
return;
}
// Create gameport.device I/O request
if( !( _glfwJoy.GameIO = (struct IOStdReq *)
CreateExtIO(_glfwJoy.GameMP, sizeof(struct IOStdReq)) ) )
{
_glfwTerminateJoysticks();
return;
}
// Open gameport.device (unit 1 = port 2)
_glfwJoy.GameIO->io_Message.mn_Node.ln_Type = NT_UNKNOWN;
if( OpenDevice( "gameport.device", 1,
(struct IORequest *)_glfwJoy.GameIO, 0 ) )
{
_glfwTerminateJoysticks();
return;
}
_glfwJoy.GameDeviceOpen = 1;
// Start critical section
Forbid();
// Find out if anyone else is using the stick
_glfwJoy.GameIO->io_Command = GPD_ASKCTYPE;
_glfwJoy.GameIO->io_Flags = IOF_QUICK;
_glfwJoy.GameIO->io_Data = (APTR) &controller_type;
_glfwJoy.GameIO->io_Length = 1;
DoIO( (struct IORequest *) _glfwJoy.GameIO );
// Was it already allocated?
if( controller_type != GPCT_NOCONTROLLER )
{
Permit();
_glfwTerminateJoysticks();
return;
}
// Allocate joystick
controller_type = GPCT_ABSJOYSTICK;
_glfwJoy.GameIO->io_Command = GPD_SETCTYPE;
_glfwJoy.GameIO->io_Flags = IOF_QUICK;
_glfwJoy.GameIO->io_Data = (APTR) &controller_type;
_glfwJoy.GameIO->io_Length = 1;
DoIO( (struct IORequest *) _glfwJoy.GameIO );
_glfwJoy.Present = 1;
// End critical section
Permit();
// Set trigger conditions
game_trigger.gpt_Keys = GPTF_UPKEYS | GPTF_DOWNKEYS;
game_trigger.gpt_XDelta = 1;
game_trigger.gpt_YDelta = 1;
game_trigger.gpt_Timeout = (UWORD) 0xFFFF; // ~20 minutes
_glfwJoy.GameIO->io_Command = GPD_SETTRIGGER;
_glfwJoy.GameIO->io_Flags = IOF_QUICK;
_glfwJoy.GameIO->io_Data = (APTR) &game_trigger;
_glfwJoy.GameIO->io_Length = (LONG) sizeof(struct GamePortTrigger);
DoIO( (struct IORequest *) _glfwJoy.GameIO );
// Flush buffer
_glfwJoy.GameIO->io_Command = CMD_CLEAR;
_glfwJoy.GameIO->io_Flags = IOF_QUICK;
_glfwJoy.GameIO->io_Data = NULL;
_glfwJoy.GameIO->io_Length = 0;
DoIO( (struct IORequest *) _glfwJoy.GameIO );
// Send joystick read request (asynchronous)
_glfwSendJoyReadRequest();
}
//========================================================================
// _glfwTerminateJoysticks() - Close all opened joystick handles
//========================================================================
void _glfwTerminateJoysticks( void )
{
unsigned char controller_type;
// Remove any remaining asynchronous messages
if( _glfwJoy.GameIO )
{
if( !CheckIO( (struct IORequest *)_glfwJoy.GameIO ) )
{
AbortIO( (struct IORequest *)_glfwJoy.GameIO );
WaitIO( (struct IORequest *)_glfwJoy.GameIO );
}
}
// Deallocate joystick
if( _glfwJoy.Present )
{
controller_type = GPCT_NOCONTROLLER;
_glfwJoy.GameIO->io_Command = GPD_SETCTYPE;
_glfwJoy.GameIO->io_Flags = IOF_QUICK;
_glfwJoy.GameIO->io_Data = (APTR) &controller_type;
_glfwJoy.GameIO->io_Length = 1;
DoIO( (struct IORequest *) _glfwJoy.GameIO );
_glfwJoy.Present = 0;
}
// Close gameport.device
if( _glfwJoy.GameDeviceOpen )
{
CloseDevice( (struct IORequest *) _glfwJoy.GameIO );
_glfwJoy.GameDeviceOpen = 0;
}
// Delete I/O request
if( _glfwJoy.GameIO )
{
DeleteExtIO( (struct IORequest *) _glfwJoy.GameIO );
_glfwJoy.GameIO = NULL;
}
// Delete message port
if( _glfwJoy.GameMP )
{
DeletePort( _glfwJoy.GameMP );
_glfwJoy.GameMP = NULL;
}
}
//========================================================================
// _glfwPollJoystickEvents() - Empty joystick event queue
//========================================================================
static void _glfwPollJoystickEvents( void )
{
int got_event = 0;
// Do we have a stick?
if( !_glfwJoy.Present )
{
return;
}
// Empty the message queue
while( GetMsg( _glfwJoy.GameMP ) != NULL )
{
// Flag: we got an event
got_event = 1;
switch( _glfwJoy.GameEvent.ie_Code )
{
// Left button pressed
case IECODE_LBUTTON:
_glfwJoy.Button[ 0 ] = 1;
break;
// Left button released
case (IECODE_LBUTTON | IECODE_UP_PREFIX):
_glfwJoy.Button[ 0 ] = 0;
break;
// Right button pressed
case IECODE_RBUTTON:
_glfwJoy.Button[ 1 ] = 1;
break;
// Right button released
case (IECODE_RBUTTON | IECODE_UP_PREFIX):
_glfwJoy.Button[ 1 ] = 0;
break;
// Axis event
case IECODE_NOBUTTON:
_glfwJoy.Axis[ 0 ] = (float) _glfwJoy.GameEvent.ie_X;
_glfwJoy.Axis[ 1 ] = (float) -_glfwJoy.GameEvent.ie_Y;
break;
default:
break;
}
}
// Did we get any events?
if( got_event )
{
// Send joystick read request (asynchronous)
_glfwSendJoyReadRequest();
}
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformGetJoystickParam() - Determine joystick capabilities
//========================================================================
int _glfwPlatformGetJoystickParam( int joy, int param )
{
// Is joystick present?
if( joy != GLFW_JOYSTICK_1 || !_glfwJoy.Present )
{
return 0;
}
// We assume that the joystick is connected, and has two axes and two
// buttons (since there is no way of retrieving this information from
// AmigaOS)
switch( param )
{
case GLFW_PRESENT:
return GL_TRUE;
case GLFW_AXES:
return 2;
case GLFW_BUTTONS:
return 2;
default:
break;
}
return 0;
}
//========================================================================
// _glfwPlatformGetJoystickPos() - Get joystick axis positions
//========================================================================
int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )
{
int k;
// Is joystick present?
if( joy != GLFW_JOYSTICK_1 || !_glfwJoy.Present )
{
return 0;
}
// Update joystick state
_glfwPollJoystickEvents();
// Copy axis position information to output vector
if( numaxes > 2 )
{
numaxes = 2;
}
for( k = 0; k < numaxes; ++ k )
{
pos[ k ] = _glfwJoy.Axis[ k ];
}
return numaxes;
}
//========================================================================
// _glfwPlatformGetJoystickButtons() - Get joystick button states
//========================================================================
int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons,
int numbuttons )
{
int k;
// Is joystick present?
if( joy != GLFW_JOYSTICK_1 || !_glfwJoy.Present )
{
return 0;
}
// Update joystick state
_glfwPollJoystickEvents();
// Copy button information to output vector
if( numbuttons > 2 )
{
numbuttons = 2;
}
for( k = 0; k < numbuttons; ++ k )
{
buttons[ k ] = _glfwJoy.Button[ k ];
}
return numbuttons;
}

View File

@ -0,0 +1,494 @@
//========================================================================
// GLFW - An OpenGL framework
// File: amigaos_thread.c
// Platforms: AmigaOS, MorphOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwNewThread() - This is simply a "wrapper" for calling the user
// thread function.
//========================================================================
int _glfwNewThread( void )
{
GLFWthreadfun threadfun;
void *arg;
_GLFWthread *t, *t_wait;
struct Task *amiTask;
int waitSig;
// Allocate a signal to use for waiting (glfwWaitThread and
// glfwWaitCond)
waitSig = AllocSignal( -1 );
if( waitSig == -1 )
{
// If we could not get a signal (VERY UNLIKELY), exit immediately
return 0;
}
// Get current task
amiTask = FindTask( NULL );
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// The task's user data points to the GLFW thread struct
t = (_GLFWthread *) amiTask->tc_UserData;
// Store wait signal handle
t->WaitSig = waitSig;
t->WaitFor = NULL;
// Get user thread function pointer and argument
threadfun = t->Function;
arg = t->Arg;
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Call the user thread function
threadfun( arg );
ENTER_THREAD_CRITICAL_SECTION
// Remove thread from thread list
_glfwRemoveThread( t );
// Signal any waiting threads that we have died
for( t_wait = &_glfwThrd.First; t_wait; t_wait = t_wait->Next )
{
if( t_wait->WaitFor == (void *) t )
{
Signal( t_wait->AmiTask, 1L<<t_wait->WaitSig );
t_wait->WaitFor = NULL;
}
}
LEAVE_THREAD_CRITICAL_SECTION
// When the process function returns, the process will die...
return 0;
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformCreateThread() - Create a new thread
//========================================================================
GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )
{
GLFWthread ID;
_GLFWthread *t;
struct TagItem tagList[ 10 ];
int tagNR;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Create a new thread information memory area
t = (_GLFWthread *) malloc( sizeof(_GLFWthread) );
if( t == NULL )
{
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
return -1;
}
// Get a new unique thread id
ID = _glfwThrd.NextID ++;
// Store thread information in the thread list
t->ID = ID;
t->Function = fun;
t->Arg = arg;
#ifdef _GLFW_MORPHOS
// For MorphOS, we set up a 68k -> PPC switch trap instruction.
// CreateNewProc actually creates a 68k process (emulated), so we make
// sure that the first 68k instruction that is executed is a trap
// instruction that forces the execution model to change from emulated
// 68k to native PPC (and starts execution at _glfwNewThread).
t->mosEmulLibEntry.Trap = TRAP_LIB;
t->mosEmulLibEntry.Extension = 0;
t->mosEmulLibEntry.Func = _glfwNewThread;
#endif
// Create new process
tagNR = 0;
tagList[ tagNR ].ti_Tag = NP_Entry;
#ifdef _GLFW_MORPHOS
tagList[ tagNR++ ].ti_Data = (ULONG) &t->mosEmulLibEntry;
#else
tagList[ tagNR++ ].ti_Data = (ULONG) _glfwNewThread;
#endif
tagList[ tagNR ].ti_Tag = NP_StackSize;
tagList[ tagNR++ ].ti_Data = _GLFW_TASK_STACK_SIZE;
tagList[ tagNR ].ti_Tag = NP_Input;
tagList[ tagNR++ ].ti_Data = (ULONG) Input();
tagList[ tagNR ].ti_Tag = NP_Output;
tagList[ tagNR++ ].ti_Data = (ULONG) Output();
tagList[ tagNR ].ti_Tag = NP_CloseInput;
tagList[ tagNR++ ].ti_Data = FALSE;
tagList[ tagNR ].ti_Tag = NP_CloseOutput;
tagList[ tagNR++ ].ti_Data = FALSE;
tagList[ tagNR ].ti_Tag = TAG_DONE;
t->AmiProc = CreateNewProc( tagList );
// Did the process creation fail?
if( !t->AmiProc )
{
free( (void *) t );
LEAVE_THREAD_CRITICAL_SECTION
return -1;
}
// Get pointer to task structure
t->AmiTask = &(t->AmiProc->pr_Task);
// Store GLFW thread struct pointer in task user data
t->AmiTask->tc_UserData = (APTR) t;
// Append thread to thread list
_glfwAppendThread( t );
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Return the GLFW thread ID
return ID;
}
//========================================================================
// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY
// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME
// SITUATIONS!
//========================================================================
void _glfwPlatformDestroyThread( GLFWthread ID )
{
_GLFWthread *t, *t_wait;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Get thread information pointer
t = _glfwGetThreadPointer( ID );
if( t == NULL )
{
LEAVE_THREAD_CRITICAL_SECTION
return;
}
// Simply murder the process, no mercy!
// ?? How about Process resources ??
RemTask( t->AmiTask );
// Remove thread from thread list
_glfwRemoveThread( t );
// Signal any waiting threads that the thread has died
for( t_wait = &_glfwThrd.First; t_wait; t_wait = t_wait->Next )
{
if( t_wait->WaitFor == (void *) t )
{
Signal( t_wait->AmiTask, 1L<<t_wait->WaitSig );
t_wait->WaitFor = NULL;
}
}
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
}
//========================================================================
// _glfwPlatformWaitThread() - Wait for a thread to die
//========================================================================
int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )
{
struct Task *amiTask;
_GLFWthread *t, *t_this;
int waitSig;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Get thread information pointer
t = _glfwGetThreadPointer( ID );
// Is the thread already dead?
if( t == NULL )
{
LEAVE_THREAD_CRITICAL_SECTION
return GL_TRUE;
}
// If got this far, the thread is alive => polling returns FALSE
if( waitmode == GLFW_NOWAIT )
{
LEAVE_THREAD_CRITICAL_SECTION
return GL_FALSE;
}
// Find pointer to this threads structure
amiTask = FindTask( NULL );
t_this = (_GLFWthread *) amiTask->tc_UserData;
// Store information in our thread structure that we want to wait for
// the specified thread to die
t_this->WaitFor = (void *) t;
waitSig = t_this->WaitSig;
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Wait for thread to die
Wait( 1L<<waitSig );
return GL_TRUE;
}
//========================================================================
// _glfwPlatformGetThreadID() - Return the thread ID for the current
// thread
//========================================================================
GLFWthread _glfwPlatformGetThreadID( void )
{
_GLFWthread *t;
struct Task *amiTask;
// Get current task
amiTask = FindTask( NULL );
// The task's user data points to the GLFW thread struct
t = (_GLFWthread *) amiTask->tc_UserData;
// Return the found GLFW thread identifier
return t->ID;
}
//========================================================================
// _glfwPlatformCreateMutex() - Create a mutual exclusion object
//========================================================================
GLFWmutex _glfwPlatformCreateMutex( void )
{
struct SignalSemaphore *mutex;
// Allocate memory for mutex
mutex = (struct SignalSemaphore *) malloc( sizeof(struct SignalSemaphore) );
if( !mutex )
{
return NULL;
}
// Initialize mutex object
memset( mutex, 0, sizeof(struct SignalSemaphore) );
InitSemaphore( mutex );
// Cast to GLFWmutex and return
return (GLFWmutex) mutex;
}
//========================================================================
// _glfwPlatformDestroyMutex() - Destroy a mutual exclusion object
//========================================================================
void _glfwPlatformDestroyMutex( GLFWmutex mutex )
{
// Free memory for mutex object
free( (void *) mutex );
}
//========================================================================
// _glfwPlatformLockMutex() - Request access to a mutex
//========================================================================
void _glfwPlatformLockMutex( GLFWmutex mutex )
{
// Wait for mutex to be released
ObtainSemaphore( (struct SignalSemaphore *) mutex );
}
//========================================================================
// _glfwPlatformUnlockMutex() - Release a mutex
//========================================================================
void _glfwPlatformUnlockMutex( GLFWmutex mutex )
{
// Release mutex
ReleaseSemaphore( (struct SignalSemaphore *) mutex );
}
//========================================================================
// _glfwPlatformCreateCond() - Create a new condition variable object
//========================================================================
GLFWcond _glfwPlatformCreateCond( void )
{
unsigned int cond;
// Generate a new unique cond ID
ENTER_THREAD_CRITICAL_SECTION
cond = _glfwThrd.NextCondID --;
LEAVE_THREAD_CRITICAL_SECTION
// Cast to GLFWcond and return
return (GLFWcond) cond;
}
//========================================================================
// _glfwPlatformDestroyCond() - Destroy a condition variable object
//========================================================================
void _glfwPlatformDestroyCond( GLFWcond cond )
{
}
//========================================================================
// _glfwPlatformWaitCond() - Wait for a condition to be raised
//========================================================================
void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,
double timeout )
{
struct Task *amiTask;
_GLFWthread *t_this;
// Do we need a limited timeout?
if( timeout < GLFW_INFINITY )
{
// Oooops! Not implemented properly yet!
ReleaseSemaphore( (struct SignalSemaphore *) mutex );
Delay( 1 );
ObtainSemaphore( (struct SignalSemaphore *) mutex );
return;
}
// Find pointer to this threads structure
amiTask = FindTask( NULL );
t_this = (_GLFWthread *) amiTask->tc_UserData;
// Store information in our thread structure that we want to wait for
// the specified condition variable to be signaled
ENTER_THREAD_CRITICAL_SECTION
t_this->WaitFor = (void *) cond;
LEAVE_THREAD_CRITICAL_SECTION
// Release the mutex
ReleaseSemaphore( (struct SignalSemaphore *) mutex );
// Wait for condition variable
Wait( 1L<<(t_this->WaitSig) );
// Reacquire the mutex
ObtainSemaphore( (struct SignalSemaphore *) mutex );
}
//========================================================================
// _glfwPlatformSignalCond() - Signal a condition to one waiting thread
//========================================================================
void _glfwPlatformSignalCond( GLFWcond cond )
{
_GLFWthread *t_wait;
// Broadcast condition to one waiting thread
ENTER_THREAD_CRITICAL_SECTION
for( t_wait = &_glfwThrd.First; t_wait; t_wait = t_wait->Next )
{
if( t_wait->WaitFor == (void *) cond )
{
Signal( t_wait->AmiTask, 1L<<t_wait->WaitSig );
t_wait->WaitFor = NULL;
break;
}
}
LEAVE_THREAD_CRITICAL_SECTION
}
//========================================================================
// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting
// threads
//========================================================================
void _glfwPlatformBroadcastCond( GLFWcond cond )
{
_GLFWthread *t_wait;
// Broadcast condition to any waiting threads
ENTER_THREAD_CRITICAL_SECTION
for( t_wait = &_glfwThrd.First; t_wait; t_wait = t_wait->Next )
{
if( t_wait->WaitFor == (void *) cond )
{
Signal( t_wait->AmiTask, 1L<<t_wait->WaitSig );
t_wait->WaitFor = NULL;
}
}
LEAVE_THREAD_CRITICAL_SECTION
}
//========================================================================
// _glfwPlatformGetNumberOfProcessors() - Return the number of processors
// in the system.
//========================================================================
int _glfwPlatformGetNumberOfProcessors( void )
{
// Return number of processors online (MorphOS has SMP support, so we
// should do something useful here...)
return 1;
}

View File

@ -0,0 +1,206 @@
//========================================================================
// GLFW - An OpenGL framework
// File: amigaos_time.c
// Platforms: AmigaOS, MorphOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwInitTimer() - Initialize timer
//========================================================================
int _glfwInitTimer( void )
{
ULONG freq;
struct EClockVal t;
// Start by clearing all handles
TimerBase = NULL;
_glfwTimer.TimerMP = NULL;
_glfwTimer.TimerIO = NULL;
// Open timer.device (used as a library for ReadEClock)
if( (_glfwTimer.TimerMP = CreatePort( NULL, 0 )) )
{
// Create the I/O request
if( (_glfwTimer.TimerIO = (struct timerequest *)
CreateExtIO(_glfwTimer.TimerMP, sizeof(struct timerequest))) )
{
// Open the timer device
if( !( OpenDevice( "timer.device", UNIT_MICROHZ,
(struct IORequest *) _glfwTimer.TimerIO,
0 ) ) )
{
// Set up pointer for timer functions
TimerBase =
(struct Device *)_glfwTimer.TimerIO->tr_node.io_Device;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
else
{
return 0;
}
// Get current time
freq = ReadEClock( &t );
// Calculate resolution
_glfwTimer.Resolution = 1.0 / (double) freq;
// Convert to 64-bit integer
_glfwTimer.t0 = (long long) t.ev_hi * (long long) 4294967296 +
(long long) t.ev_lo;
return 1;
}
//========================================================================
// _glfwTerminateTimer() - Terminate timer
//========================================================================
void _glfwTerminateTimer( void )
{
// Empty the timer.device message port queue
if( _glfwTimer.TimerMP )
{
struct Message *msg;
while( NULL != (msg = GetMsg( _glfwTimer.TimerMP )) )
{
ReplyMsg( msg );
}
}
// Close timer.device
if( TimerBase )
{
CloseDevice( (struct IORequest *) _glfwTimer.TimerIO );
TimerBase = NULL;
}
// Delete timer.device I/O request
if( _glfwTimer.TimerIO )
{
DeleteExtIO( (struct IORequest *) _glfwTimer.TimerIO );
_glfwTimer.TimerIO = NULL;
}
// Delete timer.device message port
if( _glfwTimer.TimerMP )
{
DeletePort( _glfwTimer.TimerMP );
_glfwTimer.TimerMP = NULL;
}
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformGetTime() - Return timer value in seconds
//========================================================================
double _glfwPlatformGetTime( void )
{
struct EClockVal t;
long long t64;
// Get current time
(void) ReadEClock( &t );
// Convert to 64-bit integer
t64 = (long long) t.ev_hi * (long long) 4294967296 +
(long long) t.ev_lo;
return (double)(t64 - _glfwTimer.t0) * _glfwTimer.Resolution;
}
//========================================================================
// _glfwPlatformSetTime() - Set timer value in seconds
//========================================================================
void _glfwPlatformSetTime( double t )
{
struct EClockVal t0;
long long t64;
// Get current time
(void) ReadEClock( &t0 );
// Convert to 64-bit integer
t64 = (long long) t0.ev_hi * (long long) 4294967296 +
(long long) t0.ev_lo;
// Calulate new starting time
_glfwTimer.t0 = t64 - (long long)(t/_glfwTimer.Resolution);
}
//========================================================================
// _glfwPlatformSleep() - Put a thread to sleep for a specified amount of
// time
//========================================================================
void _glfwPlatformSleep( double time )
{
ULONG ticks;
// Too short time?
if( time <= 0.0 )
{
return;
}
// Calculate Delay ticks (should be 50 ticks per second)
ticks = (ULONG) ((double)TICKS_PER_SECOND * time + 0.5);
if( ticks == 0 )
{
ticks = 1;
}
// Put process to sleep
Delay( ticks );
}

View File

@ -0,0 +1,830 @@
//========================================================================
// GLFW - An OpenGL framework
// File: amigaos_window.c
// Platforms: AmigaOS, MorphOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwTranslateChar() - Translates an AmigaOS key to Unicode
//========================================================================
static int _glfwTranslateChar( struct IntuiMessage *msg )
{
struct InputEvent event;
unsigned char buffer[ 4 ];
int character;
// Create input event
event.ie_Class = IECLASS_RAWKEY;
event.ie_Code = msg->Code;
event.ie_Qualifier = msg->Qualifier;
event.ie_EventAddress = msg->IAddress;
// Map key event to text string
if( MapRawKey( &event, buffer, 4, NULL ) > 0 )
{
// Valid Unicode character?
character = (int) buffer[ 0 ];
if( (character >= 32 && character <= 126) ||
(character >= 160 && character <= 255) )
{
return character;
}
}
return -1;
}
//========================================================================
// _glfwTranslateKey() - Translates an AmigaOS key to internal coding
//========================================================================
static int _glfwTranslateKey( struct IntuiMessage *msg )
{
int key = msg->Code & 0x7F;
ULONG old_qualifier;
// Special (non printable) keys
switch( key )
{
// Modifier keys
case 0x60: return GLFW_KEY_LSHIFT;
case 0x61: return GLFW_KEY_RSHIFT;
case 0x62: return GLFW_KEY_LCTRL; // ?
case 0x63: return GLFW_KEY_RCTRL; // ?
case 0x64: return GLFW_KEY_LALT;
case 0x65: return GLFW_KEY_RALT;
// Function keys
case 0x50: return GLFW_KEY_F1;
case 0x51: return GLFW_KEY_F2;
case 0x52: return GLFW_KEY_F3;
case 0x53: return GLFW_KEY_F4;
case 0x54: return GLFW_KEY_F5;
case 0x55: return GLFW_KEY_F6;
case 0x56: return GLFW_KEY_F7;
case 0x57: return GLFW_KEY_F8;
case 0x58: return GLFW_KEY_F9;
case 0x59: return GLFW_KEY_F10;
// Other control keys
case 0x45: return GLFW_KEY_ESC;
case 0x42: return GLFW_KEY_TAB;
case 0x44: return GLFW_KEY_ENTER;
case 0x46: return GLFW_KEY_DEL;
case 0x41: return GLFW_KEY_BACKSPACE;
case 0x66: return GLFW_KEY_INSERT; // ?
case 0x4F: return GLFW_KEY_LEFT;
case 0x4E: return GLFW_KEY_RIGHT;
case 0x4C: return GLFW_KEY_UP;
case 0x4D: return GLFW_KEY_DOWN;
// Keypad keys
case 0x0F: return GLFW_KEY_KP_0;
case 0x1D: return GLFW_KEY_KP_1;
case 0x1E: return GLFW_KEY_KP_2;
case 0x1F: return GLFW_KEY_KP_3;
case 0x2D: return GLFW_KEY_KP_4;
case 0x2E: return GLFW_KEY_KP_5;
case 0x2F: return GLFW_KEY_KP_6;
case 0x3D: return GLFW_KEY_KP_7;
case 0x3E: return GLFW_KEY_KP_8;
case 0x3F: return GLFW_KEY_KP_9;
case 0x43: return GLFW_KEY_KP_ENTER;
case 0x5E: return GLFW_KEY_KP_ADD;
case 0x4A: return GLFW_KEY_KP_SUBTRACT;
case 0x5D: return GLFW_KEY_KP_MULTIPLY;
case 0x5C: return GLFW_KEY_KP_DIVIDE;
case 0x3C: return GLFW_KEY_KP_DECIMAL;
default: break;
}
// Printable keys (without modifiers!)
old_qualifier = msg->Qualifier;
msg->Qualifier = 0;
key = _glfwTranslateChar( msg );
msg->Qualifier = old_qualifier;
if( key > 0 )
{
// Make sure it is upper case
key = ToUpper( key );
}
return key;
}
//========================================================================
// _glfwProcessEvents() - Process all pending AmigaOS events
//========================================================================
static int _glfwProcessEvents( void )
{
struct IntuiMessage message, *tmp_message = NULL;
struct MsgPort *msg_port;
int win_closed = GL_FALSE, action;
int x, y;
// Examine pending messages
msg_port = _glfwWin.Window->UserPort;
while( (tmp_message = (struct IntuiMessage *) GetMsg( msg_port )) )
{
// Copy contents of message structure
message = *tmp_message;
// Now reply to the message (we don't need it anymore)
ReplyMsg( (struct Message *) tmp_message );
// Handle different messages
switch( message.Class )
{
// Was the window activated?
case IDCMP_ACTIVEWINDOW:
_glfwWin.Active = GL_TRUE;
break;
// Was the window deactivated?
case IDCMP_INACTIVEWINDOW:
_glfwWin.Active = GL_FALSE;
_glfwInputDeactivation();
break;
// Did we get a keyboard press or release?
case IDCMP_RAWKEY:
action = (message.Code & 0x80) ? GLFW_RELEASE : GLFW_PRESS;
message.Code &= 0x7F;
_glfwInputKey( _glfwTranslateKey( &message ), action );
_glfwInputChar( _glfwTranslateChar( &message ), action );
break;
// Was the mouse moved?
case IDCMP_MOUSEMOVE:
x = message.MouseX;
y = message.MouseY;
if( _glfwWin.PointerHidden )
{
// When pointer is hidden, we get delta moves
x += _glfwInput.MousePosX;
y += _glfwInput.MousePosY;
}
else if( x < 0 || x >= _glfwWin.Width ||
y < 0 || y >= _glfwWin.Height )
{
// Only report mouse moves that are INSIDE client area
break;
}
if( x != _glfwInput.MousePosX || y != _glfwInput.MousePosY )
{
_glfwInput.MousePosX = x;
_glfwInput.MousePosY = y;
if( _glfwWin.MousePosCallback )
{
_glfwWin.MousePosCallback( x, y );
}
}
break;
// Did we get a mouse button event?
case IDCMP_MOUSEBUTTONS:
switch( message.Code )
{
case SELECTUP:
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT,
GLFW_RELEASE );
break;
case SELECTDOWN:
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT,
GLFW_PRESS );
break;
case MENUUP:
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT,
GLFW_RELEASE );
break;
case MENUDOWN:
_glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT,
GLFW_PRESS );
break;
default:
break;
}
break;
// Was the window size changed?
case IDCMP_NEWSIZE:
_glfwWin.Width = message.IDCMPWindow->GZZWidth;
_glfwWin.Height = message.IDCMPWindow->GZZHeight;
if( _glfwWin.WindowSizeCallback )
{
_glfwWin.WindowSizeCallback( _glfwWin.Width,
_glfwWin.Height );
}
break;
// Was the window contents damaged?
case IDCMP_REFRESHWINDOW:
// Intuition wants us to do this...
BeginRefresh( _glfwWin.Window );
EndRefresh( _glfwWin.Window, TRUE );
// Call user callback function
if( _glfwWin.WindowRefreshCallback )
{
_glfwWin.WindowRefreshCallback();
}
break;
// Was the window closed?
case IDCMP_CLOSEWINDOW:
win_closed = GL_TRUE;
break;
default:
break;
}
}
// Return GL_TRUE if window was closed
return( win_closed );
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformOpenWindow() - Here is where the window is created, and
// the OpenGL rendering context is created
//========================================================================
int _glfwPlatformOpenWindow( int width, int height, int redbits,
int greenbits, int bluebits, int alphabits, int depthbits,
int stencilbits, int mode, int accumredbits, int accumgreenbits,
int accumbluebits, int accumalphabits, int auxbuffers, int stereo,
int refreshrate )
{
struct TagItem tagList[ 25 ];
int tagNR, accumbits;
// Calculate sum of accumulator bits
accumbits = accumredbits + accumgreenbits + accumbluebits +
accumalphabits;
// Clear window state
_glfwWin.Screen = NULL;
_glfwWin.Window = NULL;
_glfwWin.Context = NULL;
_glfwWin.PointerHidden = 0;
_glfwWin.PointerSprite = NULL;
_glfwWin.InputMP = NULL;
_glfwWin.InputIO = NULL;
// Create input.device message port
if( !(_glfwWin.InputMP = CreatePort( NULL, 0 )) )
{
_glfwPlatformCloseWindow();
return GL_FALSE;
}
// Create input.device I/O request
if( !(_glfwWin.InputIO = (struct IOStdReq *)
CreateExtIO( _glfwWin.InputMP, sizeof(struct IOStdReq) )) )
{
_glfwPlatformCloseWindow();
return GL_FALSE;
}
// Open input.device (for pointer position manipulation)
if( OpenDevice( "input.device", 0,
(struct IORequest *)_glfwWin.InputIO, 0 ) )
{
DeleteExtIO( (struct IORequest *) _glfwWin.InputIO );
_glfwWin.InputIO = NULL;
_glfwPlatformCloseWindow();
return GL_FALSE;
}
// Do we want fullscreen?
if( _glfwWin.Fullscreen )
{
// Open a new Amiga screen
if( !_glfwOpenScreen( &width, &height, &redbits, &greenbits,
&bluebits, refreshrate ) )
{
_glfwWin.Fullscreen = GL_FALSE;
}
}
// Select window properties
tagNR = 0;
tagList[ tagNR ].ti_Tag = WA_Left;
tagList[ tagNR++ ].ti_Data = 0;
tagList[ tagNR ].ti_Tag = WA_Top;
tagList[ tagNR++ ].ti_Data = 0;
tagList[ tagNR ].ti_Tag = WA_IDCMP;
tagList[ tagNR++ ].ti_Data = IDCMP_REFRESHWINDOW |
IDCMP_CLOSEWINDOW |
IDCMP_NEWSIZE |
IDCMP_ACTIVEWINDOW |
IDCMP_INACTIVEWINDOW |
IDCMP_RAWKEY |
IDCMP_MOUSEMOVE |
IDCMP_MOUSEBUTTONS;
tagList[ tagNR ].ti_Tag = WA_ReportMouse;
tagList[ tagNR++ ].ti_Data = TRUE;
tagList[ tagNR ].ti_Tag = WA_RMBTrap;
tagList[ tagNR++ ].ti_Data = TRUE;
tagList[ tagNR ].ti_Tag = WA_NoCareRefresh;
tagList[ tagNR++ ].ti_Data = FALSE;
tagList[ tagNR ].ti_Tag = WA_SimpleRefresh;
tagList[ tagNR++ ].ti_Data = TRUE;
tagList[ tagNR ].ti_Tag = WA_Activate;
tagList[ tagNR++ ].ti_Data = TRUE;
tagList[ tagNR ].ti_Tag = WA_CloseGadget;
tagList[ tagNR++ ].ti_Data = _glfwWin.Fullscreen ? FALSE : TRUE;
tagList[ tagNR ].ti_Tag = WA_SizeGadget;
tagList[ tagNR++ ].ti_Data = _glfwWin.Fullscreen ? FALSE : ( _glfwWinHints.WindowNoResize ? FALSE : TRUE );
tagList[ tagNR ].ti_Tag = WA_DepthGadget;
tagList[ tagNR++ ].ti_Data = _glfwWin.Fullscreen ? FALSE : TRUE;
tagList[ tagNR ].ti_Tag = WA_DragBar;
tagList[ tagNR++ ].ti_Data = _glfwWin.Fullscreen ? FALSE : TRUE;
tagList[ tagNR ].ti_Tag = WA_Borderless;
tagList[ tagNR++ ].ti_Data = _glfwWin.Fullscreen ? TRUE : FALSE;
tagList[ tagNR ].ti_Tag = WA_Backdrop;
tagList[ tagNR++ ].ti_Data = _glfwWin.Fullscreen ? TRUE : FALSE;
if( _glfwWin.Fullscreen )
{
tagList[ tagNR ].ti_Tag = WA_CustomScreen;
tagList[ tagNR++ ].ti_Data = (ULONG) _glfwWin.Screen;
tagList[ tagNR ].ti_Tag = WA_Width;
tagList[ tagNR++ ].ti_Data = width;
tagList[ tagNR ].ti_Tag = WA_Height;
tagList[ tagNR++ ].ti_Data = height;
}
else
{
tagList[ tagNR ].ti_Tag = WA_GimmeZeroZero;
tagList[ tagNR++ ].ti_Data = TRUE;
tagList[ tagNR ].ti_Tag = WA_InnerWidth;
tagList[ tagNR++ ].ti_Data = width;
tagList[ tagNR ].ti_Tag = WA_InnerHeight;
tagList[ tagNR++ ].ti_Data = height;
tagList[ tagNR ].ti_Tag = WA_MinWidth;
tagList[ tagNR++ ].ti_Data = 20;
tagList[ tagNR ].ti_Tag = WA_MinHeight;
tagList[ tagNR++ ].ti_Data = 20;
tagList[ tagNR ].ti_Tag = WA_MaxWidth;
tagList[ tagNR++ ].ti_Data = 9999;
tagList[ tagNR ].ti_Tag = WA_MaxHeight;
tagList[ tagNR++ ].ti_Data = 9999;
tagList[ tagNR ].ti_Tag = WA_Title;
tagList[ tagNR++ ].ti_Data = (ULONG) "GLFW Window";
tagList[ tagNR ].ti_Tag = WA_ScreenTitle;
tagList[ tagNR++ ].ti_Data = (ULONG) "GLFW Application";
}
tagList[ tagNR ].ti_Tag = TAG_DONE;
// Open window
_glfwWin.Window = OpenWindowTagList( NULL, tagList );
if( !_glfwWin.Window )
{
_glfwPlatformCloseWindow();
return GL_FALSE;
}
// Fullscreen/windowed post fixups
if( _glfwWin.Fullscreen )
{
// Don't show screen title
ShowTitle( _glfwWin.Screen, FALSE );
// Remember window size
_glfwWin.Width = _glfwWin.Window->Width;
_glfwWin.Height = _glfwWin.Window->Height;
}
else
{
// If we are not in fullscreen mode, get screen handle from window
_glfwWin.Screen = _glfwWin.Window->WScreen;
// Get ModeID for the current video mode
_glfwWin.ModeID = GetVPModeID( &_glfwWin.Screen->ViewPort );
// Remember window size
_glfwWin.Width = _glfwWin.Window->GZZWidth;
_glfwWin.Height = _glfwWin.Window->GZZHeight;
}
// Put window on top
WindowToFront( _glfwWin.Window );
// Create OpenGL context
#ifdef _GLFW_STORMMESA
tagNR = 0;
tagList[ tagNR ].ti_Tag = AMA_Window;
tagList[ tagNR++ ].ti_Data = (ULONG) _glfwWin.Window;
tagList[ tagNR ].ti_Tag = AMA_RastPort;
tagList[ tagNR++ ].ti_Data = (ULONG) _glfwWin.Window->RPort;
tagList[ tagNR ].ti_Tag = AMA_Screen;
tagList[ tagNR++ ].ti_Data = (ULONG) _glfwWin.Screen;
tagList[ tagNR ].ti_Tag = AMA_Left;
tagList[ tagNR++ ].ti_Data = 0;
tagList[ tagNR ].ti_Tag = AMA_Bottom;
tagList[ tagNR++ ].ti_Data = 0;
tagList[ tagNR ].ti_Tag = AMA_Width;
tagList[ tagNR++ ].ti_Data = _glfwWin.Width;
tagList[ tagNR ].ti_Tag = AMA_Height;
tagList[ tagNR++ ].ti_Data = _glfwWin.Height;
tagList[ tagNR ].ti_Tag = AMA_DoubleBuf;
tagList[ tagNR++ ].ti_Data = GL_TRUE;
tagList[ tagNR ].ti_Tag = AMA_RGBMode;
tagList[ tagNR++ ].ti_Data = GL_TRUE;
tagList[ tagNR ].ti_Tag = AMA_AlphaFlag;
tagList[ tagNR++ ].ti_Data = alphabits ? GL_TRUE : GL_FALSE;
tagList[ tagNR ].ti_Tag = AMA_NoDepth;
tagList[ tagNR++ ].ti_Data = depthbits ? GL_FALSE : GL_TRUE;
tagList[ tagNR ].ti_Tag = AMA_NoStencil;
tagList[ tagNR++ ].ti_Data = stencilbits ? GL_FALSE : GL_TRUE;
tagList[ tagNR ].ti_Tag = AMA_NoAccum;
tagList[ tagNR++ ].ti_Data = accumbits ? GL_FALSE : GL_TRUE;
tagList[ tagNR ].ti_Tag = AMA_DirectRender;
tagList[ tagNR++ ].ti_Data = GL_TRUE;
tagList[ tagNR ].ti_Tag = AMA_DrawMode;
tagList[ tagNR++ ].ti_Data = AMESA_AGA_C2P;
tagList[ tagNR ].ti_Tag = TAG_DONE;
_glfwWin.Context = AmigaMesaCreateContext( tagList );
#endif
if( !_glfwWin.Context )
{
_glfwPlatformCloseWindow();
return GL_FALSE;
}
// Make current
#ifdef _GLFW_STORMMESA
AmigaMesaMakeCurrent( _glfwWin.Context, _glfwWin.Context->buffer );
#endif
return GL_TRUE;
}
//========================================================================
// _glfwPlatformCloseWindow() - Properly kill the window/video display
//========================================================================
void _glfwPlatformCloseWindow( void )
{
// Restore mouse pointer (if hidden)
_glfwPlatformShowMouseCursor();
// Destroy OpenGL context
if( _glfwWin.Context )
{
#ifdef _GLFW_STORMMESA
AmigaMesaDestroyContext( _glfwWin.Context );
#endif
_glfwWin.Context = NULL;
}
// Close window
if( _glfwWin.Window )
{
CloseWindow( _glfwWin.Window );
_glfwWin.Window = NULL;
}
// Close screen
if( _glfwWin.Fullscreen && _glfwWin.Screen )
{
CloseScreen( _glfwWin.Screen );
}
_glfwWin.Screen = NULL;
// Close input device I/O request
if( _glfwWin.InputIO )
{
CloseDevice( (struct IORequest *) _glfwWin.InputIO );
DeleteExtIO( (struct IORequest *) _glfwWin.InputIO );
_glfwWin.InputIO = NULL;
}
// Close input device message port
if( _glfwWin.InputMP )
{
DeletePort( _glfwWin.InputMP );
_glfwWin.InputMP = NULL;
}
}
//========================================================================
// _glfwPlatformSetWindowTitle() - Set the window title.
//========================================================================
void _glfwPlatformSetWindowTitle( const char *title )
{
if( !_glfwWin.Fullscreen )
{
SetWindowTitles( _glfwWin.Window, (char*) title, (char*) title );
}
}
//========================================================================
// _glfwPlatformSetWindowSize() - Set the window size.
//========================================================================
void _glfwPlatformSetWindowSize( int width, int height )
{
if( !_glfwWin.Fullscreen )
{
SizeWindow( _glfwWin.Window, width-_glfwWin.Width,
height-_glfwWin.Height );
}
}
//========================================================================
// _glfwPlatformSetWindowPos() - Set the window position.
//========================================================================
void _glfwPlatformSetWindowPos( int x, int y )
{
if( !_glfwWin.Fullscreen )
{
ChangeWindowBox( _glfwWin.Window, x, y, _glfwWin.Window->Width,
_glfwWin.Window->Height );
}
}
//========================================================================
// _glfwPlatformIconfyWindow() - Window iconification
//========================================================================
void _glfwPlatformIconifyWindow( void )
{
if( _glfwWin.Fullscreen )
{
ScreenToBack( _glfwWin.Screen );
WBenchToFront();
_glfwWin.Iconified = GL_TRUE;
}
}
//========================================================================
// _glfwPlatformRestoreWindow() - Window un-iconification
//========================================================================
void _glfwPlatformRestoreWindow( void )
{
if( _glfwWin.Fullscreen )
{
ScreenToFront( _glfwWin.Screen );
}
WindowToFront( _glfwWin.Window );
ActivateWindow( _glfwWin.Window );
_glfwWin.Iconified = GL_FALSE;
}
//========================================================================
// _glfwPlatformSwapBuffers() - Swap buffers (double-buffering) and poll
// any new events.
//========================================================================
void _glfwPlatformSwapBuffers( void )
{
#ifdef _GLFW_STORMMESA
AmigaMesaSwapBuffers( _glfwWin.Context );
#endif
}
//========================================================================
// _glfwPlatformSwapInterval() - Set double buffering swap interval
//========================================================================
void _glfwPlatformSwapInterval( int interval )
{
// Not supported
}
//========================================================================
// _glfwPlatformRefreshWindowParams()
//========================================================================
void _glfwPlatformRefreshWindowParams( void )
{
int refresh;
GLint x;
GLboolean b;
// This function is not proerly implemented yet. We use OpenGL for
// getting framebuffer format information - we should use some
// alternate interface (such as glX under the X Window System), but
// StormMesa does not seem to provide this.
// Fill out information
_glfwWin.Accelerated = GL_TRUE;
glGetIntegerv( GL_RED_BITS, &x );
_glfwWin.RedBits = x;
glGetIntegerv( GL_GREEN_BITS, &x );
_glfwWin.GreenBits = x;
glGetIntegerv( GL_BLUE_BITS, &x );
_glfwWin.BlueBits = x;
glGetIntegerv( GL_ALPHA_BITS, &x );
_glfwWin.AlphaBits = x;
glGetIntegerv( GL_DEPTH_BITS, &x );
_glfwWin.DepthBits = x;
glGetIntegerv( GL_STENCIL_BITS, &x );
_glfwWin.StencilBits = x;
glGetIntegerv( GL_ACCUM_RED_BITS, &x );
_glfwWin.AccumRedBits = x;
glGetIntegerv( GL_ACCUM_GREEN_BITS, &x );
_glfwWin.AccumGreenBits = x;
glGetIntegerv( GL_ACCUM_BLUE_BITS, &x );
_glfwWin.AccumBlueBits = x;
glGetIntegerv( GL_ACCUM_ALPHA_BITS, &x );
_glfwWin.AccumAlphaBits = x;
glGetIntegerv( GL_AUX_BUFFERS, &x );
_glfwWin.AuxBuffers = x;
glGetBooleanv( GL_AUX_BUFFERS, &b );
_glfwWin.Stereo = b ? GL_TRUE : GL_FALSE;
// Get ModeID information (refresh rate)
_glfwGetModeIDInfo( _glfwWin.ModeID, NULL, NULL, NULL, NULL, NULL,
&refresh );
_glfwWin.RefreshRate = refresh;
}
//========================================================================
// _glfwPlatformPollEvents() - Poll for new window and input events
//========================================================================
void _glfwPlatformPollEvents( void )
{
int winclosed;
// Process all pending window events
winclosed = GL_FALSE;
if( _glfwProcessEvents() )
{
winclosed = GL_TRUE;
}
// Was there a window close request?
if( winclosed && _glfwWin.WindowCloseCallback )
{
// Check if the program wants us to close the window
winclosed = _glfwWin.WindowCloseCallback();
}
if( winclosed )
{
glfwCloseWindow();
}
}
//========================================================================
// _glfwPlatformWaitEvents() - Wait for new window and input events
//========================================================================
void _glfwPlatformWaitEvents( void )
{
// Wait for new events
Wait( 1L << _glfwWin.Window->UserPort->mp_SigBit );
// Poll new events
_glfwPlatformPollEvents();
}
//========================================================================
// _glfwPlatformHideMouseCursor() - Hide mouse cursor (lock it)
//========================================================================
void _glfwPlatformHideMouseCursor( void )
{
// We only allow this under fullscreen right now, since we can't rely
// on the pointer position in windowed mode! Perhaps it's possible to
// "steal" the mouse with input.device or something...?
if( !_glfwWin.PointerHidden && _glfwWin.Fullscreen )
{
// Allocate chip memory for the blank mouse pointer
_glfwWin.PointerSprite = AllocVec( 128, MEMF_CHIP | MEMF_CLEAR );
if( _glfwWin.PointerSprite )
{
// Switch to blank/transparent pointer
SetPointer( _glfwWin.Window, (UWORD *) _glfwWin.PointerSprite,
1, 1, 0, 0 );
_glfwWin.PointerHidden = 1;
// Switch to mouse delta movement
Forbid();
_glfwWin.Window->IDCMPFlags |= IDCMP_DELTAMOVE;
Permit();
}
}
}
//========================================================================
// _glfwPlatformShowMouseCursor() - Show mouse cursor (unlock it)
//========================================================================
void _glfwPlatformShowMouseCursor( void )
{
if( _glfwWin.PointerHidden )
{
// Switch to absolute mouse movement
Forbid();
_glfwWin.Window->IDCMPFlags &= (0xFFFFFFFF^IDCMP_DELTAMOVE);
Permit();
// Change back to normal pointer
ClearPointer( _glfwWin.Window );
if( _glfwWin.PointerSprite )
{
FreeVec( _glfwWin.PointerSprite );
_glfwWin.PointerSprite = NULL;
}
_glfwWin.PointerHidden = 0;
}
}
//========================================================================
// _glfwPlatformSetMouseCursorPos() - Set physical mouse cursor position
//========================================================================
void _glfwPlatformSetMouseCursorPos( int x, int y )
{
struct IEPointerPixel ppxl;
struct InputEvent event;
// Adjust coordinates to window client area upper left corner
x += _glfwWin.Window->LeftEdge;
y += _glfwWin.Window->TopEdge;
/* Set up IEPointerPixel fields */
ppxl.iepp_Screen = _glfwWin.Screen;
ppxl.iepp_Position.X = x;
ppxl.iepp_Position.Y = y;
/* Set up InputEvent fields */
event.ie_EventAddress = (APTR)&ppxl; /* IEPointerPixel */
event.ie_NextEvent = NULL;
event.ie_Class = IECLASS_NEWPOINTERPOS; /* new mouse pos */
event.ie_SubClass = IESUBCLASS_PIXEL; /* on pixel */
event.ie_Code = IECODE_NOBUTTON;
event.ie_Qualifier = 0; /* absolute pos */
/* Set up I/O request */
_glfwWin.InputIO->io_Data = (APTR)&event;
_glfwWin.InputIO->io_Length = sizeof(struct InputEvent);
_glfwWin.InputIO->io_Command = IND_WRITEEVENT;
/* Perform I/O (move mouse cursor) */
DoIO( (struct IORequest *)_glfwWin.InputIO );
}

View File

@ -0,0 +1,337 @@
//========================================================================
// GLFW - An OpenGL framework
// File: platform.h
// Platforms: AmigaOS, MorphOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef _platform_h_
#define _platform_h_
// First of all: a file that hides compiler specific stuff
#include "SDI_compiler.h"
// This is the AmigaOS version of GLFW
#define _GLFW_AMIGAOS
// Are we compiling for MorphOS?
#if defined(__MORPHOS__) || defined(MORPHOS)
#define _GLFW_MORPHOS
#endif
// Mesa/OpenGL flavour (we only support StormMesa at the moment)
#if !defined(_GLFW_STORMMESA)
#define _GLFW_STORMMESA
#endif
// Include files
#include <exec/exec.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <dos/dosextens.h>
#include <intuition/intuition.h>
#include <graphics/displayinfo.h>
#include <graphics/rastport.h>
#include <devices/timer.h>
#include <devices/keymap.h>
#include <devices/input.h>
#include <devices/inputevent.h>
#include <devices/gameport.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/timer.h>
#include <proto/keymap.h>
#include <proto/utility.h>
#include <clib/alib_protos.h>
// Amiga Mesa/OpenGL implementation dependent include
#ifdef _GLFW_STORMMESA
#include <GL/Amigamesa.h>
#endif
// MorphOS support
#ifdef _GLFW_MORPHOS
#include <emul/emulinterface.h>
#endif
// GLFW+GL+GLU defines
#ifdef __GNUC__
#include "../../include/GL/glfw.h"
#else
#include "//include/GL/glfw.h"
#endif
// Stack size for each thread (in bytes)
#define _GLFW_TASK_STACK_SIZE 50000
//========================================================================
// Global variables (GLFW internals)
//========================================================================
//------------------------------------------------------------------------
// Shared libraries
//------------------------------------------------------------------------
#if defined( _init_c_ )
struct GfxBase * GfxBase;
struct IntuitionBase * IntuitionBase;
struct Library * KeymapBase;
struct UtilityBase * UtilityBase;
struct Device * TimerBase;
#endif
//------------------------------------------------------------------------
// Window structure
//------------------------------------------------------------------------
typedef struct _GLFWwin_struct _GLFWwin;
struct _GLFWwin_struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// User callback functions
GLFWwindowsizefun WindowSizeCallback;
GLFWwindowclosefun WindowCloseCallback;
GLFWwindowrefreshfun WindowRefreshCallback;
GLFWmousebuttonfun MouseButtonCallback;
GLFWmouseposfun MousePosCallback;
GLFWmousewheelfun MouseWheelCallback;
GLFWkeyfun KeyCallback;
GLFWcharfun CharCallback;
// User selected window settings
int Fullscreen; // Fullscreen flag
int MouseLock; // Mouse-lock flag
int AutoPollEvents; // Auto polling flag
int SysKeysDisabled; // System keys disabled flag
int WindowNoResize; // Resize- and maximize gadgets disabled flag
// Window status & parameters
int Opened; // Flag telling if window is opened or not
int Active; // Application active flag
int Iconified; // Window iconified flag
int Width, Height; // Window width and heigth
int Accelerated; // GL_TRUE if window is HW accelerated
int RedBits;
int GreenBits;
int BlueBits;
int AlphaBits;
int DepthBits;
int StencilBits;
int AccumRedBits;
int AccumGreenBits;
int AccumBlueBits;
int AccumAlphaBits;
int AuxBuffers;
int Stereo;
int RefreshRate; // Vertical monitor refresh rate
// Extensions & OpenGL version
int Has_GL_SGIS_generate_mipmap;
int Has_GL_ARB_texture_non_power_of_two;
int GLVerMajor,GLVerMinor;
// ========= PLATFORM SPECIFIC PART ======================================
// Platform specific window resources
struct Screen *Screen; // Screen handle
struct Window *Window; // Window handle
ULONG ModeID; // ModeID
APTR PointerSprite; // Memory for blank pointer sprite
int PointerHidden; // Is pointer hidden?
struct MsgPort *InputMP; // Message port (pointer movement)
struct IOStdReq *InputIO; // I/O request (pointer movement)
// Mesa/OpenGL flavour specific
#ifdef _GLFW_STORMMESA
struct amigamesa_context *Context; // GL context handle
#endif
// Platform specific extensions
// Various platform specific internal variables
};
GLFWGLOBAL _GLFWwin _glfwWin;
//------------------------------------------------------------------------
// User input status (most of this should go in _GLFWwin)
//------------------------------------------------------------------------
GLFWGLOBAL struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Mouse status
int MousePosX, MousePosY;
int WheelPos;
char MouseButton[ GLFW_MOUSE_BUTTON_LAST+1 ];
// Keyboard status
char Key[ GLFW_KEY_LAST+1 ];
int LastChar;
// User selected settings
int StickyKeys;
int StickyMouseButtons;
int KeyRepeat;
// ========= PLATFORM SPECIFIC PART ======================================
// Platform specific internal variables
int MouseMoved, OldMouseX, OldMouseY;
} _glfwInput;
//------------------------------------------------------------------------
// Timer status
//------------------------------------------------------------------------
GLFWGLOBAL struct {
struct MsgPort *TimerMP;
struct timerequest *TimerIO;
double Resolution;
long long t0;
} _glfwTimer;
//------------------------------------------------------------------------
// Thread record (one for each thread)
//------------------------------------------------------------------------
typedef struct _GLFWthread_struct _GLFWthread;
struct _GLFWthread_struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Pointer to previous and next threads in linked list
_GLFWthread *Previous, *Next;
// GLFW user side thread information
GLFWthread ID;
// ========= PLATFORM SPECIFIC PART ======================================
// System side thread information
GLFWthreadfun Function;
void *Arg;
struct Process *AmiProc;
struct Task *AmiTask;
// "Wait for" object. Can be a thread, condition variable or NULL.
void *WaitFor;
int WaitSig;
// MorphOS support
#ifdef _GLFW_MORPHOS
struct EmulLibEntry mosEmulLibEntry;
#endif
};
//------------------------------------------------------------------------
// General thread information
//------------------------------------------------------------------------
GLFWGLOBAL struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Next thread ID to use (increments for every created thread)
GLFWthread NextID;
// First thread in linked list (always the main thread)
_GLFWthread First;
// ========= PLATFORM SPECIFIC PART ======================================
// Critical section lock
struct SignalSemaphore CriticalSection;
// Next condition variable ID (decrements for every created cond)
unsigned int NextCondID;
} _glfwThrd;
//------------------------------------------------------------------------
// Joystick information & state
//------------------------------------------------------------------------
GLFWGLOBAL struct {
int Present;
int GameDeviceOpen;
struct IOStdReq *GameIO;
struct MsgPort *GameMP;
struct InputEvent GameEvent;
float Axis[ 2 ];
unsigned char Button[ 2 ];
} _glfwJoy;
//========================================================================
// Macros for encapsulating critical code sections (i.e. making parts
// of GLFW thread safe)
//========================================================================
// Thread list management
#define ENTER_THREAD_CRITICAL_SECTION ObtainSemaphore( &_glfwThrd.CriticalSection );
#define LEAVE_THREAD_CRITICAL_SECTION ReleaseSemaphore( &_glfwThrd.CriticalSection );
//========================================================================
// Prototypes for platform specific internal functions
//========================================================================
// Time
int _glfwInitTimer( void );
void _glfwTerminateTimer( void );
// Fullscreen
int _glfwOpenScreen( int *width, int *height, int *r, int *g, int *b,
int refresh );
int _glfwGetClosestVideoMode( int *w, int *h, int *r, int *g, int *b,
int refresh );
void _glfwGetModeIDInfo( ULONG ModeID, int *w, int *h, int *r, int *g,
int *b, int *refresh );
// Joystick
void _glfwInitJoysticks( void );
void _glfwTerminateJoysticks( void );
#endif // _platform_h_

View File

@ -0,0 +1,146 @@
##########################################################################
# Makefile for GLFW on DOS using DJGPP.
#-------------------------------------------------------------------------
# To compile GLFW using this makefile, run:
# make -f Makefile.dos.djgpp
# NOTE: You need long filename support (e.g. compile under Windows9x or
# use a LFN driver such as DOSLFN)
##########################################################################
##########################################################################
# Default: Build static library version of GLFW
##########################################################################
default: libglfw.a
##########################################################################
# GLFW version
##########################################################################
VERMAJOR = 2
VERMINOR = 4
##########################################################################
# Compiler settings
##########################################################################
CC = gcc
CFLAGS = -c -I. -I.. -Wall -Os
# Some modules should be optimized for speed (e.g. image decoding)
CFLAGS_SPEED = -c -I. -I.. -Wall -O3 -ffast-math
##########################################################################
# Library builder settings
##########################################################################
MKLIB = ar
LIBFLAGS = -rcs
##########################################################################
# Object files which are part of the GLFW library
##########################################################################
OBJS = \
enable.o \
fullscreen.o \
glext.o \
image.o \
init.o \
input.o \
joystick.o \
tga.o \
thread.o \
time.o \
window.o \
dos_enable.o \
dos_events.o \
dos_fullscreen.o \
dos_glext.o \
dos_init.o \
dos_irq.o \
dos_joystick.o \
dos_keyboard.o \
dos_mouse.o \
dos_thread.o \
dos_time.o \
dos_window.o
##########################################################################
# Rule for building library
##########################################################################
libglfw.a: $(OBJS)
$(MKLIB) $(LIBFLAGS) $@ $(OBJS)
##########################################################################
# Rules for building library object files
##########################################################################
enable.o: ..\\enable.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ ..\\enable.c
fullscreen.o: ..\\fullscreen.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ ..\\fullscreen.c
glext.o: ..\\glext.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ ..\\glext.c
image.o: ..\\image.c ..\\internal.h platform.h
$(CC) $(CFLAGS_SPEED) -o $@ ..\\image.c
init.o: ..\\init.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ ..\\init.c
input.o: ..\\input.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ ..\\input.c
joystick.o: ..\\joystick.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ ..\\joystick.c
tga.o: ..\\tga.c ..\\internal.h platform.h
$(CC) $(CFLAGS_SPEED) -o $@ ..\\tga.c
thread.o: ..\\thread.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ ..\\thread.c
time.o: ..\\time.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ ..\\time.c
window.o: ..\\window.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ ..\\window.c
dos_enable.o: dos_enable.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ dos_enable.c
dos_events.o: dos_events.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ dos_events.c
dos_fullscreen.o: dos_fullscreen.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ dos_fullscreen.c
dos_glext.o: dos_glext.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ dos_glext.c
dos_init.o: dos_init.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ dos_init.c
dos_irq.o: dos_irq.s ..\\internal.h platform.h
$(CC) $(CFLAGS) -x assembler-with-cpp -o $@ dos_irq.s
dos_joystick.o: dos_joystick.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ dos_joystick.c
dos_keyboard.o: dos_keyboard.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ dos_keyboard.c
dos_mouse.o: dos_mouse.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ dos_mouse.c
dos_thread.o: dos_thread.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ dos_thread.c
dos_time.o: dos_time.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ dos_time.c
dos_window.o: dos_window.c ..\\internal.h platform.h
$(CC) $(CFLAGS) -o $@ dos_window.c

View File

@ -0,0 +1,51 @@
//========================================================================
// GLFW - An OpenGL framework
// File: dos_enable.c
// Platform: DOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformEnableSystemKeys() - Enable system keys
// _glfwPlatformDisableSystemKeys() - Disable system keys
//========================================================================
void _glfwPlatformEnableSystemKeys( void )
{
// Not supported under DOS (yet)
}
void _glfwPlatformDisableSystemKeys( void )
{
// Not supported under DOS (yet)
}

View File

@ -0,0 +1,173 @@
//========================================================================
// GLFW - An OpenGL framework
// File: dos_events.c
// Platform: DOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//========================================================================
// Global variables
//========================================================================
// Event buffer
#define _GLFW_EVENT_BUFFER_SIZE 1024
static volatile struct {
volatile int Start, End;
volatile _GLFWdosevent *Event;
} _glfwEventBuffer;
static int _glfwEventsInitialized = 0;
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwWaitNextEvent() - Wait for an event to appear in the event FIFO
// NOTE: Must not be called from an interrupt routine
//========================================================================
void _glfwWaitNextEvent( void )
{
int noevent = 1;
while( noevent )
{
DISABLE();
noevent = ( _glfwEventBuffer.Start == _glfwEventBuffer.End );
ENABLE();
// Wait for an interrupt to happen?...
}
}
//========================================================================
// _glfwGetNextEvent() - Get an event from the event FIFO
// NOTE: Must not be called from an interrupt routine
//========================================================================
int _glfwGetNextEvent( _GLFWdosevent *event )
{
DISABLE();
if( _glfwEventBuffer.Start == _glfwEventBuffer.End )
{
ENABLE();
return 0;
}
*event = _glfwEventBuffer.Event[ _glfwEventBuffer.Start ++ ];
if( _glfwEventBuffer.Start >= _GLFW_EVENT_BUFFER_SIZE )
{
_glfwEventBuffer.Start = 0;
}
ENABLE();
return 1;
}
//========================================================================
// _glfwPostDOSEvent() - Put an event onto the event FIFO
// NOTE: Must only be called from an interrupt routine
//========================================================================
void _glfwPostDOSEvent( _GLFWdosevent *event )
{
// Add event
_glfwEventBuffer.Event[ _glfwEventBuffer.End ++ ] = *event;
// End of FIFO buffer?
if( _glfwEventBuffer.End >= _GLFW_EVENT_BUFFER_SIZE )
_glfwEventBuffer.End = 0;
// If the buffer is full, drop the oldest event
if( _glfwEventBuffer.End == _glfwEventBuffer.Start)
{
_glfwEventBuffer.Start ++;
if( _glfwEventBuffer.Start >= _GLFW_EVENT_BUFFER_SIZE )
_glfwEventBuffer.Start = 0;
}
} ENDOFUNC(_glfwPostDOSEvent)
//========================================================================
// _glfwInitEvents() - Initialize event management functions and the FIFO
//========================================================================
int _glfwInitEvents( void )
{
int fifosize;
// Allocate memory for the event FIFO buffer
fifosize = _GLFW_EVENT_BUFFER_SIZE * sizeof(_GLFWdosevent);
_glfwEventBuffer.Event = malloc( fifosize );
if( !_glfwEventBuffer.Event )
{
return 0;
}
// Lock data & functions
LOCKBUFF( _glfwEventBuffer.Event, fifosize );
LOCKDATA( _glfwEventBuffer );
LOCKFUNC( _glfwPostDOSEvent );
// Initialize event FIFO
_glfwEventBuffer.Start = _glfwEventBuffer.End = 0;
_glfwEventsInitialized = 1;
return 1;
}
//========================================================================
// _glfwTerminateEvents() - Terminate event management
//========================================================================
void _glfwTerminateEvents( void )
{
if( !_glfwEventsInitialized )
{
return;
}
_glfwEventsInitialized = 0;
// Free memory for the event FIFO buffer
if( _glfwEventBuffer.Event )
{
free( (void *) _glfwEventBuffer.Event );
_glfwEventBuffer.Event = NULL;
}
}

View File

@ -0,0 +1,101 @@
//========================================================================
// GLFW - An OpenGL framework
// File: dos_fullscreen.c
// Platform: DOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwBPP2RGB() - Convert BPP to RGB bits (based on "best guess")
//========================================================================
static void _glfwBPP2RGB( int bpp, int *r, int *g, int *b )
{
int delta;
int bpp2;
// Special case: bpp = 32
if( bpp == 32 ) bpp = 24;
// Convert "bits per pixel" to red, green & blue sizes
*r = *g = *b = bpp / 3;
delta = bpp - (*r * 3);
if( delta >= 1 )
{
*g = *g + 1;
}
if( delta == 2 )
{
*r = *r + 1;
}
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformGetVideoModes() - List available video modes
//========================================================================
int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )
{
if( maxcount <= 0 ) return 0;
// Dummy...
list[0].Width = 640;
list[0].Height = 480;
list[0].RedBits = 5;
list[0].GreenBits = 6;
list[0].BlueBits = 5;
return 1;
}
//========================================================================
// _glfwPlatformGetDesktopMode() - Get the desktop video mode
//========================================================================
void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )
{
// Dummy...
mode->Width = 640;
mode->Height = 480;
mode->RedBits = 5;
mode->GreenBits = 6;
mode->BlueBits = 5;
}

View File

@ -0,0 +1,59 @@
//========================================================================
// GLFW - An OpenGL framework
// File: dos_glext.c
// Platform: DOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformExtensionSupported() - Check if an OpenGL extension is
// available at runtime
//========================================================================
int _glfwPlatformExtensionSupported( const char *extension )
{
// TODO
return GL_FALSE;
}
//========================================================================
// _glfwPlatformGetProcAddress() - Get the function pointer to an OpenGL
// function
//========================================================================
void * _glfwPlatformGetProcAddress( const char *procname )
{
// TODO
return NULL;
}

View File

@ -0,0 +1,105 @@
//========================================================================
// GLFW - An OpenGL framework
// File: dos_init.c
// Platform: DOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwTerminate_atexit() - Terminate GLFW when exiting application
//========================================================================
void _glfwTerminate_atexit( void )
{
glfwTerminate();
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformInit() - Initialize various GLFW state
//========================================================================
int _glfwPlatformInit( void )
{
// Initialize thread package
if( !_glfwInitThreads() )
{
return GL_FALSE;
}
// Start the timer
if( !_glfwInitTimer() )
{
_glfwTerminateThreads();
return GL_FALSE;
}
// Initialize joysticks
_glfwInitJoysticks();
// Install atexit() routine
atexit( _glfwTerminate_atexit );
return GL_TRUE;
}
//========================================================================
// _glfwPlatformTerminate() - Close window and kill all threads
//========================================================================
int _glfwPlatformTerminate( void )
{
// Only the main thread is allowed to do this...
// TODO
// Close OpenGL window
glfwCloseWindow();
// Terminate joysticks
_glfwTerminateJoysticks();
// Kill timer
_glfwTerminateTimer();
// Kill thread package
_glfwTerminateThreads();
return GL_TRUE;
}

246
libs/glfw/lib/dos/dos_irq.s Normal file
View File

@ -0,0 +1,246 @@
//========================================================================
// GLFW - An OpenGL framework
// File: dos_irq.s
// Platform: DOS
// API version: 2.4
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2004 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
.file "dos_irq.S"
.text
#define IRQ_STACK_SIZE 16384
#define IRQ_WRAPPER_LEN (__irq_wrapper_1-__irq_wrapper_0)
#define IRQ_OLD (__irq_old_0-__irq_wrapper_0)
#define IRQ_HOOK (__irq_hook_0-__irq_wrapper_0)
#define IRQ_STACK (__irq_stack_0-__irq_wrapper_0)
//========================================================================
// common
//========================================================================
.balign 4
common:
movw $0x0400, %ax
int $0x31
movl %ss:8(%ebp), %ebx
cmpl $15, %ebx
jbe 0f
fail:
orl $-1, %eax
popl %edi
popl %ebx
leave
ret
0:
movl %ebx, %edi
imull $IRQ_WRAPPER_LEN, %edi
addl $__irq_wrapper_0, %edi
cmpb $7, %bl
jbe 1f
movb %dl, %dh
subb $8, %dh
1:
addb %dh, %bl
ret
//========================================================================
// _glfwInstallDOSIrq()
//========================================================================
.balign 4
.global __glfwInstallDOSIrq
__glfwInstallDOSIrq:
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %edi
call common
cmpl $0, IRQ_HOOK(%edi)
jne fail
pushl $IRQ_WRAPPER_LEN
pushl %edi
call __go32_dpmi_lock_code
addl $8, %esp
testl %eax, %eax
jnz fail
/* OLD >>
pushl $IRQ_STACK_SIZE
call _pc_malloc
popl %edx
testl %eax, %eax
jz fail
addl %edx, %eax
movl %eax, IRQ_STACK(%edi)
<< OLD */
/* MG: NEW >> */
pushl $IRQ_STACK_SIZE
call _malloc
popl %edx
testl %eax, %eax
jz fail
pushl %edx
pushl %eax
call __go32_dpmi_lock_data
addl $8, %esp
testl %eax, %eax
jnz fail
subl $8, %esp
popl %eax
popl %edx
addl %edx, %eax
movl %eax, IRQ_STACK(%edi)
/* << NEW */
movl ___djgpp_ds_alias, %eax
movl %eax, IRQ_STACK+4(%edi)
movl %ss:12(%ebp), %eax
movl %eax, IRQ_HOOK(%edi)
movw $0x0204, %ax
int $0x31
movl %edx, IRQ_OLD(%edi)
movw %cx, IRQ_OLD+4(%edi)
movw $0x0205, %ax
movl %edi, %edx
movl %cs, %ecx
int $0x31
done:
xorl %eax, %eax
popl %edi
popl %ebx
leave
ret
//========================================================================
// _glfwRemoveDOSIrq()
//========================================================================
.balign 4
.global __glfwRemoveDOSIrq
__glfwRemoveDOSIrq:
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %edi
call common
cmpl $0, IRQ_HOOK(%edi)
je fail
movl $0, IRQ_HOOK(%edi)
movw $0x0205, %ax
movl IRQ_OLD(%edi), %edx
movl IRQ_OLD+4(%edi), %ecx
int $0x31
movl IRQ_STACK(%edi), %eax
subl $IRQ_STACK_SIZE, %eax
pushl %eax
call _free
popl %eax
jmp done
//========================================================================
// IRQ wrapper code for all 16 different IRQs
//========================================================================
#define WRAPPER(x) ; \
.balign 4 ; \
__irq_wrapper_##x: ; \
pushal ; \
pushl %ds ; \
pushl %es ; \
pushl %fs ; \
pushl %gs ; \
movl %ss, %ebx ; \
movl %esp, %esi ; \
lss %cs:__irq_stack_##x, %esp ; \
pushl %ss ; \
pushl %ss ; \
popl %es ; \
popl %ds ; \
movl ___djgpp_dos_sel, %fs ; \
pushl %fs ; \
popl %gs ; \
call *__irq_hook_##x ; \
movl %ebx, %ss ; \
movl %esi, %esp ; \
testl %eax, %eax ; \
popl %gs ; \
popl %fs ; \
popl %es ; \
popl %ds ; \
popal ; \
jz __irq_ignore_##x ; \
__irq_bypass_##x: ; \
ljmp *%cs:__irq_old_##x ; \
__irq_ignore_##x: ; \
iret ; \
.balign 4 ; \
__irq_old_##x: ; \
.long 0, 0 ; \
__irq_hook_##x: ; \
.long 0 ; \
__irq_stack_##x: ; \
.long 0, 0
WRAPPER(0);
WRAPPER(1);
WRAPPER(2);
WRAPPER(3);
WRAPPER(4);
WRAPPER(5);
WRAPPER(6);
WRAPPER(7);
WRAPPER(8);
WRAPPER(9);
WRAPPER(10);
WRAPPER(11);
WRAPPER(12);
WRAPPER(13);
WRAPPER(14);
WRAPPER(15);

View File

@ -0,0 +1,94 @@
//========================================================================
// GLFW - An OpenGL framework
// File: dos_joystick.c
// Platform: DOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwInitJoysticks() - Initialize joystick interface
//========================================================================
void _glfwInitJoysticks( void )
{
// TODO
}
//========================================================================
// _glfwTerminateJoysticks() - Close all opened joystick handles
//========================================================================
void _glfwTerminateJoysticks( void )
{
// TODO
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformGetJoystickParam() - Determine joystick capabilities
//========================================================================
int _glfwPlatformGetJoystickParam( int joy, int param )
{
// TODO
return 0;
}
//========================================================================
// _glfwPlatformGetJoystickPos() - Get joystick axis positions
//========================================================================
int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )
{
// TODO
return 0;
}
//========================================================================
// _glfwPlatformGetJoystickButtons() - Get joystick button states
//========================================================================
int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons,
int numbuttons )
{
// TODO
return 0;
}

View File

@ -0,0 +1,694 @@
//========================================================================
// GLFW - An OpenGL framework
// File: dos_keyboard.c
// Platform: DOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//========================================================================
// Most of the code in this source file is based on two sources of
// information:
// 1) The Allegro DOS keyboard driver (allegro\src\dos\dkeybd.c)
// 2) The document "IBM PC KEYBOARD INFORMATION FOR SOFTWARE DEVELOPERS"
// by Chris Giese.
//========================================================================
//========================================================================
// Unicode in GLFW for DOS
// =======================
//
// Keyboard mapping tables in GLFW for DOS use Unicode encoding. The codes
// are 16-bit unsigned integers, and thus do not cover the entire Unicode
// standard (but a great deal is covered).
//
// Keys or characters that are not supported by GLFW (for instance the
// PrtScr or Windows keys that are found on most PC keyboards) are coded
// with 0xFFFF ("not a character" according to the Unicode standard).
//
// GLFW special keys, as defined in glfw.h (e.g. GLFW_KEY_LSHIFT) are
// encoded in the private area of the Unicode standard (i.e. codes in the
// range E000-F8FF). The encoding is as follows:
//
// unicode = 0xE000 + glfw_key - GLFW_KEY_SPECIAL;
//
// Every key in the keyboard matrix has a description consisting of four
// entries: Normal, Shift, Caps, and AltGr.
//========================================================================
//========================================================================
// Definitions
//========================================================================
// Keyboard interrupt number
#define KEYB_IRQ 1
// Qualifier flags
#define QUAL_SCROLOCK 0x0001 // Same bits as for controller cmd 0xED
#define QUAL_NUMLOCK 0x0002 // (set leds)
#define QUAL_CAPSLOCK 0x0004 // --"--
#define QUAL_LSHIFT 0x0008
#define QUAL_RSHIFT 0x0010
#define QUAL_LALT 0x0020
#define QUAL_RALT 0x0040
#define QUAL_LCTRL 0x0080
#define QUAL_RCTRL 0x0100
// Qualifier groups
#define QUAL_MODIFIERS (QUAL_LSHIFT|QUAL_RSHIFT|QUAL_LALT|QUAL_RALT|\
QUAL_LCTRL|QUAL_RCTRL)
#define QUAL_LEDS (QUAL_SCROLOCK|QUAL_NUMLOCK|QUAL_CAPSLOCK)
// Additional non-GLFW keys, defined here for internal processing only
#define GLFW_KEY_CAPSLOCK (GLFW_KEY_SPECIAL+0x0200)
#define GLFW_KEY_NUMLOCK (GLFW_KEY_SPECIAL+0x0201)
#define GLFW_KEY_SCROLOCK (GLFW_KEY_SPECIAL+0x0202)
#define GLFW_KEY_PAUSE (GLFW_KEY_SPECIAL+0x0203)
// Keymap entry definition
struct key {
unsigned short Normal, Caps, Shift, AltGr;
};
// Keymap entry macros
#define NOCHAR(x) {x+0xDF00,x+0xDF00,x+0xDF00,x+0xDF00}
#define UNDEFINED {0xFFFF,0xFFFF,0xFFFF,0xFFFF}
//========================================================================
// Global variables
//========================================================================
static struct {
int volatile KeyEnhanced, KeyPauseLoop, Qualifiers;
int LedsOK;
int Interrupt;
} _glfwKeyDrv;
static int _glfwKeyboardInstalled = 0;
//========================================================================
// scancode_to_key_us[] - Mapping table for US keyboard layout (XT)
//========================================================================
static struct key scancode_to_key_us[256] =
{
/* Standard hardware scancodes */
/* 0x00 */ UNDEFINED, NOCHAR(GLFW_KEY_ESC),
/* 0x02 */ {'1','1','!',0xFFFF}, {'2','2','@',0xFFFF},
/* 0x04 */ {'3','3','#',0xFFFF}, {'4','4','$',0xFFFF},
/* 0x06 */ {'5','5','%',0xFFFF}, {'6','6','^',0xFFFF},
/* 0x08 */ {'7','7','&',0xFFFF}, {'8','8','*',0xFFFF},
/* 0x0A */ {'9','9','(',0xFFFF}, {'0','0',')',0xFFFF},
/* 0x0C */ {'-','-','_',0xFFFF}, {'=','=','+',0xFFFF},
/* 0x0E */ NOCHAR(GLFW_KEY_BACKSPACE), NOCHAR(GLFW_KEY_TAB),
/* 0x10 */ {'q','Q','Q',0xFFFF}, {'w','W','W',0xFFFF},
/* 0x12 */ {'e','E','E',0xFFFF}, {'r','R','R',0xFFFF},
/* 0x14 */ {'t','T','T',0xFFFF}, {'y','Y','Y',0xFFFF},
/* 0x16 */ {'u','U','U',0xFFFF}, {'i','I','I',0xFFFF},
/* 0x18 */ {'o','O','O',0xFFFF}, {'p','P','P',0xFFFF},
/* 0x1A */ {'[','[','{',0xFFFF}, {']',']','}',0xFFFF},
/* 0x1C */ NOCHAR(GLFW_KEY_ENTER), NOCHAR(GLFW_KEY_LCTRL),
/* 0x1E */ {'a','A','A',0xFFFF}, {'s','S','S',0xFFFF},
/* 0x20 */ {'d','D','D',0xFFFF}, {'f','F','F',0xFFFF},
/* 0x22 */ {'g','G','G',0xFFFF}, {'h','H','H',0xFFFF},
/* 0x24 */ {'j','J','J',0xFFFF}, {'k','K','K',0xFFFF},
/* 0x26 */ {'l','L','L',0xFFFF}, {';',';',':',0xFFFF},
/* 0x28 */ {'\'','\'','"',0xFFFF}, {'\\','\\','|',0xFFFF},
/* 0x2A */ NOCHAR(GLFW_KEY_LSHIFT), {'\\','\\','|',0xFFFF},
/* 0x2C */ {'z','Z','Z',0xFFFF}, {'x','X','X',0xFFFF},
/* 0x2E */ {'c','C','C',0xFFFF}, {'v','V','V',0xFFFF},
/* 0x30 */ {'b','B','B',0xFFFF}, {'n','N','N',0xFFFF},
/* 0x32 */ {'m','M','M',0xFFFF}, {',',',','<',0xFFFF},
/* 0x34 */ {'.','.','>',0xFFFF}, {'/','/','?',0xFFFF},
/* 0x36 */ NOCHAR(GLFW_KEY_RSHIFT), NOCHAR(GLFW_KEY_KP_MULTIPLY),
/* 0x38 */ NOCHAR(GLFW_KEY_LALT), {' ',' ',' ',0xFFFF},
/* 0x3A */ NOCHAR(GLFW_KEY_CAPSLOCK), NOCHAR(GLFW_KEY_F1),
/* 0x3C */ NOCHAR(GLFW_KEY_F2), NOCHAR(GLFW_KEY_F3),
/* 0x3E */ NOCHAR(GLFW_KEY_F4), NOCHAR(GLFW_KEY_F5),
/* 0x40 */ NOCHAR(GLFW_KEY_F6), NOCHAR(GLFW_KEY_F7),
/* 0x42 */ NOCHAR(GLFW_KEY_F8), NOCHAR(GLFW_KEY_F9),
/* 0x44 */ NOCHAR(GLFW_KEY_F10), NOCHAR(GLFW_KEY_NUMLOCK),
/* 0x46 */ NOCHAR(GLFW_KEY_SCROLOCK), NOCHAR(GLFW_KEY_KP_7),
/* 0x48 */ NOCHAR(GLFW_KEY_KP_8), NOCHAR(GLFW_KEY_KP_9),
/* 0x4A */ NOCHAR(GLFW_KEY_KP_SUBTRACT), NOCHAR(GLFW_KEY_KP_4),
/* 0x4C */ NOCHAR(GLFW_KEY_KP_5), NOCHAR(GLFW_KEY_KP_6),
/* 0x4E */ NOCHAR(GLFW_KEY_KP_ADD), NOCHAR(GLFW_KEY_KP_1),
/* 0x50 */ NOCHAR(GLFW_KEY_KP_2), NOCHAR(GLFW_KEY_KP_3),
/* 0x52 */ NOCHAR(GLFW_KEY_KP_0), NOCHAR(GLFW_KEY_KP_DECIMAL),
/* 0x54 */ UNDEFINED, /* PRTSCR */ UNDEFINED,
/* 0x56 */ {'\\','\\','|',0xFFFF}, NOCHAR(GLFW_KEY_F11),
/* 0x58 */ NOCHAR(GLFW_KEY_F12), UNDEFINED,
/* 0x5A */ UNDEFINED, UNDEFINED, /* LWIN */
/* 0x5C */ UNDEFINED, /* RWIN */ UNDEFINED, /* MENU */
/* 0x5E */ UNDEFINED, UNDEFINED,
/* 0x60 */ UNDEFINED, UNDEFINED,
/* 0x62 */ UNDEFINED, UNDEFINED,
/* 0x64 */ UNDEFINED, UNDEFINED,
/* 0x66 */ UNDEFINED, UNDEFINED,
/* 0x68 */ UNDEFINED, UNDEFINED,
/* 0x6A */ UNDEFINED, UNDEFINED,
/* 0x6C */ UNDEFINED, UNDEFINED,
/* 0x6E */ UNDEFINED, UNDEFINED,
/* 0x70 */ UNDEFINED, /* KANA */ UNDEFINED,
/* 0x72 */ UNDEFINED, UNDEFINED, /* ABNT_C1 */
/* 0x74 */ UNDEFINED, UNDEFINED,
/* 0x76 */ UNDEFINED, UNDEFINED,
/* 0x78 */ UNDEFINED, UNDEFINED, /* CONVERT */
/* 0x7A */ UNDEFINED, UNDEFINED, /* NOCONVERT */
/* 0x7C */ UNDEFINED, UNDEFINED, /* YEN */
/* 0x7E */ UNDEFINED, UNDEFINED,
/* Extended hardware scancodes (index=scancode+0x80) */
/* 0xE000 */ UNDEFINED, NOCHAR(GLFW_KEY_ESC),
/* 0xE002 */ {'1','1','!',0xFFFF}, {'2','2','@',0xFFFF},
/* 0xE004 */ {'3','3','#',0xFFFF}, {'4','4','$',0xFFFF},
/* 0xE006 */ {'5','5','%',0xFFFF}, {'6','6','^',0xFFFF},
/* 0xE008 */ {'7','7','&',0xFFFF}, {'8','8','*',0xFFFF},
/* 0xE00A */ {'9','9','(',0xFFFF}, {'0','0',')',0xFFFF},
/* 0xE00C */ {'-','-','_',0xFFFF}, {'=','=','+',0xFFFF},
/* 0xE00E */ NOCHAR(GLFW_KEY_BACKSPACE), NOCHAR(GLFW_KEY_TAB),
/* 0xE010 */ UNDEFINED, /* CIRCUMFLEX */ UNDEFINED, /* AT */
/* 0xE012 */ UNDEFINED, /* COLON2 */ {'r','R','R',0xFFFF},
/* 0xE014 */ UNDEFINED, /* KANJI */ {'y','Y','Y',0xFFFF},
/* 0xE016 */ {'u','U','U',0xFFFF}, {'i','I','I',0xFFFF},
/* 0xE018 */ {'o','O','O',0xFFFF}, {'p','P','P',0xFFFF},
/* 0xE01A */ {'[','[','{',0xFFFF}, {']',']','}',0xFFFF},
/* 0xE01C */ NOCHAR(GLFW_KEY_KP_ENTER), NOCHAR(GLFW_KEY_RCTRL),
/* 0xE01E */ {'a','A','A',0xFFFF}, {'s','S','S',0xFFFF},
/* 0xE020 */ {'d','D','D',0xFFFF}, {'f','F','F',0xFFFF},
/* 0xE022 */ {'g','G','G',0xFFFF}, {'h','H','H',0xFFFF},
/* 0xE024 */ {'j','J','J',0xFFFF}, {'k','K','K',0xFFFF},
/* 0xE026 */ {'l','L','L',0xFFFF}, {';',';',':',0xFFFF},
/* 0xE028 */ {'\'','\'','"',0xFFFF}, {'`','`','~',0xFFFF},
/* 0xE02A */ UNDEFINED, {'\\','\\','|',0xFFFF},
/* 0xE02C */ {'z','Z','Z',0xFFFF}, {'x','X','X',0xFFFF},
/* 0xE02E */ {'c','C','C',0xFFFF}, {'v','V','V',0xFFFF},
/* 0xE030 */ {'b','B','B',0xFFFF}, {'n','N','N',0xFFFF},
/* 0xE032 */ {'m','M','M',0xFFFF}, {',',',','<',0xFFFF},
/* 0xE034 */ {'.','.','>',0xFFFF}, NOCHAR(GLFW_KEY_KP_DIVIDE),
/* 0xE036 */ UNDEFINED, UNDEFINED, /* PRTSCR */
/* 0xE038 */ NOCHAR(GLFW_KEY_RALT), {' ',' ',' ',0xFFFF},
/* 0xE03A */ NOCHAR(GLFW_KEY_CAPSLOCK), NOCHAR(GLFW_KEY_F1),
/* 0xE03C */ NOCHAR(GLFW_KEY_F2), NOCHAR(GLFW_KEY_F3),
/* 0xE03E */ NOCHAR(GLFW_KEY_F4), NOCHAR(GLFW_KEY_F5),
/* 0xE040 */ NOCHAR(GLFW_KEY_F6), NOCHAR(GLFW_KEY_F7),
/* 0xE042 */ NOCHAR(GLFW_KEY_F8), NOCHAR(GLFW_KEY_F9),
/* 0xE044 */ NOCHAR(GLFW_KEY_F10), NOCHAR(GLFW_KEY_NUMLOCK),
/* 0xE046 */ NOCHAR(GLFW_KEY_PAUSE), NOCHAR(GLFW_KEY_HOME),
/* 0xE048 */ NOCHAR(GLFW_KEY_UP), NOCHAR(GLFW_KEY_PAGEUP),
/* 0xE04A */ NOCHAR(GLFW_KEY_KP_SUBTRACT), NOCHAR(GLFW_KEY_LEFT),
/* 0xE04C */ NOCHAR(GLFW_KEY_KP_5), NOCHAR(GLFW_KEY_RIGHT),
/* 0xE04E */ NOCHAR(GLFW_KEY_KP_ADD), NOCHAR(GLFW_KEY_END),
/* 0xE050 */ NOCHAR(GLFW_KEY_DOWN), NOCHAR(GLFW_KEY_PAGEDOWN),
/* 0xE052 */ NOCHAR(GLFW_KEY_INSERT), NOCHAR(GLFW_KEY_DEL),
/* 0xE054 */ UNDEFINED, /* PRTSCR */ UNDEFINED,
/* 0xE056 */ {'\\','\\','|',0xFFFF}, NOCHAR(GLFW_KEY_F11),
/* 0xE058 */ NOCHAR(GLFW_KEY_F12), UNDEFINED,
/* 0xE05A */ UNDEFINED, UNDEFINED, /* LWIN */
/* 0xE05C */ UNDEFINED, /* RWIN */ UNDEFINED, /* MENU */
/* 0xE05E */ UNDEFINED, UNDEFINED,
/* 0xE060 */ UNDEFINED, UNDEFINED,
/* 0xE062 */ UNDEFINED, UNDEFINED,
/* 0xE064 */ UNDEFINED, UNDEFINED,
/* 0xE066 */ UNDEFINED, UNDEFINED,
/* 0xE068 */ UNDEFINED, UNDEFINED,
/* 0xE06A */ UNDEFINED, UNDEFINED,
/* 0xE06C */ UNDEFINED, UNDEFINED,
/* 0xE06E */ UNDEFINED, UNDEFINED,
/* 0xE070 */ UNDEFINED, UNDEFINED,
/* 0xE072 */ UNDEFINED, UNDEFINED,
/* 0xE074 */ UNDEFINED, UNDEFINED,
/* 0xE076 */ UNDEFINED, UNDEFINED,
/* 0xE078 */ UNDEFINED, UNDEFINED,
/* 0xE07A */ UNDEFINED, UNDEFINED,
/* 0xE07C */ UNDEFINED, UNDEFINED,
/* 0xE07E */ UNDEFINED, UNDEFINED
};
//************************************************************************
//**** Keyboard Decoding *************************************************
//************************************************************************
//========================================================================
// _glfwMapRawKey() - Map a raw scancode to a Unicode character
//========================================================================
static int _glfwMapRawKey( int scancode, int qualifiers )
{
struct key *keyvals;
int keycode;
// Get possible key codings for this scancode
keyvals = &scancode_to_key_us[ scancode ];
// Select Unicode code depending on qualifiers
if( qualifiers & QUAL_RALT )
{
keycode = keyvals->AltGr;
}
else if( qualifiers & (QUAL_LSHIFT|QUAL_RSHIFT) )
{
if( (qualifiers & QUAL_CAPSLOCK) &&
(keyvals->Normal != keyvals->Caps) )
{
keycode = keyvals->Normal;
}
else
{
keycode = keyvals->Shift;
}
}
else if( qualifiers & QUAL_CAPSLOCK )
{
keycode = keyvals->Caps;
}
else
{
keycode = keyvals->Normal;
}
// Special interpretations
if( keycode >= 0xE000 && keycode <= 0xE8FF )
{
keycode = -(keycode - 0xE000 + GLFW_KEY_SPECIAL);
}
else if( keycode == 0xFFFF )
{
keycode = 0;
}
return keycode;
} ENDOFUNC(_glfwMapRawKey)
//========================================================================
// _glfwCreateKeyEvent() - Add a keyboard event to the event FIFO
//========================================================================
static void _glfwCreateKeyEvent( int scancode, int qualifiers, int action )
{
_GLFWdosevent event;
struct key_event *key = &event.Key;
// Create event
key->Type = _GLFW_DOS_KEY_EVENT;
key->Key = _glfwMapRawKey( scancode, qualifiers );
key->KeyNoMod = _glfwMapRawKey( scancode, QUAL_CAPSLOCK );
key->Action = action;
// Post event
_glfwPostDOSEvent( &event );
} ENDOFUNC(_glfwCreateKeyEvent)
//************************************************************************
//**** Keyboard Communication ********************************************
//************************************************************************
//========================================================================
// _glfwWaitForReadReady() / _glfwWaitForWriteReady()
// Wait for the keyboard controller to set the ready-for-read/write bit
//========================================================================
static int _glfwWaitForReadReady( void )
{
int timeout = 16384;
while( (timeout>0) && (!(inportb(0x64)&1)) ) timeout--;
return timeout > 0;
} ENDOFUNC(_glfwWaitForReadReady)
static int _glfwWaitForWriteReady( void )
{
int timeout = 4096;
while( (timeout>0) && (inportb(0x64)&2) ) timeout--;
return timeout > 0;
} ENDOFUNC(_glfwWaitForWriteReady)
//========================================================================
// _glfwSendKeyboardByte() - Send a byte to the keyboard controller
//========================================================================
static int _glfwSendKeyboardByte( unsigned char data )
{
int resends = 4;
int timeout, ret;
do
{
if( !_glfwWaitForWriteReady() ) return 0;
outportb( 0x60, data );
timeout = 4096;
while( --timeout > 0 )
{
if( !_glfwWaitForReadReady() ) return 0;
ret = inportb( 0x60 );
if( ret == 0xFA ) return 1;
if( ret == 0xFE ) break;
}
}
while( (resends-- > 0) && (timeout > 0) );
return 0;
} ENDOFUNC(_glfwSendKeyboardByte)
//========================================================================
// _glfwSendKeyboardCommand() - Send a command sequence to the keyboard
//========================================================================
static int _glfwSendKeyboardCommand( unsigned char *cmd, int count )
{
int i, ok = 1;
// Force atomic keyboard communication session
if( !_glfwKeyDrv.Interrupt ) DISABLE();
// Send command sequence
for( i = 0; i < count; ++ i )
{
if( !_glfwSendKeyboardByte( cmd[i] ) )
{
ok = 0;
break;
}
}
// Send "clear output buffer, enable keyboard"
_glfwSendKeyboardByte( 0xF4 );
if( !_glfwKeyDrv.Interrupt ) ENABLE();
return ok;
} ENDOFUNC(_glfwSendKeyboardCommand)
//************************************************************************
//**** Miscellaneous Handling ********************************************
//************************************************************************
//========================================================================
// _glfwUpdateLeds() - Update keyboard leds
//========================================================================
static void _glfwUpdateLeds( int qualifiers )
{
unsigned char cmd[2];
cmd[0] = 0xED;
cmd[1] = qualifiers & 7;
_glfwSendKeyboardCommand( cmd, 2 );
} ENDOFUNC(_glfwUpdateLeds)
//************************************************************************
//**** Keyboard Interrupt Handler ****************************************
//************************************************************************
//========================================================================
// _glfwHandleCode() - Handle new scancode event
//========================================================================
static void _glfwHandleCode( int scancode, int keypress )
{
if( scancode == GLFW_KEY_PAUSE && keypress )
{
// Pause
_glfwCreateKeyEvent( GLFW_KEY_PAUSE, 0, GLFW_PRESS );
}
else if( scancode )
{
int tmp, qualifier;
// Check if this is a qualifier key
tmp = scancode_to_key_us[scancode].Normal;
tmp += GLFW_KEY_SPECIAL - 0xE000;
if( tmp == GLFW_KEY_LSHIFT ) qualifier = QUAL_LSHIFT;
else if( tmp == GLFW_KEY_RSHIFT ) qualifier = QUAL_RSHIFT;
else if( tmp == GLFW_KEY_LCTRL ) qualifier = QUAL_LCTRL;
else if( tmp == GLFW_KEY_RCTRL ) qualifier = QUAL_RCTRL;
else if( tmp == GLFW_KEY_LALT ) qualifier = QUAL_LALT;
else if( tmp == GLFW_KEY_RALT ) qualifier = QUAL_RALT;
else if( tmp == GLFW_KEY_NUMLOCK ) qualifier = QUAL_NUMLOCK;
else if( tmp == GLFW_KEY_SCROLOCK ) qualifier = QUAL_SCROLOCK;
else if( tmp == GLFW_KEY_CAPSLOCK ) qualifier = QUAL_CAPSLOCK;
else qualifier = 0;
if( keypress )
{
// Key press
if( qualifier & QUAL_MODIFIERS )
{
_glfwKeyDrv.Qualifiers |= qualifier;
}
if( !(qualifier & QUAL_LEDS) )
{
_glfwCreateKeyEvent( scancode, _glfwKeyDrv.Qualifiers,
GLFW_PRESS );
}
else
{
_glfwKeyDrv.Qualifiers ^= qualifier;
_glfwUpdateLeds( _glfwKeyDrv.Qualifiers );
}
}
else
{
// Key release
if( qualifier & QUAL_MODIFIERS )
{
_glfwKeyDrv.Qualifiers &= ~qualifier;
}
if( !(qualifier & QUAL_LEDS) )
{
_glfwCreateKeyEvent( scancode, _glfwKeyDrv.Qualifiers,
GLFW_RELEASE );
}
}
}
} ENDOFUNC(_glfwHandleCode)
//========================================================================
// _glfwKeyInterrupt() - Keyboard interrupt routine
//========================================================================
static int _glfwKeyInterrupt( void )
{
unsigned char keycode, scancode;
_glfwKeyDrv.Interrupt ++;
keycode = inportb( 0x60 );
if( keycode <= 0xE1 )
{
if( _glfwKeyDrv.KeyPauseLoop )
{
if( ! --_glfwKeyDrv.KeyPauseLoop )
_glfwHandleCode( GLFW_KEY_PAUSE, 1 );
}
else
{
switch( keycode )
{
case 0xE0:
_glfwKeyDrv.KeyEnhanced = 1;
break;
case 0xE1:
_glfwKeyDrv.KeyPauseLoop = 5;
break;
default:
scancode = keycode & 0x7F;
if( _glfwKeyDrv.KeyEnhanced )
{
scancode |= 0x80;
_glfwKeyDrv.KeyEnhanced = 0;
}
_glfwHandleCode( scancode, !(keycode & 0x80) );
}
}
}
_glfwKeyDrv.Interrupt --;
if( ((keycode==0x4F) || (keycode==0x53)) &&
(_glfwKeyDrv.Qualifiers & QUAL_LCTRL) &&
(_glfwKeyDrv.Qualifiers & QUAL_RALT) )
{
// Hack alert:
// Only SIGINT (but not Ctrl-Break) calls the destructors and will
// safely clean up
asm(
"movb $0x79,%%al\n\t"
"call ___djgpp_hw_exception\n\t"
:
:
: "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"
);
}
asm(
"inb $0x61,%%al\n\t"
"movb %%al,%%ah\n\t"
"orb $0x80,%%al\n\t"
"outb %%al,$0x61\n\t"
"xchgb %%al,%%ah\n\t"
"outb %%al,$0x61\n\t"
"movb $0x20,%%al\n\t"
"outb %%al,$0x20\n\t"
:
:
: "%eax"
);
return 0;
} ENDOFUNC(_glfwKeyInterrupt)
//************************************************************************
//**** Keyboard driver interface functions ****
//************************************************************************
//========================================================================
// _glfwInitKeyboard() - Initialize keyboard driver
//========================================================================
int _glfwInitKeyboard( void )
{
int s1, s2, s3;
if( _glfwKeyboardInstalled )
{
return 0;
}
// Init keyboard state
_glfwKeyDrv.LedsOK = 1;
_glfwKeyDrv.Interrupt = 0;
_glfwKeyDrv.KeyEnhanced = 0;
_glfwKeyDrv.KeyPauseLoop = 0;
// Lock data buffers
LOCKDATA(_glfwKeyboardInstalled);
LOCKDATA(_glfwKeyDrv);
LOCKDATA(scancode_to_key_us);
// Lock functions
LOCKFUNC(_glfwMapRawKey);
LOCKFUNC(_glfwCreateKeyEvent);
LOCKFUNC(_glfwWaitForReadReady);
LOCKFUNC(_glfwWaitForWriteReady);
LOCKFUNC(_glfwSendKeyboardByte);
LOCKFUNC(_glfwSendKeyboardCommand);
LOCKFUNC(_glfwUpdateLeds);
LOCKFUNC(_glfwHandleCode);
LOCKFUNC(_glfwKeyInterrupt);
_farsetsel( __djgpp_dos_sel );
_farnspokew( 0x41c, _farnspeekw(0x41a) );
// Get current state of key qualifiers
s1 = _farnspeekb( 0x417 );
s2 = _farnspeekb( 0x418 );
s3 = _farnspeekb( 0x496 );
_glfwKeyDrv.Qualifiers = 0;
if( s1 & 1 ) _glfwKeyDrv.Qualifiers |= QUAL_RSHIFT;
if( s1 & 2 ) _glfwKeyDrv.Qualifiers |= QUAL_LSHIFT;
if( s2 & 1 ) _glfwKeyDrv.Qualifiers |= QUAL_LCTRL;
if( s2 & 2 ) _glfwKeyDrv.Qualifiers |= QUAL_LALT;
if( s3 & 4 ) _glfwKeyDrv.Qualifiers |= QUAL_RCTRL;
if( s3 & 8 ) _glfwKeyDrv.Qualifiers |= QUAL_RALT;
if( s1 & 16 ) _glfwKeyDrv.Qualifiers |= QUAL_SCROLOCK;
if( s1 & 32 ) _glfwKeyDrv.Qualifiers |= QUAL_NUMLOCK;
if( s1 & 64 ) _glfwKeyDrv.Qualifiers |= QUAL_CAPSLOCK;
_glfwUpdateLeds( _glfwKeyDrv.Qualifiers );
// Install keyboard interrupt handler
if( _glfwInstallDOSIrq( KEYB_IRQ, _glfwKeyInterrupt ) )
{
return 0;
}
_glfwKeyboardInstalled = 1;
return 1;
}
//========================================================================
// _glfwTerminateKeyboard() - Terminate keyboard driver
//========================================================================
void _glfwTerminateKeyboard( void )
{
int s1, s2, s3;
if( !_glfwKeyboardInstalled )
{
return;
}
_glfwKeyboardInstalled = 0;
// Uninstall keyboard interrupt handler
_glfwRemoveDOSIrq( KEYB_IRQ );
_farsetsel( __djgpp_dos_sel );
_farnspokew( 0x41c, _farnspeekw(0x41a) );
// Set current state of key qualifiers
s1 = _farnspeekb( 0x417 ) & 0x80;
s2 = _farnspeekb( 0x418 ) & 0xFC;
s3 = _farnspeekb( 0x496 ) & 0xF3;
if(_glfwKeyDrv.Qualifiers & QUAL_RSHIFT) s1 |= 1;
if(_glfwKeyDrv.Qualifiers & QUAL_LSHIFT) s1 |= 2;
if(_glfwKeyDrv.Qualifiers & QUAL_LCTRL) {s2 |= 1; s1 |= 4;}
if(_glfwKeyDrv.Qualifiers & QUAL_LALT) {s2 |= 2; s1 |= 8;}
if(_glfwKeyDrv.Qualifiers & QUAL_RCTRL) {s3 |= 4; s1 |= 4;}
if(_glfwKeyDrv.Qualifiers & QUAL_RALT) {s3 |= 8; s1 |= 8;}
if(_glfwKeyDrv.Qualifiers & QUAL_SCROLOCK) s1 |= 16;
if(_glfwKeyDrv.Qualifiers & QUAL_NUMLOCK) s1 |= 32;
if(_glfwKeyDrv.Qualifiers & QUAL_CAPSLOCK) s1 |= 64;
_farnspokeb( 0x417, s1 );
_farnspokeb( 0x418, s2 );
_farnspokeb( 0x496, s3 );
_glfwUpdateLeds( _glfwKeyDrv.Qualifiers );
}

View File

@ -0,0 +1,337 @@
//========================================================================
// GLFW - An OpenGL framework
// File: dos_mouse.c
// Platform: DOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//========================================================================
// Most of the code in this source file is based on the mouse driver in
// Daniel Borca's GLUT implementation for DOS/MESA.
//========================================================================
//========================================================================
// Definitions
//========================================================================
#define _GLFW_MOUSE_STACK_SIZE 16384
// Assembler function prototypes
extern void _glfwMouseWrap( void );
extern int _glfwMouseWrap_end[];
//========================================================================
// Global variables
//========================================================================
static int _glfwMouseInstalled = 0;
static struct {
long Callback;
int Emulate3;
int OldX, OldY, OldB;
__dpmi_regs Regs;
} _glfwMouseDrv;
//************************************************************************
//**** Mouse Interrupt ***************************************************
//************************************************************************
//========================================================================
// _glfwMouseInt() - Mouse interrupt handler
//========================================================================
static void _glfwMouseInt( __dpmi_regs *r )
{
int newx, newy, dx, dy, dz, buttons;
_GLFWdosevent event;
struct mousemove_event *mousemove = &event.MouseMove;
struct mousewheel_event *mousewheel = &event.MouseWheel;
struct mousebutton_event *mousebutton = &event.MouseButton;
// Calculate mouse deltas
newx = (signed short)r->x.si;
newy = (signed short)r->x.di;
dx = newx - _glfwMouseDrv.OldX;
dy = newy - _glfwMouseDrv.OldY;
dz = (signed char)r->h.bh;
// Get mouse buttons status
buttons = r->h.bl;
// Emulate 3rd mouse button?
if( _glfwMouseDrv.Emulate3 )
{
if( (buttons & 3) == 3 )
{
buttons = 4;
}
}
// Mouse moved?
if( dx || dy )
{
mousemove->Type = _GLFW_DOS_MOUSE_MOVE_EVENT;
mousemove->DeltaX = dx;
mousemove->DeltaY = dy;
_glfwPostDOSEvent( &event );
}
// Mouse wheel moved?
if( dz )
{
mousewheel->Type = _GLFW_DOS_MOUSE_WHEEL_EVENT;
mousewheel->WheelDelta = dz;
_glfwPostDOSEvent( &event );
}
// Button state changed?
if( buttons != _glfwMouseDrv.OldB )
{
mousebutton->Type = _GLFW_DOS_MOUSE_BUTTON_EVENT;
// Left mouse button changed?
if( (_glfwMouseDrv.OldB & 1) && !(buttons & 1) )
{
mousebutton->Button = GLFW_MOUSE_BUTTON_LEFT;
mousebutton->Action = GLFW_RELEASE;
_glfwPostDOSEvent( &event );
}
else if( !(_glfwMouseDrv.OldB & 1) && (buttons & 1) )
{
mousebutton->Button = GLFW_MOUSE_BUTTON_LEFT;
mousebutton->Action = GLFW_PRESS;
_glfwPostDOSEvent( &event );
}
// Right mouse button changed?
if( (_glfwMouseDrv.OldB & 2) && !(buttons & 2) )
{
mousebutton->Button = GLFW_MOUSE_BUTTON_RIGHT;
mousebutton->Action = GLFW_RELEASE;
_glfwPostDOSEvent( &event );
}
else if( !(_glfwMouseDrv.OldB & 2) && (buttons & 2) )
{
mousebutton->Button = GLFW_MOUSE_BUTTON_RIGHT;
mousebutton->Action = GLFW_PRESS;
_glfwPostDOSEvent( &event );
}
// Middle mouse button changed?
if( (_glfwMouseDrv.OldB & 4) && !(buttons & 4) )
{
mousebutton->Button = GLFW_MOUSE_BUTTON_MIDDLE;
mousebutton->Action = GLFW_RELEASE;
_glfwPostDOSEvent( &event );
}
else if( !(_glfwMouseDrv.OldB & 4) && (buttons & 4) )
{
mousebutton->Button = GLFW_MOUSE_BUTTON_MIDDLE;
mousebutton->Action = GLFW_PRESS;
_glfwPostDOSEvent( &event );
}
}
// Remember old mouse state
_glfwMouseDrv.OldX = newx;
_glfwMouseDrv.OldY = newy;
_glfwMouseDrv.OldB = buttons;
} ENDOFUNC(_glfwMouseInt)
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwInitMouse() - Initialize mouse driver
//========================================================================
int _glfwInitMouse( void )
{
int buttons;
// Already installed?
if( _glfwMouseInstalled )
{
return 0;
}
// Reset mouse and get status
__asm("\n\
xorl %%eax, %%eax \n\
int $0x33 \n\
andl %%ebx, %%eax \n\
movl %%eax, %0 \n\
":"=g" (buttons)::"%eax", "%ebx");
if( !buttons )
{
return 0;
}
// Lock data and functions
LOCKDATA( _glfwMouseDrv );
LOCKBUFF( _glfwMouseWrap_end, 8 );
LOCKFUNC( _glfwMouseInt );
LOCKFUNC( _glfwMouseWrap );
_glfwMouseWrap_end[1] = __djgpp_ds_alias;
// Grab a locked stack
_glfwMouseWrap_end[0] = (int)malloc( _GLFW_MOUSE_STACK_SIZE );
if( _glfwMouseWrap_end[0] == NULL )
{
return 0;
}
LOCKBUFF( _glfwMouseWrap_end[0], _GLFW_MOUSE_STACK_SIZE );
// Try to hook a call-back
__asm("\n\
pushl %%ds \n\
pushl %%es \n\
movw $0x0303, %%ax \n\
pushl %%ds \n\
pushl %%cs \n\
popl %%ds \n\
popl %%es \n\
int $0x31 \n\
popl %%es \n\
popl %%ds \n\
jc 0f \n\
shll $16, %%ecx \n\
movw %%dx, %%cx \n\
movl %%ecx, %0 \n\
0: \n\
":"=g"(_glfwMouseDrv.Callback)
:"S" (_glfwMouseWrap), "D"(&_glfwMouseDrv.Regs)
:"%eax", "%ecx", "%edx");
if( !_glfwMouseDrv.Callback )
{
free( (void *)_glfwMouseWrap_end[0] );
return 0;
}
// Adjust stack
_glfwMouseWrap_end[0] += _GLFW_MOUSE_STACK_SIZE;
// Install the handler
_glfwMouseDrv.Regs.x.ax = 0x000c;
_glfwMouseDrv.Regs.x.cx = 0x7f | 0x80;
_glfwMouseDrv.Regs.x.dx = _glfwMouseDrv.Callback & 0xffff;
_glfwMouseDrv.Regs.x.es = _glfwMouseDrv.Callback >> 16;
__dpmi_int( 0x33, &_glfwMouseDrv.Regs );
// Clear mickeys
__asm __volatile ("\n\
movw $0xb, %%ax; \n\
int $0x33 \n\
":::"%eax", "%ecx", "%edx");
_glfwMouseDrv.OldX = 0;
_glfwMouseDrv.OldY = 0;
_glfwMouseDrv.OldB = 0;
// Emulate third mouse button?
_glfwMouseDrv.Emulate3 = buttons < 3;
return 1;
}
//========================================================================
// _glfwTerminateMouse() - Terminate mouse driver
//========================================================================
void _glfwTerminateMouse( void )
{
if( !_glfwMouseInstalled )
{
return;
}
__asm("\n\
movl %%edx, %%ecx \n\
shrl $16, %%ecx \n\
movw $0x0304, %%ax \n\
int $0x31 \n\
movw $0x000c, %%ax \n\
xorl %%ecx, %%ecx \n\
int $0x33 \n\
"::"d"(_glfwMouseDrv.Callback):"%eax", "%ecx");
_glfwMouseDrv.Callback = 0;
free( (void *)(_glfwMouseWrap_end[0] - _GLFW_MOUSE_STACK_SIZE) );
_glfwMouseInstalled = 0;
}
//========================================================================
// _glfwMouseWrap()
//========================================================================
// Hack alert: `_glfwMouseWrap_end' actually holds the address of stack in
// a safe data selector.
__asm("\n\
.text \n\
.p2align 5,,31 \n\
.global __glfwMouseWrap \n\
__glfwMouseWrap: \n\
cld \n\
lodsl \n\
movl %eax, %es:42(%edi) \n\
addw $4, %es:46(%edi) \n\
pushl %es \n\
movl %ss, %ebx \n\
movl %esp, %esi \n\
lss %cs:__glfwMouseWrap_end, %esp\n\
pushl %ss \n\
pushl %ss \n\
popl %es \n\
popl %ds \n\
movl ___djgpp_dos_sel, %fs \n\
pushl %fs \n\
popl %gs \n\
pushl %edi \n\
call __glfwMouseInt \n\
popl %edi \n\
movl %ebx, %ss \n\
movl %esi, %esp \n\
popl %es \n\
iret \n\
.global __glfwMouseWrap_end \n\
__glfwMouseWrap_end:.long 0, 0");

View File

@ -0,0 +1,267 @@
//========================================================================
// GLFW - An OpenGL framework
// File: dos_thread.c
// Platform: DOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwInitThreads() - Initialize GLFW thread package
//========================================================================
int _glfwInitThreads( void )
{
// TODO
_glfwThrd.First.Previous = NULL;
_glfwThrd.First.Next = NULL;
_glfwThrd.First.ID = 0;
_glfwThrd.NextID = 1;
return 1;
}
//========================================================================
// _glfwTerminateThreads() - Terminate GLFW thread package
//========================================================================
void _glfwTerminateThreads( void )
{
_GLFWthread *t, *t_next;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Kill all threads (NOTE: THE USER SHOULD WAIT FOR ALL THREADS TO
// DIE, _BEFORE_ CALLING glfwTerminate()!!!)
t = _glfwThrd.First.Next;
while( t != NULL )
{
// Get pointer to next thread
t_next = t->Next;
// Simply murder the process, no mercy!
// TODO
// Free memory allocated for this thread
free( (void *) t );
// Select next thread in list
t = t_next;
}
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformCreateThread() - Create a new thread
//========================================================================
GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )
{
// TODO
return -1;
}
//========================================================================
// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY
// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME
// SITUATIONS!
//========================================================================
void _glfwPlatformDestroyThread( GLFWthread ID )
{
_GLFWthread *t, *t_wait;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Get thread information pointer
t = _glfwGetThreadPointer( ID );
if( t == NULL )
{
LEAVE_THREAD_CRITICAL_SECTION
return;
}
// Simply murder the process, no mercy!
// TODO
// Remove thread from thread list
_glfwRemoveThread( t );
// Signal any waiting threads that the thread has died
// TODO
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
}
//========================================================================
// _glfwPlatformWaitThread() - Wait for a thread to die
//========================================================================
int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )
{
// TODO
return GL_FALSE;
}
//========================================================================
// _glfwPlatformGetThreadID() - Return the thread ID for the current
// thread
//========================================================================
GLFWthread _glfwPlatformGetThreadID( void )
{
// TODO
return 0;
}
//========================================================================
// _glfwPlatformCreateMutex() - Create a mutual exclusion object
//========================================================================
GLFWmutex _glfwPlatformCreateMutex( void )
{
// TODO
return NULL;
}
//========================================================================
// _glfwPlatformDestroyMutex() - Destroy a mutual exclusion object
//========================================================================
void _glfwPlatformDestroyMutex( GLFWmutex mutex )
{
// TODO
}
//========================================================================
// _glfwPlatformLockMutex() - Request access to a mutex
//========================================================================
void _glfwPlatformLockMutex( GLFWmutex mutex )
{
// TODO
}
//========================================================================
// _glfwPlatformUnlockMutex() - Release a mutex
//========================================================================
void _glfwPlatformUnlockMutex( GLFWmutex mutex )
{
// TODO
}
//========================================================================
// _glfwPlatformCreateCond() - Create a new condition variable object
//========================================================================
GLFWcond _glfwPlatformCreateCond( void )
{
// TODO
return NULL;
}
//========================================================================
// _glfwPlatformDestroyCond() - Destroy a condition variable object
//========================================================================
void _glfwPlatformDestroyCond( GLFWcond cond )
{
// TODO
}
//========================================================================
// _glfwPlatformWaitCond() - Wait for a condition to be raised
//========================================================================
void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,
double timeout )
{
// TODO
}
//========================================================================
// _glfwPlatformSignalCond() - Signal a condition to one waiting thread
//========================================================================
void _glfwPlatformSignalCond( GLFWcond cond )
{
// TODO
}
//========================================================================
// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting
// threads
//========================================================================
void _glfwPlatformBroadcastCond( GLFWcond cond )
{
// TODO
}
//========================================================================
// _glfwPlatformGetNumberOfProcessors() - Return the number of processors
// in the system.
//========================================================================
int _glfwPlatformGetNumberOfProcessors( void )
{
// Return number of processors online (DOS does not support multiple
// CPUs...)
return 1;
}

View File

@ -0,0 +1,309 @@
//========================================================================
// GLFW - An OpenGL framework
// File: dos_time.c
// Platform: DOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
// We use the __i386 define later in the code. Check if there are any
// other defines that hint that we are compiling for 32-bit x86.
#ifndef __i386
#if defined(__i386__) || defined(i386) || defined(X86) || defined(_M_IX86)
#define __i386
#endif
#endif // __i386
// Should we use inline x86 assembler?
#if defined(__i386) && defined(__GNUC__)
#define _USE_X86_ASM
#endif
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
// Functions for accessing upper and lower parts of 64-bit integers
// (Note: These are endian dependent, but ONLY used on x86 platforms!)
#define _HIGH(x) ((unsigned int*)&x)[1]
#define _LOW(x) *((unsigned int*)&x)
//========================================================================
// _glfwCPUID() - Execute x86 CPUID instruction
//========================================================================
#ifdef _USE_X86_ASM
static int _glfwCPUID( unsigned int ID, unsigned int *a, unsigned int *b,
unsigned int *c, unsigned int *d )
{
int has_cpuid;
unsigned int local_a, local_b, local_c, local_d;
// Inline assembly - GCC version
#if defined(__i386) && defined(__GNUC__)
// Detect CPUID support
asm(
"pushf\n\t"
"pop %%eax\n\t"
"movl %%eax,%%ebx\n\t"
"xorl $0x00200000,%%eax\n\t"
"push %%eax\n\t"
"popf\n\t"
"pushf\n\t"
"pop %%eax\n\t"
"xorl %%eax,%%ebx\n\t"
"movl %%eax,%0\n\t"
: "=m" (has_cpuid)
:
: "%eax", "%ebx"
);
if( !has_cpuid )
{
return GL_FALSE;
}
// Execute CPUID
asm(
"movl %4,%%eax\n\t"
"cpuid\n\t"
"movl %%eax,%0\n\t"
"movl %%ebx,%1\n\t"
"movl %%ecx,%2\n\t"
"movl %%edx,%3\n\t"
: "=m" (local_a), "=m" (local_b), "=m" (local_c), "=m" (local_d)
: "m" (ID)
: "%eax", "%ebx", "%ecx", "%edx"
);
#endif
// Common code for all compilers
*a = local_a;
*b = local_b;
*c = local_c;
*d = local_d;
return GL_TRUE;
}
#endif // _USE_X86_ASM
//========================================================================
// _glfwHasRDTSC() - Check for RDTSC availability AND usefulness
//========================================================================
static int _glfwHasRDTSC( void )
{
#ifdef _USE_X86_ASM
unsigned int cpu_name1, cpu_name2, cpu_name3;
unsigned int cpu_signature, cpu_brandID;
unsigned int max_base, feature_flags;
unsigned int dummy;
// Get processor vendor string (will return 0 if CPUID is not
// supported)
if( !_glfwCPUID( 0, &max_base, &cpu_name1, &cpu_name3, &cpu_name2 ) )
{
return GL_FALSE;
}
// Does the processor support base CPUID function 1?
if( max_base < 1 )
{
return GL_FALSE;
}
// Get CPU capabilities, CPU Brand ID & CPU Signature
_glfwCPUID( 1, &cpu_signature, &cpu_brandID, &dummy, &feature_flags );
// Is RDTSC supported?
if( !(feature_flags & 0x00000010) )
{
return GL_FALSE;
}
return GL_TRUE;
#else
// Not a supported compiler
return GL_FALSE;
#endif
}
//------------------------------------------------------------------------
// _RDTSC() - Get CPU cycle count using the RDTSC instruction
//------------------------------------------------------------------------
#if defined(__i386) && defined(__GNUC__)
// Read 64-bit processor Time Stamp Counter - GCC version
#define _RDTSC( hi, lo ) \
asm( \
"rdtsc\n\t" \
"movl %%edx,%0\n\t" \
"movl %%eax,%1" \
: "=m" (hi), "=m" (lo) \
: \
: "%edx", "%eax" \
);
#else
#define _RDTSC( hi, lo ) {hi=lo=0;}
#endif
//========================================================================
// _glfwInitTimer() - Initialize timer
//========================================================================
int _glfwInitTimer( void )
{
clock_t t, t1, t2;
long long c1, c2;
// Do we have RDTSC?
_glfwTimer.HasRDTSC = _glfwHasRDTSC();
if( _glfwTimer.HasRDTSC )
{
// Measure the CPU clock with the raw DOS clock (18.2 Hz)
t = clock();
while( (t1=clock()) == t );
_RDTSC( _HIGH(c1), _LOW(c1) );
t = t1+CLOCKS_PER_SEC/3;
while( (t2=clock()) < t );
_RDTSC( _HIGH(c2), _LOW(c2) );
// Calculate CPU clock period
_glfwTimer.Period = (double)(t2-t1) /
(CLOCKS_PER_SEC * (double)(c2-c1));
_RDTSC( _HIGH(_glfwTimer.t0), _LOW(_glfwTimer.t0) );
}
else
{
// Use the raw DOS clock (18.2 Hz)
_glfwTimer.Period = 1.0 / CLOCKS_PER_SEC;
_glfwTimer.t0 = clock();
}
return 1;
}
//========================================================================
// _glfwTerminateTimer() - Terminate timer
//========================================================================
void _glfwTerminateTimer( void )
{
// Nothing to do here
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformGetTime() - Return timer value in seconds
//========================================================================
double _glfwPlatformGetTime( void )
{
long long t_now;
// Get current clock count
if( _glfwTimer.HasRDTSC )
{
_RDTSC( _HIGH(t_now), _LOW(t_now) );
}
else
{
t_now = (long long) clock();
}
// Convert to seconds
return (t_now-_glfwTimer.t0) * _glfwTimer.Period;
}
//========================================================================
// _glfwPlatformSetTime() - Set timer value in seconds
//========================================================================
void _glfwPlatformSetTime( double t )
{
long long t_now;
// Get current clock count
if( _glfwTimer.HasRDTSC )
{
_RDTSC( _HIGH(t_now), _LOW(t_now) );
}
else
{
t_now = (long long) clock();
}
// Set timer
_glfwTimer.t0 = t_now - (long long)(t/_glfwTimer.Period);
}
//========================================================================
// _glfwPlatformSleep() - Put a thread to sleep for a specified amount of
// time
//========================================================================
void _glfwPlatformSleep( double time )
{
// TODO: Proper threaded version
if( time > 0 )
{
if( time < 0.001 )
{
delay( 1 );
}
else
{
delay( (unsigned int)(time*1000.0+0.5) );
}
}
}

View File

@ -0,0 +1,563 @@
//========================================================================
// GLFW - An OpenGL framework
// File: dos_window.c
// Platform: DOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwRedirectOutput() - Standard output redirection
//========================================================================
static void _glfwRedirectOutput( void )
{
// Generate temporary names
tmpnam( _glfwWin.OutName );
tmpnam( _glfwWin.ErrName );
// Open temporary output files
_glfwWin.hOut = open( _glfwWin.OutName, O_WRONLY | O_CREAT | O_TEXT |
O_TRUNC, S_IREAD | S_IWRITE );
_glfwWin.hErr = open( _glfwWin.ErrName, O_WRONLY | O_CREAT | O_TEXT |
O_TRUNC, S_IREAD | S_IWRITE );
// Redirect stdout
if( _glfwWin.hOut > 0 )
{
_glfwWin.hOutOld = dup( STDOUT_FILENO );
fflush( stdout );
dup2( _glfwWin.hOut, STDOUT_FILENO );
}
// Redirect stderr
if( _glfwWin.hErr > 0 )
{
_glfwWin.hErrOld = dup( STDERR_FILENO );
fflush( stderr );
dup2( _glfwWin.hErr, STDERR_FILENO );
}
}
//========================================================================
// _glfwRestoreOutput() - Standard output redirection
//========================================================================
static void _glfwRestoreOutput( void )
{
FILE *f;
char *str = alloca( 512 );
// Dump from temporary file to stdout
if( _glfwWin.hOut > 0)
{
// Restore old stdout
dup2( _glfwWin.hOutOld, STDOUT_FILENO );
close( _glfwWin.hOut );
close( _glfwWin.hOutOld );
_glfwWin.hOut = 0;
// Dump file to stdout
f = fopen( _glfwWin.OutName, "rt" );
while( fgets( str, 512, f ) )
{
fputs( str, stdout );
}
fclose( f );
// Remove temporary file
remove( _glfwWin.OutName );
}
// Dump from temporary file to stderr
if( _glfwWin.hOut > 0)
{
// Restore old stderr
dup2( _glfwWin.hErrOld, STDERR_FILENO );
close( _glfwWin.hErr );
close( _glfwWin.hErrOld );
_glfwWin.hErr = 0;
// Dump file to stderr
f = fopen( _glfwWin.ErrName, "rt" );
while( fgets( str, 512, f ) )
{
fputs( str, stderr );
}
fclose( f );
// Remove temporary file
remove( _glfwWin.ErrName );
}
}
//========================================================================
// _glfwTranslateChar() - Translates a DOS key code to Unicode
//========================================================================
static int _glfwTranslateChar( int keycode )
{
// Unicode?
if( (keycode >= 32 && keycode <= 126) || keycode >= 160 )
{
return keycode;
}
return -1;
}
//========================================================================
// _glfwTranslateKey() - Translates a DOS key code to GLFW coding
//========================================================================
static int _glfwTranslateKey( int keycode )
{
// ISO 8859-1?
if( ((keycode>=32) && (keycode<=126)) ||
((keycode>=160) && (keycode<=254)) )
{
return keycode;
}
// Special keys?
if( keycode < 0 )
{
return -keycode;
}
return -1;
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformOpenWindow() - Here is where the window is created, and
// the OpenGL rendering context is created
//========================================================================
int _glfwPlatformOpenWindow( int width, int height, int redbits,
int greenbits, int bluebits, int alphabits, int depthbits,
int stencilbits, int mode, int accumredbits, int accumgreenbits,
int accumbluebits, int accumalphabits, int auxbuffers, int stereo,
int refreshrate )
{
GLint params[2];
// Clear window resources
_glfwWin.Visual = NULL;
_glfwWin.Context = NULL;
_glfwWin.Buffer = NULL;
_glfwWin.hOut = 0;
_glfwWin.hErr = 0;
// For now, we only support 640x480, 800x600 and 1024x768
if( (width*height) < (700*500) )
{
width = 640;
height = 480;
}
else if( (width*height) < (900*700) )
{
width = 800;
height = 600;
}
else
{
width = 1024;
height = 768;
}
// For now, we only support 5,6,5 and 8,8,8 color formats
if( (redbits+greenbits+bluebits) < 20 )
{
redbits = 5;
greenbits = 6;
bluebits = 5;
}
else
{
redbits = 8;
greenbits = 8;
bluebits = 8;
}
// For now, we always set refresh rate = 0 (default)
refreshrate = 0;
// stdout/stderr redirection
_glfwRedirectOutput();
// Create visual
_glfwWin.Visual = DMesaCreateVisual(
width, height,
redbits+greenbits+bluebits,
refreshrate,
GL_TRUE, // Double buffer
GL_TRUE, // RGB mode
alphabits?GL_TRUE:GL_FALSE, // Alpha buffer?
depthbits,
stencilbits,
(accumredbits+accumgreenbits+
accumbluebits+accumalphabits)>>2
);
if( _glfwWin.Visual == NULL )
{
printf("Unable to create visual\n");
_glfwPlatformCloseWindow();
return GL_FALSE;
}
// Create context
_glfwWin.Context = DMesaCreateContext( _glfwWin.Visual, NULL );
if( _glfwWin.Context == NULL )
{
printf("Unable to create context\n");
_glfwPlatformCloseWindow();
return GL_FALSE;
}
// Create buffer
_glfwWin.Buffer = DMesaCreateBuffer( _glfwWin.Visual, 0, 0,
width, height );
if( _glfwWin.Buffer == NULL )
{
printf("Unable to create buffer\n");
_glfwPlatformCloseWindow();
return GL_FALSE;
}
// Make current context
if( !DMesaMakeCurrent( _glfwWin.Context, _glfwWin.Buffer ) )
{
printf("Unable to make current context\n");
_glfwPlatformCloseWindow();
return GL_FALSE;
}
// Start DOS event handler
if( !_glfwInitEvents() )
{
printf("Unable to start event handler\n");
_glfwPlatformCloseWindow();
return GL_FALSE;
}
// Start keyboard handler
if( !_glfwInitKeyboard() )
{
printf("Unable to start keyboard driver\n");
_glfwPlatformCloseWindow();
return GL_FALSE;
}
// Start mouse handler
if( !_glfwInitMouse() )
{
printf("***Warning: Unable to start mouse driver\n");
}
// Remember actual screen/window size
_glfwWin.Width = width;
_glfwWin.Height = height;
return GL_TRUE;
}
//========================================================================
// _glfwPlatformCloseWindow() - Properly kill the window/video display
//========================================================================
void _glfwPlatformCloseWindow( void )
{
// Terminate mouse handler
_glfwTerminateMouse();
// Terminate keyboard handler
_glfwTerminateKeyboard();
// Terminate event handler
_glfwTerminateEvents();
// Destroy buffer
if( _glfwWin.Buffer != NULL )
{
DMesaDestroyBuffer( _glfwWin.Buffer );
_glfwWin.Buffer = NULL;
}
// Destroy context
if( _glfwWin.Context != NULL )
{
DMesaDestroyContext( _glfwWin.Context );
_glfwWin.Context = NULL;
}
// Destroy visual
if( _glfwWin.Visual != NULL )
{
DMesaDestroyVisual( _glfwWin.Visual );
_glfwWin.Visual = NULL;
}
// stdout/stderr redirection
_glfwRestoreOutput();
}
//========================================================================
// _glfwPlatformSetWindowTitle() - Set the window title.
//========================================================================
void _glfwPlatformSetWindowTitle( const char *title )
{
// Nothing to do here...
}
//========================================================================
// _glfwPlatformSetWindowSize() - Set the window size.
//========================================================================
void _glfwPlatformSetWindowSize( int width, int height )
{
// TODO
}
//========================================================================
// _glfwPlatformSetWindowPos() - Set the window position.
//========================================================================
void _glfwPlatformSetWindowPos( int x, int y )
{
// Nothing to do here...
}
//========================================================================
// _glfwPlatformIconfyWindow() - Window iconification
//========================================================================
void _glfwPlatformIconifyWindow( void )
{
// Nothing to do here...
}
//========================================================================
// _glfwPlatformRestoreWindow() - Window un-iconification
//========================================================================
void _glfwPlatformRestoreWindow( void )
{
// Nothing to do here...
}
//========================================================================
// _glfwPlatformSwapBuffers() - Swap buffers (double-buffering) and poll
// any new events.
//========================================================================
void _glfwPlatformSwapBuffers( void )
{
DMesaSwapBuffers( _glfwWin.Buffer );
}
//========================================================================
// _glfwPlatformSwapInterval() - Set double buffering swap interval
//========================================================================
void _glfwPlatformSwapInterval( int interval )
{
// TODO
}
//========================================================================
// _glfwPlatformRefreshWindowParams()
//========================================================================
void _glfwPlatformRefreshWindowParams( void )
{
GLint x;
GLboolean b;
// Fill out information
_glfwWin.Accelerated = GL_TRUE;
glGetIntegerv( GL_RED_BITS, &x );
_glfwWin.RedBits = x;
glGetIntegerv( GL_GREEN_BITS, &x );
_glfwWin.GreenBits = x;
glGetIntegerv( GL_BLUE_BITS, &x );
_glfwWin.BlueBits = x;
glGetIntegerv( GL_ALPHA_BITS, &x );
_glfwWin.AlphaBits = x;
glGetIntegerv( GL_DEPTH_BITS, &x );
_glfwWin.DepthBits = x;
glGetIntegerv( GL_STENCIL_BITS, &x );
_glfwWin.StencilBits = x;
glGetIntegerv( GL_ACCUM_RED_BITS, &x );
_glfwWin.AccumRedBits = x;
glGetIntegerv( GL_ACCUM_GREEN_BITS, &x );
_glfwWin.AccumGreenBits = x;
glGetIntegerv( GL_ACCUM_BLUE_BITS, &x );
_glfwWin.AccumBlueBits = x;
glGetIntegerv( GL_ACCUM_ALPHA_BITS, &x );
_glfwWin.AccumAlphaBits = x;
glGetIntegerv( GL_AUX_BUFFERS, &x );
_glfwWin.AuxBuffers = x;
glGetBooleanv( GL_AUX_BUFFERS, &b );
_glfwWin.Stereo = b ? GL_TRUE : GL_FALSE;
_glfwWin.RefreshRate = 0;
}
//========================================================================
// _glfwPlatformPollEvents() - Poll for new window and input events
//========================================================================
void _glfwPlatformPollEvents( void )
{
_GLFWdosevent event;
struct key_event *key;
struct mousemove_event *mousemove;
struct mousewheel_event *mousewheel;
struct mousebutton_event *mousebutton;
// Empty the event queue
while( _glfwGetNextEvent( &event ) )
{
switch( event.Type )
{
// Keyboard event?
case _GLFW_DOS_KEY_EVENT:
key = &event.Key;
_glfwInputKey( _glfwTranslateKey( key->KeyNoMod ),
key->Action );
_glfwInputChar( _glfwTranslateChar( key->Key ),
key->Action );
break;
// Mouse move event?
case _GLFW_DOS_MOUSE_MOVE_EVENT:
mousemove = &event.MouseMove;
_glfwInput.MousePosX += mousemove->DeltaX;
_glfwInput.MousePosY += mousemove->DeltaY;
// Call user callback function
if( _glfwWin.MousePosCallback )
{
_glfwWin.MousePosCallback( _glfwInput.MousePosX,
_glfwInput.MousePosY );
}
break;
// Mouse wheel event?
case _GLFW_DOS_MOUSE_WHEEL_EVENT:
mousewheel = &event.MouseWheel;
_glfwInput.WheelPos += mousewheel->WheelDelta;
// Call user callback function
if( _glfwWin.MouseWheelCallback )
{
_glfwWin.MouseWheelCallback( _glfwInput.WheelPos );
}
break;
// Mouse button event?
case _GLFW_DOS_MOUSE_BUTTON_EVENT:
mousebutton = &event.MouseButton;
_glfwInputMouseClick( mousebutton->Button,
mousebutton->Action );
break;
default:
break;
}
}
}
//========================================================================
// _glfwPlatformWaitEvents() - Wait for new window and input events
//========================================================================
void _glfwPlatformWaitEvents( void )
{
// Wait for new events
_glfwWaitNextEvent;
// Poll new events
_glfwPlatformPollEvents();
}
//========================================================================
// _glfwPlatformHideMouseCursor() - Hide mouse cursor (lock it)
//========================================================================
void _glfwPlatformHideMouseCursor( void )
{
// TODO
}
//========================================================================
// _glfwPlatformShowMouseCursor() - Show mouse cursor (unlock it)
//========================================================================
void _glfwPlatformShowMouseCursor( void )
{
// TODO
}
//========================================================================
// _glfwPlatformSetMouseCursorPos() - Set physical mouse cursor position
//========================================================================
void _glfwPlatformSetMouseCursorPos( int x, int y )
{
// TODO
}

View File

@ -0,0 +1,341 @@
//========================================================================
// GLFW - An OpenGL framework
// File: platform.h
// Platform: DOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef _platform_h_
#define _platform_h_
// This is the DOS version of GLFW
#define _GLFW_DOS
// Include files
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <dos.h>
#include <dpmi.h>
#include <fcntl.h>
#include <pc.h>
#include <sys/stat.h>
#include <sys/exceptn.h>
#include <sys/farptr.h>
#include <sys/segments.h>
// GLFW+GL+GLU defines
#include "../../include/GL/glfw.h"
// DOS Mesa (include this AFTER gl.h!)
#include <GL/dmesa.h>
// Stack size for each thread (in bytes)
#define _GLFW_TASK_STACK_SIZE 50000
//========================================================================
// Global variables (GLFW internals)
//========================================================================
//------------------------------------------------------------------------
// Window structure
//------------------------------------------------------------------------
typedef struct _GLFWwin_struct _GLFWwin;
struct _GLFWwin_struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// User callback functions
GLFWwindowsizefun WindowSizeCallback;
GLFWwindowclosefun WindowCloseCallback;
GLFWwindowrefreshfun WindowRefreshCallback;
GLFWmousebuttonfun MouseButtonCallback;
GLFWmouseposfun MousePosCallback;
GLFWmousewheelfun MouseWheelCallback;
GLFWkeyfun KeyCallback;
GLFWcharfun CharCallback;
// User selected window settings
int Fullscreen; // Fullscreen flag
int MouseLock; // Mouse-lock flag
int AutoPollEvents; // Auto polling flag
int SysKeysDisabled; // System keys disabled flag
int WindowNoResize; // Resize- and maximize gadgets disabled flag
// Window status & parameters
int Opened; // Flag telling if window is opened or not
int Active; // Application active flag
int Iconified; // Window iconified flag
int Width, Height; // Window width and heigth
int Accelerated; // GL_TRUE if window is HW accelerated
int RedBits;
int GreenBits;
int BlueBits;
int AlphaBits;
int DepthBits;
int StencilBits;
int AccumRedBits;
int AccumGreenBits;
int AccumBlueBits;
int AccumAlphaBits;
int AuxBuffers;
int Stereo;
int RefreshRate; // Vertical monitor refresh rate
// Extensions & OpenGL version
int Has_GL_SGIS_generate_mipmap;
int Has_GL_ARB_texture_non_power_of_two;
int GLVerMajor,GLVerMinor;
// ========= PLATFORM SPECIFIC PART ======================================
// Platform specific window resources
DMesaVisual Visual;
DMesaContext Context;
DMesaBuffer Buffer;
// Standard output redirection
char OutName[L_tmpnam];
char ErrName[L_tmpnam];
int hOut,hOutOld,hErr,hErrOld;
// Platform specific extensions
// Various platform specific internal variables
};
GLFWGLOBAL _GLFWwin _glfwWin;
//------------------------------------------------------------------------
// User input status (most of this should go in _GLFWwin)
//------------------------------------------------------------------------
GLFWGLOBAL struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Mouse status
int MousePosX, MousePosY;
int WheelPos;
char MouseButton[ GLFW_MOUSE_BUTTON_LAST+1 ];
// Keyboard status
char Key[ GLFW_KEY_LAST+1 ];
int LastChar;
// User selected settings
int StickyKeys;
int StickyMouseButtons;
int KeyRepeat;
// ========= PLATFORM SPECIFIC PART ======================================
// Platform specific internal variables
} _glfwInput;
//------------------------------------------------------------------------
// Timer status
//------------------------------------------------------------------------
GLFWGLOBAL struct {
double Period;
long long t0;
int HasRDTSC;
} _glfwTimer;
//------------------------------------------------------------------------
// Thread record (one for each thread)
//------------------------------------------------------------------------
typedef struct _GLFWthread_struct _GLFWthread;
struct _GLFWthread_struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Pointer to previous and next threads in linked list
_GLFWthread *Previous, *Next;
// GLFW user side thread information
GLFWthread ID;
// ========= PLATFORM SPECIFIC PART ======================================
// System side thread information
GLFWthreadfun Function;
void *Arg;
};
//------------------------------------------------------------------------
// General thread information
//------------------------------------------------------------------------
GLFWGLOBAL struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Next thread ID to use (increments for every created thread)
GLFWthread NextID;
// First thread in linked list (always the main thread)
_GLFWthread First;
// ========= PLATFORM SPECIFIC PART ======================================
// Critical section lock
} _glfwThrd;
//------------------------------------------------------------------------
// Joystick information & state
//------------------------------------------------------------------------
GLFWGLOBAL struct {
int dummy;
} _glfwJoy;
//========================================================================
// Macros for encapsulating critical code sections (i.e. making parts
// of GLFW thread safe)
//========================================================================
// Thread list management
#define ENTER_THREAD_CRITICAL_SECTION \
;
#define LEAVE_THREAD_CRITICAL_SECTION \
;
//========================================================================
// DOS events
//========================================================================
// Valid event types
#define _GLFW_DOS_KEY_EVENT 1
#define _GLFW_DOS_MOUSE_MOVE_EVENT 2
#define _GLFW_DOS_MOUSE_WHEEL_EVENT 3
#define _GLFW_DOS_MOUSE_BUTTON_EVENT 4
// Keyboard event structure
struct key_event {
int Type;
int Key;
int KeyNoMod;
int Action;
};
// Mouse move event structure
struct mousemove_event {
int Type;
int DeltaX, DeltaY;
};
// Mouse wheel event structure
struct mousewheel_event {
int Type;
int WheelDelta;
};
// Mouse button event structure
struct mousebutton_event {
int Type;
int Button;
int Action;
};
// DOS event structure
typedef union {
int Type;
struct key_event Key;
struct mousemove_event MouseMove;
struct mousewheel_event MouseWheel;
struct mousebutton_event MouseButton;
} _GLFWdosevent;
//========================================================================
// Prototypes for platform specific internal functions
//========================================================================
// Time
int _glfwInitTimer( void );
void _glfwTerminateTimer( void );
// Fullscreen
// Events
int _glfwInitEvents( void );
void _glfwTerminateEvents( void );
void _glfwWaitNextEvent( void );
int _glfwGetNextEvent( _GLFWdosevent *event );
void _glfwPostDOSEvent( _GLFWdosevent *event );
// Mouse
int _glfwInitMouse( void );
void _glfwTerminateMouse( void );
// Keyboard
int _glfwInitKeyboard( void );
void _glfwTerminateKeyboard( void );
// Joystick
void _glfwInitJoysticks( void );
void _glfwTerminateJoysticks( void );
// Threads
int _glfwInitThreads( void );
void _glfwTerminateThreads( void );
// Interrupt handling
int _glfwInstallDOSIrq( int i, int (*handler) () );
int _glfwRemoveDOSIrq( int i );
// Interrupt macros
#define ENABLE() __asm __volatile("sti")
#define DISABLE() __asm __volatile("cli")
// Memory macros (for locking memory)
#define ENDOFUNC(x) static void x##_end() { }
#define LOCKFUNC(x) _go32_dpmi_lock_code((void *)x, (long)x##_end - (long)x)
#define LOCKDATA(x) _go32_dpmi_lock_data((void *)&x, sizeof(x))
#define LOCKBUFF(x, l) _go32_dpmi_lock_data((void *)x, l)
#endif // _platform_h_

295
libs/glfw/lib/enable.c Normal file
View File

@ -0,0 +1,295 @@
//========================================================================
// GLFW - An OpenGL framework
// File: enable.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// Enable (show) mouse cursor
//========================================================================
static void _glfwEnableMouseCursor( void )
{
int CenterPosX, CenterPosY;
if( !_glfwWin.Opened || !_glfwWin.MouseLock )
{
return;
}
// Show mouse cursor
_glfwPlatformShowMouseCursor();
CenterPosX = _glfwWin.Width / 2;
CenterPosY = _glfwWin.Height / 2;
if( CenterPosX != _glfwInput.MousePosX || CenterPosY != _glfwInput.MousePosY )
{
_glfwPlatformSetMouseCursorPos( CenterPosX, CenterPosY );
_glfwInput.MousePosX = CenterPosX;
_glfwInput.MousePosY = CenterPosY;
if( _glfwWin.MousePosCallback )
{
_glfwWin.MousePosCallback( _glfwInput.MousePosX,
_glfwInput.MousePosY );
}
}
// From now on the mouse is unlocked
_glfwWin.MouseLock = GL_FALSE;
}
//========================================================================
// Disable (hide) mouse cursor
//========================================================================
static void _glfwDisableMouseCursor( void )
{
if( !_glfwWin.Opened || _glfwWin.MouseLock )
{
return;
}
// Hide mouse cursor
_glfwPlatformHideMouseCursor();
// Move cursor to the middle of the window
_glfwPlatformSetMouseCursorPos( _glfwWin.Width>>1,
_glfwWin.Height>>1 );
// From now on the mouse is locked
_glfwWin.MouseLock = GL_TRUE;
}
//========================================================================
// _glfwEnableStickyKeys() - Enable sticky keys
// _glfwDisableStickyKeys() - Disable sticky keys
//========================================================================
static void _glfwEnableStickyKeys( void )
{
_glfwInput.StickyKeys = 1;
}
static void _glfwDisableStickyKeys( void )
{
int i;
_glfwInput.StickyKeys = 0;
// Release all sticky keys
for( i = 0; i <= GLFW_KEY_LAST; i ++ )
{
if( _glfwInput.Key[ i ] == 2 )
{
_glfwInput.Key[ i ] = 0;
}
}
}
//========================================================================
// _glfwEnableStickyMouseButtons() - Enable sticky mouse buttons
// _glfwDisableStickyMouseButtons() - Disable sticky mouse buttons
//========================================================================
static void _glfwEnableStickyMouseButtons( void )
{
_glfwInput.StickyMouseButtons = 1;
}
static void _glfwDisableStickyMouseButtons( void )
{
int i;
_glfwInput.StickyMouseButtons = 0;
// Release all sticky mouse buttons
for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i ++ )
{
if( _glfwInput.MouseButton[ i ] == 2 )
{
_glfwInput.MouseButton[ i ] = 0;
}
}
}
//========================================================================
// _glfwEnableSystemKeys() - Enable system keys
// _glfwDisableSystemKeys() - Disable system keys
//========================================================================
static void _glfwEnableSystemKeys( void )
{
if( !_glfwWin.SysKeysDisabled )
{
return;
}
_glfwPlatformEnableSystemKeys();
// Indicate that system keys are no longer disabled
_glfwWin.SysKeysDisabled = GL_FALSE;
}
static void _glfwDisableSystemKeys( void )
{
if( _glfwWin.SysKeysDisabled )
{
return;
}
_glfwPlatformDisableSystemKeys();
// Indicate that system keys are now disabled
_glfwWin.SysKeysDisabled = GL_TRUE;
}
//========================================================================
// _glfwEnableKeyRepeat() - Enable key repeat
// _glfwDisableKeyRepeat() - Disable key repeat
//========================================================================
static void _glfwEnableKeyRepeat( void )
{
_glfwInput.KeyRepeat = 1;
}
static void _glfwDisableKeyRepeat( void )
{
_glfwInput.KeyRepeat = 0;
}
//========================================================================
// _glfwEnableAutoPollEvents() - Enable automatic event polling
// _glfwDisableAutoPollEvents() - Disable automatic event polling
//========================================================================
static void _glfwEnableAutoPollEvents( void )
{
_glfwWin.AutoPollEvents = 1;
}
static void _glfwDisableAutoPollEvents( void )
{
_glfwWin.AutoPollEvents = 0;
}
//************************************************************************
//**** GLFW user functions ****
//************************************************************************
//========================================================================
// glfwEnable() - Enable certain GLFW/window/system functions.
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwEnable( int token )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return;
}
switch( token )
{
case GLFW_MOUSE_CURSOR:
_glfwEnableMouseCursor();
break;
case GLFW_STICKY_KEYS:
_glfwEnableStickyKeys();
break;
case GLFW_STICKY_MOUSE_BUTTONS:
_glfwEnableStickyMouseButtons();
break;
case GLFW_SYSTEM_KEYS:
_glfwEnableSystemKeys();
break;
case GLFW_KEY_REPEAT:
_glfwEnableKeyRepeat();
break;
case GLFW_AUTO_POLL_EVENTS:
_glfwEnableAutoPollEvents();
break;
default:
break;
}
}
//========================================================================
// glfwDisable() - Disable certain GLFW/window/system functions.
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwDisable( int token )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return;
}
switch( token )
{
case GLFW_MOUSE_CURSOR:
_glfwDisableMouseCursor();
break;
case GLFW_STICKY_KEYS:
_glfwDisableStickyKeys();
break;
case GLFW_STICKY_MOUSE_BUTTONS:
_glfwDisableStickyMouseButtons();
break;
case GLFW_SYSTEM_KEYS:
_glfwDisableSystemKeys();
break;
case GLFW_KEY_REPEAT:
_glfwDisableKeyRepeat();
break;
case GLFW_AUTO_POLL_EVENTS:
_glfwDisableAutoPollEvents();
break;
default:
break;
}
}

View File

@ -0,0 +1,95 @@
//========================================================================
// GLFW - An OpenGL framework
// File: fullscreen.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW user functions ****
//************************************************************************
//========================================================================
// glfwGetVideoModes() - Get a list of available video modes
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwGetVideoModes( GLFWvidmode *list,
int maxcount )
{
int count, i, swap, res1, res2, depth1, depth2;
GLFWvidmode vm;
if( !_glfwInitialized || maxcount <= 0 || list == (GLFWvidmode*) 0 )
{
return 0;
}
// Get list of video modes
count = _glfwPlatformGetVideoModes( list, maxcount );
// Sort list (bubble sort)
do
{
swap = 0;
for( i = 0; i < count-1; ++ i )
{
res1 = list[i].Width*list[i].Height;
depth1 = list[i].RedBits+list[i].GreenBits+list[i].BlueBits;
res2 = list[i+1].Width*list[i+1].Height;
depth2 = list[i+1].RedBits+list[i+1].GreenBits+
list[i+1].BlueBits;
if( (depth2<depth1) || ((depth2==depth1) && (res2<res1)) )
{
vm = list[i];
list[i] = list[i+1];
list[i+1] = vm;
swap = 1;
}
}
}
while( swap );
return count;
}
//========================================================================
// glfwGetDesktopMode() - Get the desktop video mode
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwGetDesktopMode( GLFWvidmode *mode )
{
if( !_glfwInitialized || mode == (GLFWvidmode*) 0 )
{
return;
}
_glfwPlatformGetDesktopMode( mode );
}

201
libs/glfw/lib/glext.c Normal file
View File

@ -0,0 +1,201 @@
//========================================================================
// GLFW - An OpenGL framework
// File: glext.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwStringInExtensionString() - Check if a string can be found in an
// OpenGL extension string
//========================================================================
int _glfwStringInExtensionString( const char *string,
const GLubyte *extensions )
{
const GLubyte *start;
GLubyte *where, *terminator;
// It takes a bit of care to be fool-proof about parsing the
// OpenGL extensions string. Don't be fooled by sub-strings,
// etc.
start = extensions;
while( 1 )
{
where = (GLubyte *) strstr( (const char *) start, string );
if( !where )
{
return GL_FALSE;
}
terminator = where + strlen( string );
if( where == start || *(where - 1) == ' ' )
{
if( *terminator == ' ' || *terminator == '\0' )
{
break;
}
}
start = terminator;
}
return GL_TRUE;
}
//************************************************************************
//**** GLFW user functions ****
//************************************************************************
//========================================================================
// glfwExtensionSupported() - Check if an OpenGL extension is available
// at runtime
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwExtensionSupported( const char *extension )
{
const GLubyte *extensions;
GLubyte *where;
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return GL_FALSE;
}
// Extension names should not have spaces
where = (GLubyte *) strchr( extension, ' ' );
if( where || *extension == '\0' )
{
return GL_FALSE;
}
// Check if extension is in the standard OpenGL extensions string
extensions = (GLubyte *) glGetString( GL_EXTENSIONS );
if( extensions != NULL )
{
if( _glfwStringInExtensionString( extension, extensions ) )
{
return GL_TRUE;
}
}
// Additional platform specific extension checking (e.g. WGL)
if( _glfwPlatformExtensionSupported( extension ) )
{
return GL_TRUE;
}
return GL_FALSE;
}
//========================================================================
// glfwGetProcAddress() - Get the function pointer to an OpenGL function.
// This function can be used to get access to extended OpenGL functions.
//========================================================================
GLFWAPI void * GLFWAPIENTRY glfwGetProcAddress( const char *procname )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return NULL;
}
return _glfwPlatformGetProcAddress( procname );
}
//========================================================================
// glfwGetGLVersion() - Get OpenGL version
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwGetGLVersion( int *major, int *minor,
int *rev )
{
GLuint _major, _minor = 0, _rev = 0;
const GLubyte *version;
GLubyte *ptr;
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Get OpenGL version string
version = glGetString( GL_VERSION );
if( !version )
{
return;
}
// Parse string
ptr = (GLubyte*) version;
for( _major = 0; *ptr >= '0' && *ptr <= '9'; ptr ++ )
{
_major = 10*_major + (*ptr - '0');
}
if( *ptr == '.' )
{
ptr ++;
for( _minor = 0; *ptr >= '0' && *ptr <= '9'; ptr ++ )
{
_minor = 10*_minor + (*ptr - '0');
}
if( *ptr == '.' )
{
ptr ++;
for( _rev = 0; *ptr >= '0' && *ptr <= '9'; ptr ++ )
{
_rev = 10*_rev + (*ptr - '0');
}
}
}
// Return parsed values
if( major != NULL )
{
*major = _major;
}
if( minor != NULL )
{
*minor = _minor;
}
if( rev != NULL )
{
*rev = _rev;
}
}

629
libs/glfw/lib/image.c Normal file
View File

@ -0,0 +1,629 @@
//========================================================================
// GLFW - An OpenGL framework
// File: image.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
//========================================================================
// Description:
//
// This module acts as an interface for different image file formats (the
// image file format is detected automatically).
//
// By default the loaded image is rescaled (using bilinear interpolation)
// to the next higher 2^N x 2^M resolution, unless it has a valid
// 2^N x 2^M resolution. The interpolation is quite slow, even if the
// routine has been optimized for speed (a 200x200 RGB image is scaled to
// 256x256 in ~30 ms on a P3-500).
//
// Paletted images are converted to RGB/RGBA images.
//
// A convenience function is also included (glfwLoadTexture2D), which
// loads a texture image from a file directly to OpenGL texture memory,
// with an option to generate all mipmap levels. GL_SGIS_generate_mipmap
// is used whenever available, which should give an optimal mipmap
// generation speed (possibly performed in hardware). A software fallback
// method is included when GL_SGIS_generate_mipmap is not supported (it
// generates all mipmaps of a 256x256 RGB texture in ~3 ms on a P3-500).
//
//========================================================================
#include "internal.h"
// We want to support automatic mipmap generation
#ifndef GL_SGIS_generate_mipmap
#define GL_GENERATE_MIPMAP_SGIS 0x8191
#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
#define GL_SGIS_generate_mipmap 1
#endif // GL_SGIS_generate_mipmap
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwUpsampleImage() - Upsample image, from size w1 x h1 to w2 x h2
//========================================================================
static void _glfwUpsampleImage( unsigned char *src, unsigned char *dst,
int w1, int h1, int w2, int h2, int bpp )
{
int m, n, k, x, y, col8;
float dx, dy, xstep, ystep, col, col1, col2;
unsigned char *src1, *src2, *src3, *src4;
// Calculate scaling factor
xstep = (float)(w1-1) / (float)(w2-1);
ystep = (float)(h1-1) / (float)(h2-1);
// Copy source data to destination data with bilinear interpolation
// Note: The rather strange look of this routine is a direct result of
// my attempts at optimizing it. Improvements are welcome!
dy = 0.0f;
y = 0;
for( n = 0; n < h2; n ++ )
{
dx = 0.0f;
src1 = &src[ y*w1*bpp ];
src3 = y < (h1-1) ? src1 + w1*bpp : src1;
src2 = src1 + bpp;
src4 = src3 + bpp;
x = 0;
for( m = 0; m < w2; m ++ )
{
for( k = 0; k < bpp; k ++ )
{
col1 = *src1 ++;
col2 = *src2 ++;
col = col1 + (col2 - col1) * dx;
col1 = *src3 ++;
col2 = *src4 ++;
col2 = col1 + (col2 - col1) * dx;
col += (col2 - col) * dy;
col8 = (int) (col + 0.5);
if( col8 >= 256 ) col8 = 255;
*dst++ = (unsigned char) col8;
}
dx += xstep;
if( dx >= 1.0f )
{
x ++;
dx -= 1.0f;
if( x >= (w1-1) )
{
src2 = src1;
src4 = src3;
}
}
else
{
src1 -= bpp;
src2 -= bpp;
src3 -= bpp;
src4 -= bpp;
}
}
dy += ystep;
if( dy >= 1.0f )
{
y ++;
dy -= 1.0f;
}
}
}
//========================================================================
// _glfwHalveImage() - Build the next mip-map level
//========================================================================
static int _glfwHalveImage( GLubyte *src, int *width, int *height,
int components )
{
int halfwidth, halfheight, m, n, k, idx1, idx2;
GLubyte *dst;
// Last level?
if( *width <= 1 && *height <= 1 )
{
return GL_FALSE;
}
// Calculate new width and height (handle 1D case)
halfwidth = *width > 1 ? *width / 2 : 1;
halfheight = *height > 1 ? *height / 2 : 1;
// Downsample image with a simple box-filter
dst = src;
if( *width == 1 || *height == 1 )
{
// 1D case
for( m = 0; m < halfwidth+halfheight-1; m ++ )
{
for( k = 0; k < components; k ++ )
{
*dst ++ = (GLubyte) (((int)*src +
(int)src[components] + 1) >> 1);
src ++;
}
src += components;
}
}
else
{
// 2D case
idx1 = *width*components;
idx2 = (*width+1)*components;
for( m = 0; m < halfheight; m ++ )
{
for( n = 0; n < halfwidth; n ++ )
{
for( k = 0; k < components; k ++ )
{
*dst ++ = (GLubyte) (((int)*src +
(int)src[components] +
(int)src[idx1] +
(int)src[idx2] + 2) >> 2);
src ++;
}
src += components;
}
src += components * (*width);
}
}
// Return new width and height
*width = halfwidth;
*height = halfheight;
return GL_TRUE;
}
//========================================================================
// _glfwRescaleImage() - Rescales an image into power-of-two dimensions
//========================================================================
static int _glfwRescaleImage( GLFWimage* image )
{
int width, height, log2, newsize;
unsigned char *data;
// Calculate next larger 2^N width
for( log2 = 0, width = image->Width; width > 1; width >>= 1, log2 ++ )
;
width = (int) 1 << log2;
if( width < image->Width )
{
width <<= 1;
}
// Calculate next larger 2^M height
for( log2 = 0, height = image->Height; height > 1; height >>= 1, log2 ++ )
;
height = (int) 1 << log2;
if( height < image->Height )
{
height <<= 1;
}
// Do we really need to rescale?
if( width != image->Width || height != image->Height )
{
// Allocate memory for new (upsampled) image data
newsize = width * height * image->BytesPerPixel;
data = (unsigned char *) malloc( newsize );
if( data == NULL )
{
free( image->Data );
return GL_FALSE;
}
// Copy old image data to new image data with interpolation
_glfwUpsampleImage( image->Data, data, image->Width, image->Height,
width, height, image->BytesPerPixel );
// Free memory for old image data (not needed anymore)
free( image->Data );
// Set pointer to new image data, and set new image dimensions
image->Data = data;
image->Width = width;
image->Height = height;
}
return GL_TRUE;
}
//************************************************************************
//**** GLFW user functions ****
//************************************************************************
//========================================================================
// glfwReadImage() - Read an image from a named file
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwReadImage( const char *name, GLFWimage *img,
int flags )
{
_GLFWstream stream;
// Is GLFW initialized?
if( !_glfwInitialized )
{
return GL_FALSE;
}
// Start with an empty image descriptor
img->Width = 0;
img->Height = 0;
img->BytesPerPixel = 0;
img->Data = NULL;
// Open file
if( !_glfwOpenFileStream( &stream, name, "rb" ) )
{
return GL_FALSE;
}
// We only support TGA files at the moment
if( !_glfwReadTGA( &stream, img, flags ) )
{
_glfwCloseStream( &stream );
return GL_FALSE;
}
// Close stream
_glfwCloseStream( &stream );
// Should we rescale the image to closest 2^N x 2^M resolution?
if( !(flags & GLFW_NO_RESCALE_BIT) )
{
if( !_glfwRescaleImage( img ) )
{
return GL_FALSE;
}
}
// Interpret BytesPerPixel as an OpenGL format
switch( img->BytesPerPixel )
{
default:
case 1:
if( flags & GLFW_ALPHA_MAP_BIT )
{
img->Format = GL_ALPHA;
}
else
{
img->Format = GL_LUMINANCE;
}
break;
case 3:
img->Format = GL_RGB;
break;
case 4:
img->Format = GL_RGBA;
break;
}
return GL_TRUE;
}
//========================================================================
// glfwReadMemoryImage() - Read an image file from a memory buffer
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwReadMemoryImage( const void *data, long size, GLFWimage *img, int flags )
{
_GLFWstream stream;
// Is GLFW initialized?
if( !_glfwInitialized )
{
return GL_FALSE;
}
// Start with an empty image descriptor
img->Width = 0;
img->Height = 0;
img->BytesPerPixel = 0;
img->Data = NULL;
// Open buffer
if( !_glfwOpenBufferStream( &stream, (void*) data, size ) )
{
return GL_FALSE;
}
// We only support TGA files at the moment
if( !_glfwReadTGA( &stream, img, flags ) )
{
_glfwCloseStream( &stream );
return GL_FALSE;
}
// Close stream
_glfwCloseStream( &stream );
// Should we rescale the image to closest 2^N x 2^M resolution?
if( !(flags & GLFW_NO_RESCALE_BIT) )
{
if( !_glfwRescaleImage( img ) )
{
return GL_FALSE;
}
}
// Interpret BytesPerPixel as an OpenGL format
switch( img->BytesPerPixel )
{
default:
case 1:
if( flags & GLFW_ALPHA_MAP_BIT )
{
img->Format = GL_ALPHA;
}
else
{
img->Format = GL_LUMINANCE;
}
break;
case 3:
img->Format = GL_RGB;
break;
case 4:
img->Format = GL_RGBA;
break;
}
return GL_TRUE;
}
//========================================================================
// glfwFreeImage() - Free allocated memory for an image
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwFreeImage( GLFWimage *img )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return;
}
// Free memory
if( img->Data != NULL )
{
free( img->Data );
img->Data = NULL;
}
// Clear all fields
img->Width = 0;
img->Height = 0;
img->Format = 0;
img->BytesPerPixel = 0;
}
//========================================================================
// glfwLoadTexture2D() - Read an image from a file, and upload it to
// texture memory
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwLoadTexture2D( const char *name, int flags )
{
GLFWimage img;
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return GL_FALSE;
}
// Force rescaling if necessary
if( !_glfwWin.Has_GL_ARB_texture_non_power_of_two )
{
flags &= (~GLFW_NO_RESCALE_BIT);
}
// Read image from file
if( !glfwReadImage( name, &img, flags ) )
{
return GL_FALSE;
}
if( !glfwLoadTextureImage2D( &img, flags ) )
{
return GL_FALSE;
}
// Data buffer is not needed anymore
glfwFreeImage( &img );
return GL_TRUE;
}
//========================================================================
// glfwLoadMemoryTexture2D() - Read an image from a buffer, and upload it to
// texture memory
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwLoadMemoryTexture2D( const void *data, long size, int flags )
{
GLFWimage img;
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return GL_FALSE;
}
// Force rescaling if necessary
if( !_glfwWin.Has_GL_ARB_texture_non_power_of_two )
{
flags &= (~GLFW_NO_RESCALE_BIT);
}
// Read image from file
if( !glfwReadMemoryImage( data, size, &img, flags ) )
{
return GL_FALSE;
}
if( !glfwLoadTextureImage2D( &img, flags ) )
{
return GL_FALSE;
}
// Data buffer is not needed anymore
glfwFreeImage( &img );
return GL_TRUE;
}
//========================================================================
// glfwLoadTextureImage2D() - Upload an image object to texture memory
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwLoadTextureImage2D( GLFWimage *img, int flags )
{
GLint UnpackAlignment, GenMipMap;
int level, format, AutoGen, newsize, n;
unsigned char *data, *dataptr;
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return GL_FALSE;
}
// TODO: Use GL_MAX_TEXTURE_SIZE or GL_PROXY_TEXTURE_2D to determine
// whether the image size is valid.
// NOTE: May require box filter downsampling routine.
// Do we need to convert the alpha map to RGBA format (OpenGL 1.0)?
if( (_glfwWin.GLVerMajor == 1) && (_glfwWin.GLVerMinor == 0) &&
(img->Format == GL_ALPHA) )
{
// We go to RGBA representation instead
img->BytesPerPixel = 4;
// Allocate memory for new RGBA image data
newsize = img->Width * img->Height * img->BytesPerPixel;
data = (unsigned char *) malloc( newsize );
if( data == NULL )
{
free( img->Data );
return GL_FALSE;
}
// Convert Alpha map to RGBA
dataptr = data;
for( n = 0; n < (img->Width*img->Height); ++ n )
{
*dataptr ++ = 255;
*dataptr ++ = 255;
*dataptr ++ = 255;
*dataptr ++ = img->Data[n];
}
// Free memory for old image data (not needed anymore)
free( img->Data );
// Set pointer to new image data
img->Data = data;
}
// Set unpack alignment to one byte
glGetIntegerv( GL_UNPACK_ALIGNMENT, &UnpackAlignment );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
// Should we use automatic mipmap generation?
AutoGen = ( flags & GLFW_BUILD_MIPMAPS_BIT ) &&
_glfwWin.Has_GL_SGIS_generate_mipmap;
// Enable automatic mipmap generation
if( AutoGen )
{
glGetTexParameteriv( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,
&GenMipMap );
glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,
GL_TRUE );
}
// Format specification is different for OpenGL 1.0
if( _glfwWin.GLVerMajor == 1 && _glfwWin.GLVerMinor == 0 )
{
format = img->BytesPerPixel;
}
else
{
format = img->Format;
}
// Upload to texture memeory
level = 0;
do
{
// Upload this mipmap level
glTexImage2D( GL_TEXTURE_2D, level, format,
img->Width, img->Height, 0, format,
GL_UNSIGNED_BYTE, (void*) img->Data );
// Build next mipmap level manually, if required
if( ( flags & GLFW_BUILD_MIPMAPS_BIT ) && !AutoGen )
{
level = _glfwHalveImage( img->Data, &img->Width,
&img->Height, img->BytesPerPixel ) ?
level + 1 : 0;
}
}
while( level != 0 );
// Restore old automatic mipmap generation state
if( AutoGen )
{
glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,
GenMipMap );
}
// Restore old unpack alignment
glPixelStorei( GL_UNPACK_ALIGNMENT, UnpackAlignment );
return GL_TRUE;
}

108
libs/glfw/lib/init.c Normal file
View File

@ -0,0 +1,108 @@
//========================================================================
// GLFW - An OpenGL framework
// File: init.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define _init_c_
#include "internal.h"
//************************************************************************
//**** GLFW user functions ****
//************************************************************************
//========================================================================
// glfwInit() - Initialize various GLFW state
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwInit( void )
{
// Is GLFW already initialized?
if( _glfwInitialized )
{
return GL_TRUE;
}
// Window is not yet opened
_glfwWin.Opened = GL_FALSE;
// Default enable/disable settings
_glfwWin.SysKeysDisabled = GL_FALSE;
// Clear window hints
_glfwClearWindowHints();
// Platform specific initialization
if( !_glfwPlatformInit() )
{
return GL_FALSE;
}
// Form now on, GLFW state is valid
_glfwInitialized = GL_TRUE;
return GL_TRUE;
}
//========================================================================
// glfwTerminate() - Close window and kill all threads.
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwTerminate( void )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return;
}
// Platform specific termination
if( !_glfwPlatformTerminate() )
{
return;
}
// GLFW is no longer initialized
_glfwInitialized = GL_FALSE;
}
//========================================================================
// glfwGetVersion() - Get GLFW version
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwGetVersion( int *major, int *minor,
int *rev )
{
if( major != NULL ) *major = GLFW_VERSION_MAJOR;
if( minor != NULL ) *minor = GLFW_VERSION_MINOR;
if( rev != NULL ) *rev = GLFW_VERSION_REVISION;
}

280
libs/glfw/lib/input.c Normal file
View File

@ -0,0 +1,280 @@
//========================================================================
// GLFW - An OpenGL framework
// File: input.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//========================================================================
// glfwGetKey()
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwGetKey( int key )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return GLFW_RELEASE;
}
// Is it a valid key?
if( key < 0 || key > GLFW_KEY_LAST )
{
return GLFW_RELEASE;
}
if( _glfwInput.Key[ key ] == GLFW_STICK )
{
// Sticky mode: release key now
_glfwInput.Key[ key ] = GLFW_RELEASE;
return GLFW_PRESS;
}
return (int) _glfwInput.Key[ key ];
}
//========================================================================
// glfwGetMouseButton()
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwGetMouseButton( int button )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return GLFW_RELEASE;
}
// Is it a valid mouse button?
if( button < 0 || button > GLFW_MOUSE_BUTTON_LAST )
{
return GLFW_RELEASE;
}
if( _glfwInput.MouseButton[ button ] == GLFW_STICK )
{
// Sticky mode: release mouse button now
_glfwInput.MouseButton[ button ] = GLFW_RELEASE;
return GLFW_PRESS;
}
return (int) _glfwInput.MouseButton[ button ];
}
//========================================================================
// glfwGetMousePos()
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwGetMousePos( int *xpos, int *ypos )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Return mouse position
if( xpos != NULL )
{
*xpos = _glfwInput.MousePosX;
}
if( ypos != NULL )
{
*ypos = _glfwInput.MousePosY;
}
}
//========================================================================
// glfwSetMousePos()
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetMousePos( int xpos, int ypos )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Don't do anything if the mouse position did not change
if( xpos == _glfwInput.MousePosX && ypos == _glfwInput.MousePosY )
{
return;
}
// Set GLFW mouse position
_glfwInput.MousePosX = xpos;
_glfwInput.MousePosY = ypos;
// If we have a locked mouse, do not change cursor position
if( _glfwWin.MouseLock )
{
return;
}
// Update physical cursor position
_glfwPlatformSetMouseCursorPos( xpos, ypos );
}
//========================================================================
// glfwGetMouseWheel()
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwGetMouseWheel( void )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return 0;
}
// Return mouse wheel position
return _glfwInput.WheelPos;
}
//========================================================================
// glfwSetMouseWheel()
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetMouseWheel( int pos )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set mouse wheel position
_glfwInput.WheelPos = pos;
}
//========================================================================
// glfwSetKeyCallback() - Set callback function for keyboard input
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetKeyCallback( GLFWkeyfun cbfun )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set callback function
_glfwWin.KeyCallback = cbfun;
}
//========================================================================
// glfwSetCharCallback() - Set callback function for character input
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetCharCallback( GLFWcharfun cbfun )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set callback function
_glfwWin.CharCallback = cbfun;
}
//========================================================================
// glfwSetMouseButtonCallback() - Set callback function for mouse clicks
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetMouseButtonCallback( GLFWmousebuttonfun cbfun )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set callback function
_glfwWin.MouseButtonCallback = cbfun;
}
//========================================================================
// glfwSetMousePosCallback() - Set callback function for mouse moves
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetMousePosCallback( GLFWmouseposfun cbfun )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set callback function
_glfwWin.MousePosCallback = cbfun;
// Call the callback function to let the application know the current
// mouse position
if( cbfun )
{
cbfun( _glfwInput.MousePosX, _glfwInput.MousePosY );
}
}
//========================================================================
// glfwSetMouseWheelCallback() - Set callback function for mouse wheel
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetMouseWheelCallback( GLFWmousewheelfun cbfun )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set callback function
_glfwWin.MouseWheelCallback = cbfun;
// Call the callback function to let the application know the current
// mouse wheel position
if( cbfun )
{
cbfun( _glfwInput.WheelPos );
}
}

210
libs/glfw/lib/internal.h Normal file
View File

@ -0,0 +1,210 @@
//========================================================================
// GLFW - An OpenGL framework
// File: internal.h
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef _internal_h_
#define _internal_h_
//========================================================================
// GLFWGLOBAL is a macro that places all global variables in the init.c
// module (all other modules reference global variables as 'extern')
//========================================================================
#if defined( _init_c_ )
#define GLFWGLOBAL
#else
#define GLFWGLOBAL extern
#endif
//========================================================================
// Input handling definitions
//========================================================================
// Internal key and button state/action definitions
#define GLFW_STICK 2
//========================================================================
// System independent include files
//========================================================================
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//------------------------------------------------------------------------
// Platform specific definitions goes in platform.h (which also includes
// glfw.h)
//------------------------------------------------------------------------
#include "platform.h"
//========================================================================
// System independent global variables (GLFW internals)
//========================================================================
// Flag indicating if GLFW has been initialized
#if defined( _init_c_ )
int _glfwInitialized = 0;
#else
GLFWGLOBAL int _glfwInitialized;
#endif
//------------------------------------------------------------------------
// Window hints (set by glfwOpenWindowHint - will go into _GLFWthread)
//------------------------------------------------------------------------
typedef struct {
int RefreshRate;
int AccumRedBits;
int AccumGreenBits;
int AccumBlueBits;
int AccumAlphaBits;
int AuxBuffers;
int Stereo;
int WindowNoResize;
int Samples;
} _GLFWhints;
GLFWGLOBAL _GLFWhints _glfwWinHints;
//------------------------------------------------------------------------
// Abstracted data stream (for image I/O)
//------------------------------------------------------------------------
typedef struct {
FILE* File;
void* Data;
long Position;
long Size;
} _GLFWstream;
//========================================================================
// Prototypes for platform specific implementation functions
//========================================================================
// Init/terminate
int _glfwPlatformInit( void );
int _glfwPlatformTerminate( void );
// Enable/Disable
void _glfwPlatformEnableSystemKeys( void );
void _glfwPlatformDisableSystemKeys( void );
// Fullscreen
int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount );
void _glfwPlatformGetDesktopMode( GLFWvidmode *mode );
// OpenGL extensions
int _glfwPlatformExtensionSupported( const char *extension );
void * _glfwPlatformGetProcAddress( const char *procname );
// Joystick
int _glfwPlatformGetJoystickParam( int joy, int param );
int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes );
int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons );
// Threads
GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg );
void _glfwPlatformDestroyThread( GLFWthread ID );
int _glfwPlatformWaitThread( GLFWthread ID, int waitmode );
GLFWthread _glfwPlatformGetThreadID( void );
GLFWmutex _glfwPlatformCreateMutex( void );
void _glfwPlatformDestroyMutex( GLFWmutex mutex );
void _glfwPlatformLockMutex( GLFWmutex mutex );
void _glfwPlatformUnlockMutex( GLFWmutex mutex );
GLFWcond _glfwPlatformCreateCond( void );
void _glfwPlatformDestroyCond( GLFWcond cond );
void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex, double timeout );
void _glfwPlatformSignalCond( GLFWcond cond );
void _glfwPlatformBroadcastCond( GLFWcond cond );
int _glfwPlatformGetNumberOfProcessors( void );
// Time
double _glfwPlatformGetTime( void );
void _glfwPlatformSetTime( double time );
void _glfwPlatformSleep( double time );
// Window management
int _glfwPlatformOpenWindow( int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int mode, _GLFWhints* hints );
void _glfwPlatformCloseWindow( void );
void _glfwPlatformSetWindowTitle( const char *title );
void _glfwPlatformSetWindowSize( int width, int height );
void _glfwPlatformSetWindowPos( int x, int y );
void _glfwPlatformIconifyWindow( void );
void _glfwPlatformRestoreWindow( void );
void _glfwPlatformSwapBuffers( void );
void _glfwPlatformSwapInterval( int interval );
void _glfwPlatformRefreshWindowParams( void );
void _glfwPlatformPollEvents( void );
void _glfwPlatformWaitEvents( void );
void _glfwPlatformHideMouseCursor( void );
void _glfwPlatformShowMouseCursor( void );
void _glfwPlatformSetMouseCursorPos( int x, int y );
//========================================================================
// Prototypes for platform independent internal functions
//========================================================================
// Window management (window.c)
void _glfwClearWindowHints( void );
// Input handling (window.c)
void _glfwClearInput( void );
void _glfwInputDeactivation( void );
void _glfwInputKey( int key, int action );
void _glfwInputChar( int character, int action );
void _glfwInputMouseClick( int button, int action );
// Threads (thread.c)
_GLFWthread * _glfwGetThreadPointer( int ID );
void _glfwAppendThread( _GLFWthread * t );
void _glfwRemoveThread( _GLFWthread * t );
// OpenGL extensions (glext.c)
int _glfwStringInExtensionString( const char *string, const GLubyte *extensions );
// Abstracted data streams (stream.c)
int _glfwOpenFileStream( _GLFWstream *stream, const char *name, const char *mode );
int _glfwOpenBufferStream( _GLFWstream *stream, void *data, long size );
long _glfwReadStream( _GLFWstream *stream, void *data, long size );
long _glfwTellStream( _GLFWstream *stream );
int _glfwSeekStream( _GLFWstream *stream, long offset, int whence );
void _glfwCloseStream( _GLFWstream *stream );
// Targa image I/O (tga.c)
int _glfwReadTGA( _GLFWstream *s, GLFWimage *img, int flags );
#endif // _internal_h_

101
libs/glfw/lib/joystick.c Normal file
View File

@ -0,0 +1,101 @@
//========================================================================
// GLFW - An OpenGL framework
// File: joystick.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW user functions ****
//************************************************************************
//========================================================================
// glfwGetJoystickParam() - Determine joystick capabilities
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwGetJoystickParam( int joy, int param )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return 0;
}
return _glfwPlatformGetJoystickParam( joy, param );
}
//========================================================================
// glfwGetJoystickPos() - Get joystick axis positions
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwGetJoystickPos( int joy, float *pos,
int numaxes )
{
int i;
// Is GLFW initialized?
if( !_glfwInitialized )
{
return 0;
}
// Clear positions
for( i = 0; i < numaxes; i++ )
{
pos[ i ] = 0.0f;
}
return _glfwPlatformGetJoystickPos( joy, pos, numaxes );
}
//========================================================================
// glfwGetJoystickButtons() - Get joystick button states
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwGetJoystickButtons( int joy,
unsigned char *buttons, int numbuttons )
{
int i;
// Is GLFW initialized?
if( !_glfwInitialized )
{
return 0;
}
// Clear button states
for( i = 0; i < numbuttons; i++ )
{
buttons[ i ] = GLFW_RELEASE;
}
return _glfwPlatformGetJoystickButtons( joy, buttons, numbuttons );
}

View File

@ -0,0 +1,172 @@
##########################################################################
# Makefile for GLFW on Mac OS X using GCC (Apple SDK).
#-------------------------------------------------------------------------
# To compile GLFW using this makefile, run:
# make -f Makefile.macosx.gcc
##########################################################################
##########################################################################
# Installation prefix (default to /usr/local)
##########################################################################
PREFIX ?= /usr/local
##########################################################################
# Default: Build GLFW static and shared library
##########################################################################
default: libglfw.a libglfw.dylib
##########################################################################
# Compiler settings
##########################################################################
CC = gcc
CFLAGS = -c -I. -I.. -Wall -O2 -fno-common -g
# Some modules should be optimized for speed (e.g. image decoding)
CFLAGS_SPEED = -c -I. -I.. -Wall -O3 -ffast-math -fno-common -g
##########################################################################
# Library builder settings
##########################################################################
AR = ar
SED = sed
INSTALL = install
ARFLAGS = -rcs
RANLIB = ranlib
DYLIBFLAGS = -framework AGL -framework Carbon -framework OpenGL \
-dynamiclib -Wl,-single_module -compatibility_version 1 \
-current_version 1 -install_name @executable_path/libglfw.dylib
##########################################################################
# Install GLFW header and static library
##########################################################################
install: libglfw.a libglfw.pc
$(INSTALL) -d $(PREFIX)/lib
$(INSTALL) -c -m 644 libglfw.a $(PREFIX)/lib/libglfw.a
$(RANLIB) $(PREFIX)/lib/libglfw.a
$(INSTALL) -d $(PREFIX)/include/GL
$(INSTALL) -c -m 644 ../../include/GL/glfw.h $(PREFIX)/include/GL/glfw.h
$(INSTALL) -d $(PREFIX)/lib/pkgconfig
$(INSTALL) -c -m 644 libglfw.pc $(PREFIX)/lib/pkgconfig/libglfw.pc
##########################################################################
# Object files for the GLFW library
##########################################################################
OBJS = \
enable.o \
fullscreen.o \
glext.o \
image.o \
init.o \
input.o \
joystick.o \
stream.o \
tga.o \
thread.o \
time.o \
window.o \
macosx_enable.o \
macosx_fullscreen.o \
macosx_glext.o \
macosx_init.o \
macosx_joystick.o \
macosx_thread.o \
macosx_time.o \
macosx_window.o
##########################################################################
# Rule for building libglfw.pc
##########################################################################
libglfw.pc: libglfw.pc.in
$(SED) -e 's,\@PREFIX\@,$(PREFIX),' libglfw.pc.in > libglfw.pc
##########################################################################
# Rule for building static library
##########################################################################
libglfw.a: $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
$(RANLIB) $@
##########################################################################
# Rule for building shared library
##########################################################################
libglfw.dylib: $(OBJS)
$(CC) -o $@ $(DYLIBFLAGS) $(OBJS)
##########################################################################
# Rule for cleaning up generated files
##########################################################################
clean:
@rm -f *.o libglfw.a libglfw.dylib libglfw.pc
##########################################################################
# Rules for building library object files
##########################################################################
enable.o: ../enable.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../enable.c
fullscreen.o: ../fullscreen.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../fullscreen.c
glext.o: ../glext.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../glext.c
image.o: ../image.c ../internal.h platform.h
$(CC) $(CFLAGS_SPEED) -o $@ ../image.c
init.o: ../init.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../init.c
input.o: ../input.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../input.c
joystick.o: ../joystick.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../joystick.c
stream.o: ../stream.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../stream.c
tga.o: ../tga.c ../internal.h platform.h
$(CC) $(CFLAGS_SPEED) -o $@ ../tga.c
thread.o: ../thread.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../thread.c
time.o: ../time.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../time.c
window.o: ../window.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../window.c
macosx_enable.o: macosx_enable.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_enable.c
macosx_fullscreen.o: macosx_fullscreen.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_fullscreen.c
macosx_glext.o: macosx_glext.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_glext.c
macosx_init.o: macosx_init.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_init.c
macosx_joystick.o: macosx_joystick.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_joystick.c
macosx_thread.o: macosx_thread.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_thread.c
macosx_time.o: macosx_time.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_time.c
macosx_window.o: macosx_window.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_window.c

View File

@ -0,0 +1,166 @@
##########################################################################
# Makefile for GLFW on Mac OS X using GCC (Apple SDK).
#-------------------------------------------------------------------------
# To compile GLFW using this makefile, run:
# make -f Makefile.macosx.gcc
##########################################################################
##########################################################################
# Installation prefix (default to /usr/local)
##########################################################################
PREFIX ?= /usr/local
##########################################################################
# Default: Build GLFW static library
##########################################################################
default: libglfw.a
##########################################################################
# Compiler settings
##########################################################################
CC = gcc
FATFLAGS = -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386
CFLAGS = -c -I. -I.. -Wall -Os -fno-common $(FATFLAGS)
# Some modules should be optimized for speed (e.g. image decoding)
CFLAGS_SPEED = -c -I. -I.. -Wall -O3 -ffast-math -fno-common $(FATFLAGS)
##########################################################################
# Library builder settings
##########################################################################
# Static library
SED = sed
INSTALL = install
MKLIB = ar
LIBFLAGS = -rcs
RANLIB = ranlib
##########################################################################
# Install GLFW header and static library
##########################################################################
install: libglfw.a libglfw.pc
$(INSTALL) -d $(PREFIX)/lib
$(INSTALL) -c -m 644 libglfw.a $(PREFIX)/lib/libglfw.a
$(RANLIB) $(PREFIX)/lib/libglfw.a
$(INSTALL) -d $(PREFIX)/include/GL
$(INSTALL) -c -m 644 ../../include/GL/glfw.h $(PREFIX)/include/GL/glfw.h
$(INSTALL) -d $(PREFIX)/lib/pkgconfig
$(INSTALL) -c -m 644 libglfw.pc $(PREFIX)/lib/pkgconfig/libglfw.pc
##########################################################################
# Rule for cleaning up generated files
##########################################################################
clean:
@rm -f *.o libglfw.a libglfw.pc
##########################################################################
# Object files which are part of the GLFW library
##########################################################################
OBJS = \
enable.o \
fullscreen.o \
glext.o \
image.o \
init.o \
input.o \
joystick.o \
stream.o \
tga.o \
thread.o \
time.o \
window.o \
macosx_enable.o \
macosx_fullscreen.o \
macosx_glext.o \
macosx_init.o \
macosx_joystick.o \
macosx_thread.o \
macosx_time.o \
macosx_window.o
##########################################################################
# Rule for building libglfw.pc
##########################################################################
libglfw.pc: libglfw.pc.in
$(SED) -e 's,\@PREFIX\@,$(PREFIX),' libglfw.pc.in > libglfw.pc
##########################################################################
# Rule for building library
##########################################################################
libglfw.a: $(OBJS)
rm -f $@
$(MKLIB) $(LIBFLAGS) $@ $(OBJS)
$(RANLIB) $@
##########################################################################
# Rules for building library object files
##########################################################################
enable.o: ../enable.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../enable.c
fullscreen.o: ../fullscreen.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../fullscreen.c
glext.o: ../glext.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../glext.c
image.o: ../image.c ../internal.h platform.h
$(CC) $(CFLAGS_SPEED) -o $@ ../image.c
init.o: ../init.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../init.c
input.o: ../input.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../input.c
joystick.o: ../joystick.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../joystick.c
stream.o: ../stream.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../stream.c
tga.o: ../tga.c ../internal.h platform.h
$(CC) $(CFLAGS_SPEED) -o $@ ../tga.c
thread.o: ../thread.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../thread.c
time.o: ../time.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../time.c
window.o: ../window.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ ../window.c
macosx_enable.o: macosx_enable.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_enable.c
macosx_fullscreen.o: macosx_fullscreen.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_fullscreen.c
macosx_glext.o: macosx_glext.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_glext.c
macosx_init.o: macosx_init.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_init.c
macosx_joystick.o: macosx_joystick.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_joystick.c
macosx_thread.o: macosx_thread.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_thread.c
macosx_time.o: macosx_time.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_time.c
macosx_window.o: macosx_window.c ../internal.h platform.h
$(CC) $(CFLAGS) -o $@ macosx_window.c

View File

@ -0,0 +1,11 @@
prefix=@PREFIX@
exec_prefix=@PREFIX@
libdir=@PREFIX@/lib
includedir=@PREFIX@/include
Name: GLFW
Description: A portable framework for OpenGL development
Version: 2.6.0
URL: http://glfw.sourceforge.net/
Libs: -L${libdir} -lglfw -framework AGL -framework OpenGL -framework Carbon
Cflags: -I${includedir}

View File

@ -0,0 +1,42 @@
//========================================================================
// GLFW - An OpenGL framework
// File: macosx_enable.c
// Platform: Mac OS X
// API Version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
void _glfwPlatformEnableSystemKeys( void )
{
// Nothing to do; event handling code checks the status of
// _glfwWin.SysKeysDisabled to ensure this behavior.
}
void _glfwPlatformDisableSystemKeys( void )
{
// Nothing to do; event handling code checks the status of
// _glfwWin.SysKeysDisabled to ensure this behavior.
}

View File

@ -0,0 +1,126 @@
//========================================================================
// GLFW - An OpenGL framework
// File: macosx_fullscreen.c
// Platform: Mac OS X
// API Version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//========================================================================
// _glfwVideoModesEqual() - Compares two video modes
//========================================================================
static int _glfwVideoModesEqual( GLFWvidmode* first,
GLFWvidmode* second )
{
if( first->Width != second->Width )
return 0;
if( first->Height != second->Height )
return 0;
if( first->RedBits + first->GreenBits + first->BlueBits !=
second->RedBits + second->GreenBits + second->BlueBits )
return 0;
return 1;
}
//========================================================================
// _glfwCGToGLFWVideoMode() - Converts a CG mode to a GLFW mode
//========================================================================
static void _glfwCGToGLFWVideoMode( CFDictionaryRef cgMode,
GLFWvidmode* glfwMode )
{
int bitsPerSample;
CFNumberGetValue( CFDictionaryGetValue( cgMode, kCGDisplayWidth ),
kCFNumberIntType,
&(glfwMode->Width) );
CFNumberGetValue( CFDictionaryGetValue( cgMode, kCGDisplayHeight ),
kCFNumberIntType,
&(glfwMode->Height) );
CFNumberGetValue( CFDictionaryGetValue( cgMode, kCGDisplayBitsPerSample ),
kCFNumberIntType,
&bitsPerSample );
glfwMode->RedBits = bitsPerSample;
glfwMode->GreenBits = bitsPerSample;
glfwMode->BlueBits = bitsPerSample;
}
//========================================================================
// _glfwPlatformGetVideoModes() - Get a list of available video modes
//========================================================================
int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )
{
int i, j, maxModes, numModes;
GLFWvidmode mode;
CFArrayRef availableModes = CGDisplayAvailableModes( kCGDirectMainDisplay );
CFIndex numberOfAvailableModes = CFArrayGetCount( availableModes );
numModes = 0;
maxModes = ( numberOfAvailableModes < maxcount ?
numberOfAvailableModes :
maxcount );
for( i = 0; i < maxModes; ++i )
{
_glfwCGToGLFWVideoMode( CFArrayGetValueAtIndex( availableModes, i ),
&mode );
// Is it a valid mode? (only list depths >= 15 bpp)
if( mode.RedBits + mode.GreenBits + mode.BlueBits < 15 )
continue;
// Check for duplicate of current mode in target list
for( j = 0; j < numModes; ++j )
{
if( _glfwVideoModesEqual( &mode, &(list[j]) ) )
break;
}
// If empty list or no match found
if( numModes == 0 || j == numModes )
list[numModes++] = mode;
}
return numModes;
}
//========================================================================
// glfwGetDesktopMode() - Get the desktop video mode
//========================================================================
void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )
{
_glfwCGToGLFWVideoMode( _glfwDesktopVideoMode, mode );
}

View File

@ -0,0 +1,52 @@
//========================================================================
// GLFW - An OpenGL framework
// File: macosx_glext.c
// Platform: Mac OS X
// API Version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
int _glfwPlatformExtensionSupported( const char *extension )
{
// There are no AGL, CGL or NSGL extensions.
return GL_FALSE;
}
void * _glfwPlatformGetProcAddress( const char *procname )
{
CFStringRef symbolName = CFStringCreateWithCString( kCFAllocatorDefault,
procname,
kCFStringEncodingASCII );
void *symbol = CFBundleGetFunctionPointerForName( _glfwLibrary.Libs.OpenGLFramework,
symbolName );
CFRelease( symbolName );
return symbol;
}

View File

@ -0,0 +1,194 @@
//========================================================================
// GLFW - An OpenGL framework
// File: macosx_init.c
// Platform: Mac OS X
// API Version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <unistd.h>
//========================================================================
// Global variables
//========================================================================
// KCHR resource pointer for keycode translation
void *KCHRPtr;
//========================================================================
// _glfwInitThreads() - Initialize GLFW thread package
//========================================================================
static void _glfwInitThreads( void )
{
// Initialize critical section handle
(void) pthread_mutex_init( &_glfwThrd.CriticalSection, NULL );
// The first thread (the main thread) has ID 0
_glfwThrd.NextID = 0;
// Fill out information about the main thread (this thread)
_glfwThrd.First.ID = _glfwThrd.NextID ++;
_glfwThrd.First.Function = NULL;
_glfwThrd.First.PosixID = pthread_self();
_glfwThrd.First.Previous = NULL;
_glfwThrd.First.Next = NULL;
}
#define NO_BUNDLE_MESSAGE \
"Working in unbundled mode. " \
"You should build a .app wrapper for your Mac OS X applications.\n"
#define UNBUNDLED \
fprintf(stderr, NO_BUNDLE_MESSAGE); \
_glfwLibrary.Unbundled = 1; \
return
void _glfwChangeToResourcesDirectory( void )
{
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL( mainBundle );
char resourcesPath[ _GLFW_MAX_PATH_LENGTH ];
CFStringRef lastComponent = CFURLCopyLastPathComponent( resourcesURL );
if ( kCFCompareEqualTo != CFStringCompare(
CFSTR( "Resources" ),
lastComponent,
0 ) )
{
UNBUNDLED;
}
CFRelease( lastComponent );
if( !CFURLGetFileSystemRepresentation( resourcesURL,
TRUE,
(UInt8*)resourcesPath,
_GLFW_MAX_PATH_LENGTH ) )
{
CFRelease( resourcesURL );
UNBUNDLED;
}
CFRelease( resourcesURL );
if( chdir( resourcesPath ) != 0 )
{
UNBUNDLED;
}
}
int _glfwPlatformInit( void )
{
struct timeval tv;
UInt32 nullDummy = 0;
_glfwWin.MacWindow = NULL;
_glfwWin.AGLContext = NULL;
_glfwWin.CGLContext = NULL;
_glfwWin.WindowFunctions = NULL;
_glfwWin.MouseUPP = NULL;
_glfwWin.CommandUPP = NULL;
_glfwWin.KeyboardUPP = NULL;
_glfwWin.WindowUPP = NULL;
_glfwInput.Modifiers = 0;
_glfwLibrary.Unbundled = 0;
_glfwLibrary.Libs.OpenGLFramework
= CFBundleGetBundleWithIdentifier( CFSTR( "com.apple.opengl" ) );
if( _glfwLibrary.Libs.OpenGLFramework == NULL )
{
fprintf(
stderr,
"glfwInit failing because you aren't linked to OpenGL\n" );
return GL_FALSE;
}
_glfwDesktopVideoMode = CGDisplayCurrentMode( kCGDirectMainDisplay );
if( _glfwDesktopVideoMode == NULL )
{
fprintf(
stderr,
"glfwInit failing because it kind find the desktop display mode\n" );
return GL_FALSE;
}
_glfwInitThreads();
_glfwChangeToResourcesDirectory();
if( !_glfwInstallEventHandlers() )
{
fprintf(
stderr,
"glfwInit failing because it can't install event handlers\n" );
_glfwPlatformTerminate();
return GL_FALSE;
}
// Ugly hack to reduce the nasty jump that occurs at the first non-
// sys keypress, caused by OS X loading certain meta scripts used
// for lexical- and raw keycode translation - instead of letting
// this happen while our application is running, we do some blunt
// function calls in advance just to get the script caching out of
// the way BEFORE our window/screen is opened. These calls might
// generate err return codes, but we don't care in this case.
// NOTE: KCHRPtr is declared globally, because we need it later on.
KCHRPtr = (void *)GetScriptVariable( smCurrentScript, smKCHRCache );
KeyTranslate( KCHRPtr, 0, &nullDummy );
UppercaseText( (char *)&nullDummy, 0, smSystemScript );
gettimeofday( &tv, NULL );
_glfwLibrary.Timer.t0 = tv.tv_sec + (double) tv.tv_usec / 1000000.0;
return GL_TRUE;
}
int _glfwPlatformTerminate( void )
{
if( _glfwWin.MouseUPP != NULL )
{
DisposeEventHandlerUPP( _glfwWin.MouseUPP );
_glfwWin.MouseUPP = NULL;
}
if( _glfwWin.CommandUPP != NULL )
{
DisposeEventHandlerUPP( _glfwWin.CommandUPP );
_glfwWin.CommandUPP = NULL;
}
if( _glfwWin.KeyboardUPP != NULL )
{
DisposeEventHandlerUPP( _glfwWin.KeyboardUPP );
_glfwWin.KeyboardUPP = NULL;
}
return GL_TRUE;
}

View File

@ -0,0 +1,50 @@
//========================================================================
// GLFW - An OpenGL framework
// File: macosx_joystick.c
// Platform: Mac OS X
// API Version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
// TO DO: use HID manager to implement joystick support.
int _glfwPlatformGetJoystickParam( int joy, int param )
{
// GL_FALSE == 0
return 0;
}
int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )
{
return 0;
}
int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons )
{
return 0;
}

View File

@ -0,0 +1,414 @@
//========================================================================
// GLFW - An OpenGL framework
// File: macosx_thread.c
// Platform: Mac OS X
// API Version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwNewThread() - This is simply a "wrapper" for calling the user
// thread function.
//========================================================================
void * _glfwNewThread( void * arg )
{
GLFWthreadfun threadfun;
_GLFWthread *t;
// Get pointer to thread information for current thread
t = _glfwGetThreadPointer( glfwGetThreadID() );
if( t == NULL )
{
return 0;
}
// Get user thread function pointer
threadfun = t->Function;
// Call the user thread function
threadfun( arg );
// Remove thread from thread list
ENTER_THREAD_CRITICAL_SECTION
_glfwRemoveThread( t );
LEAVE_THREAD_CRITICAL_SECTION
// When the thread function returns, the thread will die...
return NULL;
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformCreateThread() - Create a new thread
//========================================================================
GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )
{
GLFWthread ID;
_GLFWthread *t;
int result;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Create a new thread information memory area
t = (_GLFWthread *) malloc( sizeof(_GLFWthread) );
if( t == NULL )
{
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
return -1;
}
// Get a new unique thread id
ID = _glfwThrd.NextID ++;
// Store thread information in the thread list
t->Function = fun;
t->ID = ID;
// Create thread
result = pthread_create(
&t->PosixID, // Thread handle
NULL, // Default thread attributes
_glfwNewThread, // Thread function (a wrapper function)
(void *)arg // Argument to thread is user argument
);
// Did the thread creation fail?
if( result != 0 )
{
free( (void *) t );
LEAVE_THREAD_CRITICAL_SECTION
return -1;
}
// Append thread to thread list
_glfwAppendThread( t );
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Return the GLFW thread ID
return ID;
}
//========================================================================
// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY
// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME
// SITUATIONS!
//========================================================================
void _glfwPlatformDestroyThread( GLFWthread ID )
{
_GLFWthread *t;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Get thread information pointer
t = _glfwGetThreadPointer( ID );
if( t == NULL )
{
LEAVE_THREAD_CRITICAL_SECTION
return;
}
// Simply murder the process, no mercy!
pthread_kill( t->PosixID, SIGKILL );
// Remove thread from thread list
_glfwRemoveThread( t );
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
}
//========================================================================
// _glfwPlatformWaitThread() - Wait for a thread to die
//========================================================================
int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )
{
pthread_t thread;
_GLFWthread *t;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Get thread information pointer
t = _glfwGetThreadPointer( ID );
// Is the thread already dead?
if( t == NULL )
{
LEAVE_THREAD_CRITICAL_SECTION
return GL_TRUE;
}
// If got this far, the thread is alive => polling returns FALSE
if( waitmode == GLFW_NOWAIT )
{
LEAVE_THREAD_CRITICAL_SECTION
return GL_FALSE;
}
// Get thread handle
thread = t->PosixID;
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Wait for thread to die
(void) pthread_join( thread, NULL );
return GL_TRUE;
}
//========================================================================
// _glfwPlatformGetThreadID() - Return the thread ID for the current
// thread
//========================================================================
GLFWthread _glfwPlatformGetThreadID( void )
{
_GLFWthread *t;
GLFWthread ID = -1;
pthread_t posixID;
// Get current thread ID
posixID = pthread_self();
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Loop through entire list of threads to find the matching POSIX
// thread ID
for( t = &_glfwThrd.First; t != NULL; t = t->Next )
{
if( t->PosixID == posixID )
{
ID = t->ID;
break;
}
}
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Return the found GLFW thread identifier
return ID;
}
//========================================================================
// _glfwPlatformCreateMutex() - Create a mutual exclusion object
//========================================================================
GLFWmutex _glfwPlatformCreateMutex( void )
{
pthread_mutex_t *mutex;
// Allocate memory for mutex
mutex = (pthread_mutex_t *) malloc( sizeof( pthread_mutex_t ) );
if( !mutex )
{
return NULL;
}
// Initialise a mutex object
(void) pthread_mutex_init( mutex, NULL );
// Cast to GLFWmutex and return
return (GLFWmutex) mutex;
}
//========================================================================
// _glfwPlatformDestroyMutex() - Destroy a mutual exclusion object
//========================================================================
void _glfwPlatformDestroyMutex( GLFWmutex mutex )
{
// Destroy the mutex object
pthread_mutex_destroy( (pthread_mutex_t *) mutex );
// Free memory for mutex object
free( (void *) mutex );
}
//========================================================================
// _glfwPlatformLockMutex() - Request access to a mutex
//========================================================================
void _glfwPlatformLockMutex( GLFWmutex mutex )
{
// Wait for mutex to be released
(void) pthread_mutex_lock( (pthread_mutex_t *) mutex );
}
//========================================================================
// _glfwPlatformUnlockMutex() - Release a mutex
//========================================================================
void _glfwPlatformUnlockMutex( GLFWmutex mutex )
{
// Release mutex
pthread_mutex_unlock( (pthread_mutex_t *) mutex );
}
//========================================================================
// _glfwPlatformCreateCond() - Create a new condition variable object
//========================================================================
GLFWcond _glfwPlatformCreateCond( void )
{
pthread_cond_t *cond;
// Allocate memory for condition variable
cond = (pthread_cond_t *) malloc( sizeof(pthread_cond_t) );
if( !cond )
{
return NULL;
}
// Initialise condition variable
(void) pthread_cond_init( cond, NULL );
// Cast to GLFWcond and return
return (GLFWcond) cond;
}
//========================================================================
// _glfwPlatformDestroyCond() - Destroy a condition variable object
//========================================================================
void _glfwPlatformDestroyCond( GLFWcond cond )
{
// Destroy the condition variable object
(void) pthread_cond_destroy( (pthread_cond_t *) cond );
// Free memory for condition variable object
free( (void *) cond );
}
//========================================================================
// _glfwPlatformWaitCond() - Wait for a condition to be raised
//========================================================================
void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,
double timeout )
{
struct timeval currenttime;
struct timespec wait;
long dt_sec, dt_usec;
// Select infinite or timed wait
if( timeout >= GLFW_INFINITY )
{
// Wait for condition (infinite wait)
(void) pthread_cond_wait( (pthread_cond_t *) cond,
(pthread_mutex_t *) mutex );
}
else
{
// Set timeout time, relatvie to current time
gettimeofday( &currenttime, NULL );
dt_sec = (long) timeout;
dt_usec = (long) ((timeout - (double)dt_sec) * 1000000.0);
wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;
if( wait.tv_nsec > 1000000000L )
{
wait.tv_nsec -= 1000000000L;
dt_sec ++;
}
wait.tv_sec = currenttime.tv_sec + dt_sec;
// Wait for condition (timed wait)
(void) pthread_cond_timedwait( (pthread_cond_t *) cond,
(pthread_mutex_t *) mutex, &wait );
}
}
//========================================================================
// _glfwPlatformSignalCond() - Signal a condition to one waiting thread
//========================================================================
void _glfwPlatformSignalCond( GLFWcond cond )
{
// Signal condition
(void) pthread_cond_signal( (pthread_cond_t *) cond );
}
//========================================================================
// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting
// threads
//========================================================================
void _glfwPlatformBroadcastCond( GLFWcond cond )
{
// Broadcast condition
(void) pthread_cond_broadcast( (pthread_cond_t *) cond );
}
//========================================================================
// _glfwPlatformGetNumberOfProcessors() - Return the number of processors
// in the system.
//========================================================================
int _glfwPlatformGetNumberOfProcessors( void )
{
int n;
// Get number of processors online
_glfw_numprocessors( n );
return n;
}

View File

@ -0,0 +1,112 @@
//========================================================================
// GLFW - An OpenGL framework
// File: macosx_time.c
// Platform: Mac OS X
// API Version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// Return timer value in seconds
//========================================================================
double _glfwPlatformGetTime( void )
{
struct timeval tv;
gettimeofday( &tv, NULL );
return tv.tv_sec + (double) tv.tv_usec / 1000000.0 - _glfwLibrary.Timer.t0;
}
//========================================================================
// Set timer value in seconds
//========================================================================
void _glfwPlatformSetTime( double time )
{
struct timeval tv;
gettimeofday( &tv, NULL );
_glfwLibrary.Timer.t0 = tv.tv_sec + (double) tv.tv_usec / 1000000.0 - time;
}
//========================================================================
// Put a thread to sleep for a specified amount of time
//========================================================================
void _glfwPlatformSleep( double time )
{
if( time == 0.0 )
{
sched_yield();
return;
}
struct timeval currenttime;
struct timespec wait;
pthread_mutex_t mutex;
pthread_cond_t cond;
long dt_sec, dt_usec;
// Not all pthread implementations have a pthread_sleep() function. We
// do it the portable way, using a timed wait for a condition that we
// will never signal. NOTE: The unistd functions sleep/usleep suspends
// the entire PROCESS, not a signle thread, which is why we can not
// use them to implement glfwSleep.
// Set timeout time, relatvie to current time
gettimeofday( &currenttime, NULL );
dt_sec = (long) time;
dt_usec = (long) ((time - (double)dt_sec) * 1000000.0);
wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;
if( wait.tv_nsec > 1000000000L )
{
wait.tv_nsec -= 1000000000L;
dt_sec ++;
}
wait.tv_sec = currenttime.tv_sec + dt_sec;
// Initialize condition and mutex objects
pthread_mutex_init( &mutex, NULL );
pthread_cond_init( &cond, NULL );
// Do a timed wait
pthread_mutex_lock( &mutex );
pthread_cond_timedwait( &cond, &mutex, &wait );
pthread_mutex_unlock( &mutex );
// Destroy condition and mutex objects
pthread_mutex_destroy( &mutex );
pthread_cond_destroy( &cond );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,349 @@
//========================================================================
// GLFW - An OpenGL framework
// File: platform.h
// Platform: Mac OS X
// API Version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef _platform_h_
#define _platform_h_
// This is the Mac OS X version of GLFW
#define _GLFW_MAC_OS_X
// Include files
#include <Carbon/Carbon.h>
#include <OpenGL/OpenGL.h>
#include <AGL/agl.h>
#include <sched.h>
#include <pthread.h>
#include <sys/sysctl.h>
#include "../../include/GL/glfw.h"
//========================================================================
// Defines
//========================================================================
#define _GLFW_MAX_PATH_LENGTH (8192)
#define MAC_KEY_ENTER 0x24
#define MAC_KEY_RETURN 0x34
#define MAC_KEY_ESC 0x35
#define MAC_KEY_F1 0x7A
#define MAC_KEY_F2 0x78
#define MAC_KEY_F3 0x63
#define MAC_KEY_F4 0x76
#define MAC_KEY_F5 0x60
#define MAC_KEY_F6 0x61
#define MAC_KEY_F7 0x62
#define MAC_KEY_F8 0x64
#define MAC_KEY_F9 0x65
#define MAC_KEY_F10 0x6D
#define MAC_KEY_F11 0x67
#define MAC_KEY_F12 0x6F
#define MAC_KEY_F13 0x69
#define MAC_KEY_F14 0x6B
#define MAC_KEY_F15 0x71
#define MAC_KEY_UP 0x7E
#define MAC_KEY_DOWN 0x7D
#define MAC_KEY_LEFT 0x7B
#define MAC_KEY_RIGHT 0x7C
#define MAC_KEY_TAB 0x30
#define MAC_KEY_BACKSPACE 0x33
#define MAC_KEY_HELP 0x72
#define MAC_KEY_DEL 0x75
#define MAC_KEY_PAGEUP 0x74
#define MAC_KEY_PAGEDOWN 0x79
#define MAC_KEY_HOME 0x73
#define MAC_KEY_END 0x77
#define MAC_KEY_KP_0 0x52
#define MAC_KEY_KP_1 0x53
#define MAC_KEY_KP_2 0x54
#define MAC_KEY_KP_3 0x55
#define MAC_KEY_KP_4 0x56
#define MAC_KEY_KP_5 0x57
#define MAC_KEY_KP_6 0x58
#define MAC_KEY_KP_7 0x59
#define MAC_KEY_KP_8 0x5B
#define MAC_KEY_KP_9 0x5C
#define MAC_KEY_KP_DIVIDE 0x4B
#define MAC_KEY_KP_MULTIPLY 0x43
#define MAC_KEY_KP_SUBTRACT 0x4E
#define MAC_KEY_KP_ADD 0x45
#define MAC_KEY_KP_DECIMAL 0x41
#define MAC_KEY_KP_EQUAL 0x51
#define MAC_KEY_KP_ENTER 0x4C
//========================================================================
// full-screen/desktop-window "virtual" function table
//========================================================================
typedef int ( * GLFWmacopenwindowfun )( int, int, int, int, int, int, int, int, int, int, int, int, int, int, int );
typedef void ( * GLFWmacclosewindowfun )( void );
typedef void ( * GLFWmacsetwindowtitlefun )( const char * );
typedef void ( * GLFWmacsetwindowsizefun )( int, int );
typedef void ( * GLFWmacsetwindowposfun )( int, int );
typedef void ( * GLFWmaciconifywindowfun )( void );
typedef void ( * GLFWmacrestorewindowfun )( void );
typedef void ( * GLFWmacrefreshwindowparamsfun )( void );
typedef void ( * GLFWmacsetmousecursorposfun )( int, int );
typedef struct
{
GLFWmacopenwindowfun OpenWindow;
GLFWmacclosewindowfun CloseWindow;
GLFWmacsetwindowtitlefun SetWindowTitle;
GLFWmacsetwindowsizefun SetWindowSize;
GLFWmacsetwindowposfun SetWindowPos;
GLFWmaciconifywindowfun IconifyWindow;
GLFWmacrestorewindowfun RestoreWindow;
GLFWmacrefreshwindowparamsfun RefreshWindowParams;
GLFWmacsetmousecursorposfun SetMouseCursorPos;
}
_GLFWmacwindowfunctions;
//========================================================================
// Global variables (GLFW internals)
//========================================================================
GLFWGLOBAL CFDictionaryRef _glfwDesktopVideoMode;
//------------------------------------------------------------------------
// Window structure
//------------------------------------------------------------------------
typedef struct _GLFWwin_struct _GLFWwin;
struct _GLFWwin_struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Window states
int Opened; // Flag telling if window is opened or not
int Active; // Application active flag
int Iconified; // Window iconified flag
// User callback functions
GLFWwindowsizefun WindowSizeCallback;
GLFWwindowclosefun WindowCloseCallback;
GLFWwindowrefreshfun WindowRefreshCallback;
GLFWmousebuttonfun MouseButtonCallback;
GLFWmouseposfun MousePosCallback;
GLFWmousewheelfun MouseWheelCallback;
GLFWkeyfun KeyCallback;
GLFWcharfun CharCallback;
// User selected window settings
int Fullscreen; // Fullscreen flag
int MouseLock; // Mouse-lock flag
int AutoPollEvents; // Auto polling flag
int SysKeysDisabled; // System keys disabled flag
int RefreshRate; // Refresh rate (for fullscreen mode)
int WindowNoResize; // Resize- and maximize gadgets disabled flag
int Samples;
// Window status
int Width, Height; // Window width and heigth
// Extensions & OpenGL version
int Has_GL_SGIS_generate_mipmap;
int Has_GL_ARB_texture_non_power_of_two;
int GLVerMajor,GLVerMinor;
// ========= PLATFORM SPECIFIC PART ======================================
WindowRef MacWindow;
AGLContext AGLContext;
CGLContextObj CGLContext;
EventHandlerUPP MouseUPP;
EventHandlerUPP CommandUPP;
EventHandlerUPP KeyboardUPP;
EventHandlerUPP WindowUPP;
_GLFWmacwindowfunctions* WindowFunctions;
// for easy access by _glfwPlatformGetWindowParam
int Accelerated;
int RedBits, GreenBits, BlueBits, AlphaBits;
int DepthBits;
int StencilBits;
int AccumRedBits, AccumGreenBits, AccumBlueBits, AccumAlphaBits;
int AuxBuffers;
int Stereo;
};
GLFWGLOBAL _GLFWwin _glfwWin;
//------------------------------------------------------------------------
// User input status (some of this should go in _GLFWwin)
//------------------------------------------------------------------------
GLFWGLOBAL struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Mouse status
int MousePosX, MousePosY;
int WheelPos;
char MouseButton[ GLFW_MOUSE_BUTTON_LAST+1 ];
// Keyboard status
char Key[ GLFW_KEY_LAST+1 ];
int LastChar;
// User selected settings
int StickyKeys;
int StickyMouseButtons;
int KeyRepeat;
// ========= PLATFORM SPECIFIC PART ======================================
UInt32 Modifiers;
} _glfwInput;
//------------------------------------------------------------------------
// Thread information
//------------------------------------------------------------------------
typedef struct _GLFWthread_struct _GLFWthread;
// Thread record (one for each thread)
struct _GLFWthread_struct {
// Pointer to previous and next threads in linked list
_GLFWthread *Previous, *Next;
// GLFW user side thread information
GLFWthread ID;
GLFWthreadfun Function;
// System side thread information
pthread_t PosixID;
};
// General thread information
GLFWGLOBAL struct {
// Critical section lock
pthread_mutex_t CriticalSection;
// Next thread ID to use (increments for every created thread)
GLFWthread NextID;
// First thread in linked list (always the main thread)
_GLFWthread First;
} _glfwThrd;
//------------------------------------------------------------------------
// Library global data
//------------------------------------------------------------------------
GLFWGLOBAL struct {
// Timer data
struct {
double t0;
} Timer;
struct {
// Bundle for dynamically-loading extension function pointers
CFBundleRef OpenGLFramework;
} Libs;
int Unbundled;
} _glfwLibrary;
//========================================================================
// Macros for encapsulating critical code sections (i.e. making parts
// of GLFW thread safe)
//========================================================================
// Define so we can use the same thread code as X11
#define _glfw_numprocessors(n) { \
int mib[2], ncpu; \
size_t len = 1; \
mib[0] = CTL_HW; \
mib[1] = HW_NCPU; \
n = 1; \
if( sysctl( mib, 2, &ncpu, &len, NULL, 0 ) != -1 ) \
{ \
if( len > 0 ) \
{ \
n = ncpu; \
} \
} \
}
// Thread list management
#define ENTER_THREAD_CRITICAL_SECTION \
pthread_mutex_lock( &_glfwThrd.CriticalSection );
#define LEAVE_THREAD_CRITICAL_SECTION \
pthread_mutex_unlock( &_glfwThrd.CriticalSection );
//========================================================================
// Prototypes for platform specific internal functions
//========================================================================
void _glfwChangeToResourcesDirectory( void );
int _glfwInstallEventHandlers( void );
//========================================================================
// Prototypes for full-screen/desktop-window "virtual" functions
//========================================================================
int _glfwMacFSOpenWindow( int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int accumredbits, int accumgreenbits, int accumbluebits, int accumalphabits, int auxbuffers, int stereo, int refreshrate );
void _glfwMacFSCloseWindow( void );
void _glfwMacFSSetWindowTitle( const char *title );
void _glfwMacFSSetWindowSize( int width, int height );
void _glfwMacFSSetWindowPos( int x, int y );
void _glfwMacFSIconifyWindow( void );
void _glfwMacFSRestoreWindow( void );
void _glfwMacFSRefreshWindowParams( void );
void _glfwMacFSSetMouseCursorPos( int x, int y );
int _glfwMacDWOpenWindow( int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int accumredbits, int accumgreenbits, int accumbluebits, int accumalphabits, int auxbuffers, int stereo, int refreshrate );
void _glfwMacDWCloseWindow( void );
void _glfwMacDWSetWindowTitle( const char *title );
void _glfwMacDWSetWindowSize( int width, int height );
void _glfwMacDWSetWindowPos( int x, int y );
void _glfwMacDWIconifyWindow( void );
void _glfwMacDWRestoreWindow( void );
void _glfwMacDWRefreshWindowParams( void );
void _glfwMacDWSetMouseCursorPos( int x, int y );
#endif // _platform_h_

194
libs/glfw/lib/stream.c Normal file
View File

@ -0,0 +1,194 @@
//========================================================================
// GLFW - An OpenGL framework
// File: stream.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//========================================================================
// Opens a GLFW stream with a file
//========================================================================
int _glfwOpenFileStream( _GLFWstream *stream, const char* name, const char* mode )
{
memset( stream, 0, sizeof(_GLFWstream) );
stream->File = fopen( name, mode );
if( stream->File == NULL )
{
return GL_FALSE;
}
return GL_TRUE;
}
//========================================================================
// Opens a GLFW stream with a memory block
//========================================================================
int _glfwOpenBufferStream( _GLFWstream *stream, void *data, long size )
{
memset( stream, 0, sizeof(_GLFWstream) );
stream->Data = data;
stream->Size = size;
return GL_TRUE;
}
//========================================================================
// Reads data from a GLFW stream
//========================================================================
long _glfwReadStream( _GLFWstream *stream, void *data, long size )
{
if( stream->File != NULL )
{
return fread( data, 1, size, stream->File );
}
if( stream->Data != NULL )
{
// Check for EOF
if( stream->Position == stream->Size )
{
return 0;
}
// Clamp read size to available data
if( stream->Position + size > stream->Size )
{
size = stream->Size - stream->Position;
}
// Perform data read
memcpy( data, (unsigned char*) stream->Data + stream->Position, size );
stream->Position += size;
return size;
}
return 0;
}
//========================================================================
// Returns the current position of a GLFW stream
//========================================================================
long _glfwTellStream( _GLFWstream *stream )
{
if( stream->File != NULL )
{
return ftell( stream->File );
}
if( stream->Data != NULL )
{
return stream->Position;
}
return 0;
}
//========================================================================
// Sets the current position of a GLFW stream
//========================================================================
int _glfwSeekStream( _GLFWstream *stream, long offset, int whence )
{
long position;
if( stream->File != NULL )
{
if( fseek( stream->File, offset, whence ) != 0 )
{
return GL_FALSE;
}
return GL_TRUE;
}
if( stream->Data != NULL )
{
position = offset;
// Handle whence parameter
if( whence == SEEK_CUR )
{
position += stream->Position;
}
else if( whence == SEEK_END )
{
position += stream->Size;
}
else if( whence != SEEK_SET )
{
return GL_FALSE;
}
// Clamp offset to buffer bounds and apply it
if( position > stream->Size )
{
stream->Position = stream->Size;
}
else if( position < 0 )
{
stream->Position = 0;
}
else
{
stream->Position = position;
}
return GL_TRUE;
}
return GL_FALSE;
}
//========================================================================
// Closes a GLFW stream
//========================================================================
void _glfwCloseStream( _GLFWstream *stream )
{
if( stream->File != NULL )
{
fclose( stream->File );
}
// Nothing to be done about (user allocated) memory blocks
memset( stream, 0, sizeof(_GLFWstream) );
}

405
libs/glfw/lib/tga.c Normal file
View File

@ -0,0 +1,405 @@
//========================================================================
// GLFW - An OpenGL framework
// File: tga.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
//========================================================================
// Description:
//
// TGA format image file loader. This module supports version 1 Targa
// images, with these restrictions:
// - Pixel format may only be 8, 24 or 32 bits
// - Colormaps must be no longer than 256 entries
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions & declarations ****
//************************************************************************
//========================================================================
// TGA file header information
//========================================================================
typedef struct {
int idlen; // 1 byte
int cmaptype; // 1 byte
int imagetype; // 1 byte
int cmapfirstidx; // 2 bytes
int cmaplen; // 2 bytes
int cmapentrysize; // 1 byte
int xorigin; // 2 bytes
int yorigin; // 2 bytes
int width; // 2 bytes
int height; // 2 bytes
int bitsperpixel; // 1 byte
int imageinfo; // 1 byte
int _alphabits; // (derived from imageinfo)
int _origin; // (derived from imageinfo)
} _tga_header_t;
#define _TGA_CMAPTYPE_NONE 0
#define _TGA_CMAPTYPE_PRESENT 1
#define _TGA_IMAGETYPE_NONE 0
#define _TGA_IMAGETYPE_CMAP 1
#define _TGA_IMAGETYPE_TC 2
#define _TGA_IMAGETYPE_GRAY 3
#define _TGA_IMAGETYPE_CMAP_RLE 9
#define _TGA_IMAGETYPE_TC_RLE 10
#define _TGA_IMAGETYPE_GRAY_RLE 11
#define _TGA_IMAGEINFO_ALPHA_MASK 0x0f
#define _TGA_IMAGEINFO_ALPHA_SHIFT 0
#define _TGA_IMAGEINFO_ORIGIN_MASK 0x30
#define _TGA_IMAGEINFO_ORIGIN_SHIFT 4
#define _TGA_ORIGIN_BL 0
#define _TGA_ORIGIN_BR 1
#define _TGA_ORIGIN_UL 2
#define _TGA_ORIGIN_UR 3
//========================================================================
// _glfwReadTGAHeader() - Read TGA file header (and check that it is
// valid)
//========================================================================
static int _glfwReadTGAHeader( _GLFWstream *s, _tga_header_t *h )
{
unsigned char buf[ 18 ];
int pos;
// Read TGA file header from file
pos = _glfwTellStream( s );
_glfwReadStream( s, buf, 18 );
// Interpret header (endian independent parsing)
h->idlen = (int) buf[0];
h->cmaptype = (int) buf[1];
h->imagetype = (int) buf[2];
h->cmapfirstidx = (int) buf[3] | (((int) buf[4]) << 8);
h->cmaplen = (int) buf[5] | (((int) buf[6]) << 8);
h->cmapentrysize = (int) buf[7];
h->xorigin = (int) buf[8] | (((int) buf[9]) << 8);
h->yorigin = (int) buf[10] | (((int) buf[11]) << 8);
h->width = (int) buf[12] | (((int) buf[13]) << 8);
h->height = (int) buf[14] | (((int) buf[15]) << 8);
h->bitsperpixel = (int) buf[16];
h->imageinfo = (int) buf[17];
// Extract alphabits and origin information
h->_alphabits = (int) (h->imageinfo & _TGA_IMAGEINFO_ALPHA_MASK) >>
_TGA_IMAGEINFO_ALPHA_SHIFT;
h->_origin = (int) (h->imageinfo & _TGA_IMAGEINFO_ORIGIN_MASK) >>
_TGA_IMAGEINFO_ORIGIN_SHIFT;
// Validate TGA header (is this a TGA file?)
if( (h->cmaptype == 0 || h->cmaptype == 1) &&
((h->imagetype >= 1 && h->imagetype <= 3) ||
(h->imagetype >= 9 && h->imagetype <= 11)) &&
(h->bitsperpixel == 8 || h->bitsperpixel == 24 ||
h->bitsperpixel == 32) )
{
// Skip the ID field
_glfwSeekStream( s, h->idlen, SEEK_CUR );
// Indicate that the TGA header was valid
return GL_TRUE;
}
else
{
// Restore file position
_glfwSeekStream( s, pos, SEEK_SET );
// Indicate that the TGA header was invalid
return GL_FALSE;
}
}
//========================================================================
// _glfwReadTGA_RLE() - Read Run-Length Encoded data
//========================================================================
static void _glfwReadTGA_RLE( unsigned char *buf, int size, int bpp,
_GLFWstream *s )
{
int repcount, bytes, k, n;
unsigned char pixel[ 4 ];
char c;
// Dummy check
if( bpp > 4 )
{
return;
}
while( size > 0 )
{
// Get repetition count
_glfwReadStream( s, &c, 1 );
repcount = (unsigned int) c;
bytes = ((repcount & 127) + 1) * bpp;
if( size < bytes )
{
bytes = size;
}
// Run-Length packet?
if( repcount & 128 )
{
_glfwReadStream( s, pixel, bpp );
for( n = 0; n < (repcount & 127) + 1; n ++ )
{
for( k = 0; k < bpp; k ++ )
{
*buf ++ = pixel[ k ];
}
}
}
else
{
// It's a Raw packet
_glfwReadStream( s, buf, bytes );
buf += bytes;
}
size -= bytes;
}
}
//========================================================================
// _glfwReadTGA() - Read a TGA image from a file
//========================================================================
int _glfwReadTGA( _GLFWstream *s, GLFWimage *img, int flags )
{
_tga_header_t h;
unsigned char *cmap, *pix, tmp, *src, *dst;
int cmapsize, pixsize, pixsize2;
int bpp, bpp2, k, m, n, swapx, swapy;
// Read TGA header
if( !_glfwReadTGAHeader( s, &h ) )
{
return 0;
}
// Is there a colormap?
cmapsize = (h.cmaptype == _TGA_CMAPTYPE_PRESENT ? 1 : 0) * h.cmaplen *
((h.cmapentrysize+7) / 8);
if( cmapsize > 0 )
{
// Is it a colormap that we can handle?
if( (h.cmapentrysize != 24 && h.cmapentrysize != 32) ||
h.cmaplen == 0 || h.cmaplen > 256 )
{
return 0;
}
// Allocate memory for colormap
cmap = (unsigned char *) malloc( cmapsize );
if( cmap == NULL )
{
return 0;
}
// Read colormap from file
_glfwReadStream( s, cmap, cmapsize );
}
else
{
cmap = NULL;
}
// Size of pixel data
pixsize = h.width * h.height * ((h.bitsperpixel + 7) / 8);
// Bytes per pixel (pixel data - unexpanded)
bpp = (h.bitsperpixel + 7) / 8;
// Bytes per pixel (expanded pixels - not colormap indeces)
if( cmap )
{
bpp2 = (h.cmapentrysize + 7) / 8;
}
else
{
bpp2 = bpp;
}
// For colormaped images, the RGB/RGBA image data may use more memory
// than the stored pixel data
pixsize2 = h.width * h.height * bpp2;
// Allocate memory for pixel data
pix = (unsigned char *) malloc( pixsize2 );
if( pix == NULL )
{
if( cmap )
{
free( cmap );
}
return 0;
}
// Read pixel data from file
if( h.imagetype >= _TGA_IMAGETYPE_CMAP_RLE )
{
_glfwReadTGA_RLE( pix, pixsize, bpp, s );
}
else
{
_glfwReadStream( s, pix, pixsize );
}
// If the image origin is not what we want, re-arrange the pixels
switch( h._origin )
{
default:
case _TGA_ORIGIN_UL:
swapx = 0;
swapy = 1;
break;
case _TGA_ORIGIN_BL:
swapx = 0;
swapy = 0;
break;
case _TGA_ORIGIN_UR:
swapx = 1;
swapy = 1;
break;
case _TGA_ORIGIN_BR:
swapx = 1;
swapy = 0;
break;
}
if( (swapy && !(flags & GLFW_ORIGIN_UL_BIT)) ||
(!swapy && (flags & GLFW_ORIGIN_UL_BIT)) )
{
src = pix;
dst = &pix[ (h.height-1)*h.width*bpp ];
for( n = 0; n < h.height/2; n ++ )
{
for( m = 0; m < h.width ; m ++ )
{
for( k = 0; k < bpp; k ++ )
{
tmp = *src;
*src ++ = *dst;
*dst ++ = tmp;
}
}
dst -= 2*h.width*bpp;
}
}
if( swapx )
{
src = pix;
dst = &pix[ (h.width-1)*bpp ];
for( n = 0; n < h.height; n ++ )
{
for( m = 0; m < h.width/2 ; m ++ )
{
for( k = 0; k < bpp; k ++ )
{
tmp = *src;
*src ++ = *dst;
*dst ++ = tmp;
}
dst -= 2*bpp;
}
src += ((h.width+1)/2)*bpp;
dst += ((3*h.width+1)/2)*bpp;
}
}
// Convert BGR/BGRA to RGB/RGBA, and optionally colormap indeces to
// RGB/RGBA values
if( cmap )
{
// Convert colormap pixel format (BGR -> RGB or BGRA -> RGBA)
if( bpp2 == 3 || bpp2 == 4 )
{
for( n = 0; n < h.cmaplen; n ++ )
{
tmp = cmap[ n*bpp2 ];
cmap[ n*bpp2 ] = cmap[ n*bpp2 + 2 ];
cmap[ n*bpp2 + 2 ] = tmp;
}
}
// Convert pixel data to RGB/RGBA data
for( m = h.width * h.height - 1; m >= 0; m -- )
{
n = pix[ m ];
for( k = 0; k < bpp2; k ++ )
{
pix[ m*bpp2 + k ] = cmap[ n*bpp2 + k ];
}
}
// Free memory for colormap (it's not needed anymore)
free( cmap );
}
else
{
// Convert image pixel format (BGR -> RGB or BGRA -> RGBA)
if( bpp2 == 3 || bpp2 == 4 )
{
src = pix;
dst = &pix[ 2 ];
for( n = 0; n < h.height * h.width; n ++ )
{
tmp = *src;
*src = *dst;
*dst = tmp;
src += bpp2;
dst += bpp2;
}
}
}
// Fill out GLFWimage struct (the Format field will be set by
// glfwReadImage)
img->Width = h.width;
img->Height = h.height;
img->BytesPerPixel = bpp2;
img->Data = pix;
return 1;
}

340
libs/glfw/lib/thread.c Normal file
View File

@ -0,0 +1,340 @@
//========================================================================
// GLFW - An OpenGL framework
// File: thread.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwGetThreadPointer() - Find pointer to thread with a matching ID
//========================================================================
_GLFWthread * _glfwGetThreadPointer( int ID )
{
_GLFWthread *t;
for( t = &_glfwThrd.First; t != NULL; t = t->Next )
{
if( t->ID == ID )
{
break;
}
}
return t;
}
//========================================================================
// _glfwAppendThread() - Append thread to thread list
//========================================================================
void _glfwAppendThread( _GLFWthread * t )
{
_GLFWthread *t_tmp;
t_tmp = &_glfwThrd.First;
while( t_tmp->Next != NULL )
{
t_tmp = t_tmp->Next;
}
t_tmp->Next = t;
t->Previous = t_tmp;
t->Next = NULL;
}
//========================================================================
// _glfwRemoveThread() - Remove thread from thread list
//========================================================================
void _glfwRemoveThread( _GLFWthread * t )
{
if( t->Previous != NULL )
{
t->Previous->Next = t->Next;
}
if( t->Next != NULL )
{
t->Next->Previous = t->Previous;
}
free( (void *) t );
}
//************************************************************************
//**** GLFW user functions ****
//************************************************************************
//========================================================================
// glfwCreateThread() - Create a new thread
//========================================================================
GLFWAPI GLFWthread GLFWAPIENTRY glfwCreateThread( GLFWthreadfun fun,
void *arg )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return -1;
}
// Return the GLFW thread ID
return _glfwPlatformCreateThread( fun, arg );
}
//========================================================================
// glfwDestroyThread() - Kill a thread. NOTE: THIS IS A VERY DANGEROUS
// OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME SITUATIONS!
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwDestroyThread( GLFWthread ID )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return;
}
// Is it a valid thread? (killing the main thread is not allowed)
if( ID < 1 )
{
return;
}
_glfwPlatformDestroyThread( ID );
}
//========================================================================
// glfwWaitThread() - Wait for a thread to die
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwWaitThread( GLFWthread ID, int waitmode )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return GL_TRUE;
}
// Is it a valid thread? (waiting for the main thread is not allowed)
if( ID < 1 )
{
return GL_TRUE;
}
return _glfwPlatformWaitThread( ID, waitmode );
}
//========================================================================
// glfwGetThreadID() - Return the thread ID for the current thread
//========================================================================
GLFWAPI GLFWthread GLFWAPIENTRY glfwGetThreadID( void )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return 0;
}
return _glfwPlatformGetThreadID();
}
//========================================================================
// glfwCreateMutex() - Create a mutual exclusion object
//========================================================================
GLFWAPI GLFWmutex GLFWAPIENTRY glfwCreateMutex( void )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return (GLFWmutex) 0;
}
return _glfwPlatformCreateMutex();
}
//========================================================================
// glfwDestroyMutex() - Destroy a mutual exclusion object
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwDestroyMutex( GLFWmutex mutex )
{
// Initialized & valid mutex (no real way of assuring this)?
if( !_glfwInitialized || !mutex )
{
return;
}
_glfwPlatformDestroyMutex( mutex );
}
//========================================================================
// glfwLockMutex() - Request access to a mutex
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwLockMutex( GLFWmutex mutex )
{
// Initialized & valid mutex (no real way of assuring this)?
if( !_glfwInitialized && !mutex )
{
return;
}
_glfwPlatformLockMutex( mutex );
}
//========================================================================
// glfwUnlockMutex() - Release a mutex
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwUnlockMutex( GLFWmutex mutex )
{
// Initialized & valid mutex (no real way of assuring this)?
if( !_glfwInitialized && !mutex )
{
return;
}
_glfwPlatformUnlockMutex( mutex );
}
//========================================================================
// glfwCreateCond() - Create a new condition variable object
//========================================================================
GLFWAPI GLFWcond GLFWAPIENTRY glfwCreateCond( void )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return (GLFWcond) 0;
}
return _glfwPlatformCreateCond();
}
//========================================================================
// glfwDestroyCond() - Destroy a condition variable object
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwDestroyCond( GLFWcond cond )
{
// Initialized & valid condition variable?
if( !_glfwInitialized || !cond )
{
return;
}
_glfwPlatformDestroyCond( cond );
}
//========================================================================
// glfwWaitCond() - Wait for a condition to be raised
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwWaitCond( GLFWcond cond, GLFWmutex mutex,
double timeout )
{
// Initialized & valid condition variable and mutex?
if( !_glfwInitialized || !cond || !mutex )
{
return;
}
_glfwPlatformWaitCond( cond, mutex, timeout );
}
//========================================================================
// glfwSignalCond() - Signal a condition to one waiting thread
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSignalCond( GLFWcond cond )
{
// Initialized & valid condition variable?
if( !_glfwInitialized || !cond )
{
return;
}
_glfwPlatformSignalCond( cond );
}
//========================================================================
// glfwBroadcastCond() - Broadcast a condition to all waiting threads
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwBroadcastCond( GLFWcond cond )
{
// Initialized & valid condition variable?
if( !_glfwInitialized || !cond )
{
return;
}
_glfwPlatformBroadcastCond( cond );
}
//========================================================================
// glfwGetNumberOfProcessors() - Return the number of processors in the
// system. This information can be useful for determining the optimal
// number of threads to use for performing a certain task.
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwGetNumberOfProcessors( void )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return 0;
}
return _glfwPlatformGetNumberOfProcessors();
}

83
libs/glfw/lib/time.c Normal file
View File

@ -0,0 +1,83 @@
//========================================================================
// GLFW - An OpenGL framework
// File: time.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW user functions ****
//************************************************************************
//========================================================================
// glfwGetTime() - Return timer value in seconds
//========================================================================
GLFWAPI double GLFWAPIENTRY glfwGetTime( void )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return 0.0;
}
return _glfwPlatformGetTime();
}
//========================================================================
// glfwSetTime() - Set timer value in seconds
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetTime( double time )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return;
}
_glfwPlatformSetTime( time );
}
//========================================================================
// glfwSleep() - Put a thread to sleep for a specified amount of time
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSleep( double time )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return;
}
_glfwPlatformSleep( time );
}

View File

@ -0,0 +1,474 @@
//========================================================================
// GLFW - An OpenGL framework
// File: platform.h
// Platform: Windows
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef _platform_h_
#define _platform_h_
// This is the Windows version of GLFW
#define _GLFW_WIN32
// Include files
#include <windows.h>
#include <mmsystem.h>
#include "../../include/GL/glfw.h"
//========================================================================
// Hack: Define things that some <windows.h>'s do not define
//========================================================================
// Some old versions of w32api (used by MinGW and Cygwin) define
// WH_KEYBOARD_LL without typedef:ing KBDLLHOOKSTRUCT (!)
#if defined(__MINGW32__) || defined(__CYGWIN__)
#include <w32api.h>
#if defined(WH_KEYBOARD_LL) && (__W32API_MAJOR_VERSION == 1) && (__W32API_MINOR_VERSION <= 2)
#undef WH_KEYBOARD_LL
#endif
#endif
//------------------------------------------------------------------------
// ** NOTE ** If this gives you compiler errors and you are using MinGW
// (or Dev-C++), update to w32api version 1.3 or later:
// http://sourceforge.net/project/showfiles.php?group_id=2435
//------------------------------------------------------------------------
#ifndef WH_KEYBOARD_LL
#define WH_KEYBOARD_LL 13
typedef struct tagKBDLLHOOKSTRUCT {
DWORD vkCode;
DWORD scanCode;
DWORD flags;
DWORD time;
DWORD dwExtraInfo;
} KBDLLHOOKSTRUCT, FAR *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
#endif // WH_KEYBOARD_LL
#ifndef LLKHF_ALTDOWN
#define LLKHF_ALTDOWN 0x00000020
#endif
#ifndef SPI_SETSCREENSAVERRUNNING
#define SPI_SETSCREENSAVERRUNNING 97
#endif
#ifndef SPI_GETANIMATION
#define SPI_GETANIMATION 72
#endif
#ifndef SPI_SETANIMATION
#define SPI_SETANIMATION 73
#endif
#ifndef SPI_GETFOREGROUNDLOCKTIMEOUT
#define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000
#endif
#ifndef SPI_SETFOREGROUNDLOCKTIMEOUT
#define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001
#endif
#ifndef CDS_FULLSCREEN
#define CDS_FULLSCREEN 4
#endif
#ifndef PFD_GENERIC_ACCELERATED
#define PFD_GENERIC_ACCELERATED 0x00001000
#endif
#ifndef PFD_DEPTH_DONTCARE
#define PFD_DEPTH_DONTCARE 0x20000000
#endif
#ifndef ENUM_CURRENT_SETTINGS
#define ENUM_CURRENT_SETTINGS -1
#endif
#ifndef ENUM_REGISTRY_SETTINGS
#define ENUM_REGISTRY_SETTINGS -2
#endif
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A
#endif
#ifndef WHEEL_DELTA
#define WHEEL_DELTA 120
#endif
#ifndef WM_XBUTTONDOWN
#define WM_XBUTTONDOWN 0x020B
#endif
#ifndef WM_XBUTTONUP
#define WM_XBUTTONUP 0x020C
#endif
#ifndef XBUTTON1
#define XBUTTON1 1
#endif
#ifndef XBUTTON2
#define XBUTTON2 2
#endif
// wglSwapIntervalEXT typedef (Win32 buffer-swap interval control)
typedef int (APIENTRY * WGLSWAPINTERVALEXT_T) (int);
// wglChoosePixelFormatARB typedef
typedef BOOL (WINAPI * WGLCHOOSEPIXELFORMATARB_T) (HDC, const int *, const FLOAT *, UINT, int *, UINT *);
// wglGetPixelFormatAttribivARB typedef
typedef BOOL (WINAPI * WGLGETPIXELFORMATATTRIBIVARB_T) (HDC, int, int, UINT, const int *, int *);
// wglGetExtensionStringEXT typedef
typedef const char *(APIENTRY * WGLGETEXTENSIONSSTRINGEXT_T)( void );
// wglGetExtensionStringARB typedef
typedef const char *(APIENTRY * WGLGETEXTENSIONSSTRINGARB_T)( HDC );
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_RED_BITS_ARB 0x2015
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_ACCUM_BITS_ARB 0x201D
#define WGL_ACCUM_RED_BITS_ARB 0x201E
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
#define WGL_SAMPLES_ARB 0x2042
//========================================================================
// DLLs that are loaded at glfwInit()
//========================================================================
// gdi32.dll function pointer typedefs
#ifndef _GLFW_NO_DLOAD_GDI32
typedef int (WINAPI * CHOOSEPIXELFORMAT_T) (HDC,CONST PIXELFORMATDESCRIPTOR*);
typedef int (WINAPI * DESCRIBEPIXELFORMAT_T) (HDC,int,UINT,LPPIXELFORMATDESCRIPTOR);
typedef int (WINAPI * GETPIXELFORMAT_T) (HDC);
typedef BOOL (WINAPI * SETPIXELFORMAT_T) (HDC,int,const PIXELFORMATDESCRIPTOR*);
typedef BOOL (WINAPI * SWAPBUFFERS_T) (HDC);
#endif // _GLFW_NO_DLOAD_GDI32
// winmm.dll function pointer typedefs
#ifndef _GLFW_NO_DLOAD_WINMM
typedef MMRESULT (WINAPI * JOYGETDEVCAPSA_T) (UINT,LPJOYCAPSA,UINT);
typedef MMRESULT (WINAPI * JOYGETPOS_T) (UINT,LPJOYINFO);
typedef MMRESULT (WINAPI * JOYGETPOSEX_T) (UINT,LPJOYINFOEX);
typedef DWORD (WINAPI * TIMEGETTIME_T) (void);
#endif // _GLFW_NO_DLOAD_WINMM
// gdi32.dll shortcuts
#ifndef _GLFW_NO_DLOAD_GDI32
#define _glfw_ChoosePixelFormat _glfwLibrary.Libs.ChoosePixelFormat
#define _glfw_DescribePixelFormat _glfwLibrary.Libs.DescribePixelFormat
#define _glfw_GetPixelFormat _glfwLibrary.Libs.GetPixelFormat
#define _glfw_SetPixelFormat _glfwLibrary.Libs.SetPixelFormat
#define _glfw_SwapBuffers _glfwLibrary.Libs.SwapBuffers
#else
#define _glfw_ChoosePixelFormat ChoosePixelFormat
#define _glfw_DescribePixelFormat DescribePixelFormat
#define _glfw_GetPixelFormat GetPixelFormat
#define _glfw_SetPixelFormat SetPixelFormat
#define _glfw_SwapBuffers SwapBuffers
#endif // _GLFW_NO_DLOAD_GDI32
// winmm.dll shortcuts
#ifndef _GLFW_NO_DLOAD_WINMM
#define _glfw_joyGetDevCaps _glfwLibrary.Libs.joyGetDevCapsA
#define _glfw_joyGetPos _glfwLibrary.Libs.joyGetPos
#define _glfw_joyGetPosEx _glfwLibrary.Libs.joyGetPosEx
#define _glfw_timeGetTime _glfwLibrary.Libs.timeGetTime
#else
#define _glfw_joyGetDevCaps joyGetDevCapsA
#define _glfw_joyGetPos joyGetPos
#define _glfw_joyGetPosEx joyGetPosEx
#define _glfw_timeGetTime timeGetTime
#endif // _GLFW_NO_DLOAD_WINMM
//========================================================================
// Global variables (GLFW internals)
//========================================================================
//------------------------------------------------------------------------
// Window structure
//------------------------------------------------------------------------
typedef struct _GLFWwin_struct _GLFWwin;
struct _GLFWwin_struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// User callback functions
GLFWwindowsizefun WindowSizeCallback;
GLFWwindowclosefun WindowCloseCallback;
GLFWwindowrefreshfun WindowRefreshCallback;
GLFWmousebuttonfun MouseButtonCallback;
GLFWmouseposfun MousePosCallback;
GLFWmousewheelfun MouseWheelCallback;
GLFWkeyfun KeyCallback;
GLFWcharfun CharCallback;
// User selected window settings
int Fullscreen; // Fullscreen flag
int MouseLock; // Mouse-lock flag
int AutoPollEvents; // Auto polling flag
int SysKeysDisabled; // System keys disabled flag
int WindowNoResize; // Resize- and maximize gadgets disabled flag
// Window status & parameters
int Opened; // Flag telling if window is opened or not
int Active; // Application active flag
int Iconified; // Window iconified flag
int Width, Height; // Window width and heigth
int Accelerated; // GL_TRUE if window is HW accelerated
int RedBits;
int GreenBits;
int BlueBits;
int AlphaBits;
int DepthBits;
int StencilBits;
int AccumRedBits;
int AccumGreenBits;
int AccumBlueBits;
int AccumAlphaBits;
int AuxBuffers;
int Stereo;
int RefreshRate; // Vertical monitor refresh rate
int Samples;
// Extensions & OpenGL version
int Has_GL_SGIS_generate_mipmap;
int Has_GL_ARB_texture_non_power_of_two;
int GLVerMajor,GLVerMinor;
// ========= PLATFORM SPECIFIC PART ======================================
// Platform specific window resources
HDC DC; // Private GDI device context
HGLRC RC; // Permanent rendering context
HWND Wnd; // Window handle
ATOM ClassAtom; // Window class atom
int ModeID; // Mode ID for fullscreen mode
HHOOK KeyboardHook; // Keyboard hook handle
DWORD dwStyle; // Window styles used for window creation
DWORD dwExStyle; // --"--
// Platform specific extensions (context specific)
WGLSWAPINTERVALEXT_T SwapInterval;
WGLCHOOSEPIXELFORMATARB_T ChoosePixelFormat;
WGLGETPIXELFORMATATTRIBIVARB_T GetPixelFormatAttribiv;
WGLGETEXTENSIONSSTRINGEXT_T GetExtensionsStringEXT;
WGLGETEXTENSIONSSTRINGARB_T GetExtensionsStringARB;
// Various platform specific internal variables
int OldMouseLock; // Old mouse-lock flag (used for remembering
// mouse-lock state when iconifying)
int OldMouseLockValid;
int DesiredRefreshRate; // Desired vertical monitor refresh rate
};
GLFWGLOBAL _GLFWwin _glfwWin;
//------------------------------------------------------------------------
// User input status (most of this should go in _GLFWwin)
//------------------------------------------------------------------------
GLFWGLOBAL struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Mouse status
int MousePosX, MousePosY;
int WheelPos;
char MouseButton[ GLFW_MOUSE_BUTTON_LAST+1 ];
// Keyboard status
char Key[ GLFW_KEY_LAST+1 ];
int LastChar;
// User selected settings
int StickyKeys;
int StickyMouseButtons;
int KeyRepeat;
// ========= PLATFORM SPECIFIC PART ======================================
// Platform specific internal variables
int MouseMoved, OldMouseX, OldMouseY;
} _glfwInput;
//------------------------------------------------------------------------
// Library global data
//------------------------------------------------------------------------
GLFWGLOBAL struct {
// ========= PLATFORM SPECIFIC PART ======================================
HINSTANCE Instance; // Instance of the application
// Timer data
struct {
int HasPerformanceCounter;
double Resolution;
unsigned int t0_32;
__int64 t0_64;
} Timer;
// System information
struct {
int WinVer;
int HasUnicode;
DWORD ForegroundLockTimeout;
} Sys;
#if !defined(_GLFW_NO_DLOAD_WINMM) || !defined(_GLFW_NO_DLOAD_GDI32)
// Library handles and function pointers
struct {
#ifndef _GLFW_NO_DLOAD_GDI32
// gdi32.dll
HINSTANCE gdi32;
CHOOSEPIXELFORMAT_T ChoosePixelFormat;
DESCRIBEPIXELFORMAT_T DescribePixelFormat;
GETPIXELFORMAT_T GetPixelFormat;
SETPIXELFORMAT_T SetPixelFormat;
SWAPBUFFERS_T SwapBuffers;
#endif // _GLFW_NO_DLOAD_GDI32
// winmm.dll
#ifndef _GLFW_NO_DLOAD_WINMM
HINSTANCE winmm;
JOYGETDEVCAPSA_T joyGetDevCapsA;
JOYGETPOS_T joyGetPos;
JOYGETPOSEX_T joyGetPosEx;
TIMEGETTIME_T timeGetTime;
#endif // _GLFW_NO_DLOAD_WINMM
} Libs;
#endif
} _glfwLibrary;
//------------------------------------------------------------------------
// Thread record (one for each thread)
//------------------------------------------------------------------------
typedef struct _GLFWthread_struct _GLFWthread;
struct _GLFWthread_struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Pointer to previous and next threads in linked list
_GLFWthread *Previous, *Next;
// GLFW user side thread information
GLFWthread ID;
GLFWthreadfun Function;
// ========= PLATFORM SPECIFIC PART ======================================
// System side thread information
HANDLE Handle;
DWORD WinID;
};
//------------------------------------------------------------------------
// General thread information
//------------------------------------------------------------------------
GLFWGLOBAL struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Next thread ID to use (increments for every created thread)
GLFWthread NextID;
// First thread in linked list (always the main thread)
_GLFWthread First;
// ========= PLATFORM SPECIFIC PART ======================================
// Critical section lock
CRITICAL_SECTION CriticalSection;
} _glfwThrd;
//========================================================================
// Macros for encapsulating critical code sections (i.e. making parts
// of GLFW thread safe)
//========================================================================
// Thread list management
#define ENTER_THREAD_CRITICAL_SECTION \
EnterCriticalSection( &_glfwThrd.CriticalSection );
#define LEAVE_THREAD_CRITICAL_SECTION \
LeaveCriticalSection( &_glfwThrd.CriticalSection );
//========================================================================
// Various Windows version constants
//========================================================================
#define _GLFW_WIN_UNKNOWN 0x0000 // Earlier than 95 or NT4
#define _GLFW_WIN_95 0x0001
#define _GLFW_WIN_98 0x0002
#define _GLFW_WIN_ME 0x0003
#define _GLFW_WIN_UNKNOWN_9x 0x0004 // Later than ME
#define _GLFW_WIN_NT4 0x0101
#define _GLFW_WIN_2K 0x0102
#define _GLFW_WIN_XP 0x0103
#define _GLFW_WIN_NET_SERVER 0x0104
#define _GLFW_WIN_UNKNOWN_NT 0x0105 // Later than .NET Server
//========================================================================
// Prototypes for platform specific internal functions
//========================================================================
// Time
void _glfwInitTimer( void );
// Fullscreen support
int _glfwGetClosestVideoModeBPP( int *w, int *h, int *bpp, int *refresh );
int _glfwGetClosestVideoMode( int *w, int *h, int *r, int *g, int *b, int *refresh );
void _glfwSetVideoModeMODE( int mode );
void _glfwSetVideoMode( int *w, int *h, int r, int g, int b, int refresh );
#endif // _platform_h_

View File

@ -0,0 +1,60 @@
//========================================================================
// GLFW - An OpenGL framework
// File: win32_dllmain.c
// Platform: Windows
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(GLFW_BUILD_DLL)
//========================================================================
// DllMain()
//========================================================================
int WINAPI DllMain( HINSTANCE hinst, unsigned long reason, void *x )
{
// NOTE: Some compilers complains about hinst and x never being used -
// never mind that (we don't want to use them)!
switch( reason )
{
case DLL_PROCESS_ATTACH:
// Initializations
//glfwInit(); // We don't want to do that now!
break;
case DLL_PROCESS_DETACH:
// Do some cleanup
glfwTerminate();
break;
};
return 1;
}
#endif // GLFW_BUILD_DLL

View File

@ -0,0 +1,155 @@
//========================================================================
// GLFW - An OpenGL framework
// File: win32_enable.c
// Platform: Windows
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwLLKeyboardProc() - Low level keyboard callback function (used to
// disable system keys under Windows NT).
//========================================================================
LRESULT CALLBACK _glfwLLKeyboardProc( int nCode, WPARAM wParam,
LPARAM lParam )
{
BOOL syskeys = 0;
PKBDLLHOOKSTRUCT p;
// We are only looking for keyboard events - interpret lParam as a
// pointer to a KBDLLHOOKSTRUCT
p = (PKBDLLHOOKSTRUCT) lParam;
// If nCode == HC_ACTION, then we have a keyboard event
if( nCode == HC_ACTION )
{
switch( wParam )
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
// Detect: ALT+TAB, ALT+ESC, ALT+F4, CTRL+ESC,
// LWIN, RWIN, APPS (mysterious menu key)
syskeys = ( p->vkCode == VK_TAB &&
p->flags & LLKHF_ALTDOWN ) ||
( p->vkCode == VK_ESCAPE &&
p->flags & LLKHF_ALTDOWN ) ||
( p->vkCode == VK_F4 &&
p->flags & LLKHF_ALTDOWN ) ||
( p->vkCode == VK_ESCAPE &&
(GetKeyState(VK_CONTROL) & 0x8000)) ||
p->vkCode == VK_LWIN ||
p->vkCode == VK_RWIN ||
p->vkCode == VK_APPS;
break;
default:
break;
}
}
// Was it a system key combination (e.g. ALT+TAB)?
if( syskeys )
{
// Pass the key event to our window message loop
if( _glfwWin.Opened )
{
PostMessage( _glfwWin.Wnd, (UINT) wParam, p->vkCode, 0 );
}
// We've taken care of it - don't let the system know about this
// key event
return 1;
}
else
{
// It's a harmless key press, let the system deal with it
return CallNextHookEx( _glfwWin.KeyboardHook, nCode, wParam,
lParam );
}
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformEnableSystemKeys() - Enable system keys
// _glfwPlatformDisableSystemKeys() - Disable system keys
//========================================================================
void _glfwPlatformEnableSystemKeys( void )
{
BOOL bOld;
// Use different methods depending on operating system version
if( _glfwLibrary.Sys.WinVer >= _GLFW_WIN_NT4 )
{
if( _glfwWin.KeyboardHook != NULL )
{
UnhookWindowsHookEx( _glfwWin.KeyboardHook );
_glfwWin.KeyboardHook = NULL;
}
}
else
{
(void) SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, FALSE,
&bOld, 0 );
}
}
void _glfwPlatformDisableSystemKeys( void )
{
BOOL bOld;
// Use different methods depending on operating system version
if( _glfwLibrary.Sys.WinVer >= _GLFW_WIN_NT4 )
{
// Under Windows NT, install a low level keyboard hook
_glfwWin.KeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL,
_glfwLLKeyboardProc,
_glfwLibrary.Instance,
0 );
}
else
{
// Under Windows 95/98/ME, fool Windows that a screensaver
// is running => prevents ALT+TAB, CTRL+ESC and CTRL+ALT+DEL
(void) SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, TRUE,
&bOld, 0 );
}
}

View File

@ -0,0 +1,317 @@
//========================================================================
// GLFW - An OpenGL framework
// File: win32_fullscreen.c
// Platform: Windows
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwBPP2RGB() - Convert BPP to RGB bits (based on "best guess")
//========================================================================
static void _glfwBPP2RGB( int bpp, int *r, int *g, int *b )
{
int delta;
// Special case: BPP = 32
if( bpp == 32 ) bpp = 24;
// Convert "bits per pixel" to red, green & blue sizes
*r = *g = *b = bpp / 3;
delta = bpp - (*r * 3);
if( delta >= 1 )
{
*g = *g + 1;
}
if( delta == 2 )
{
*r = *r + 1;
}
}
//========================================================================
// _glfwGetClosestVideoModeBPP()
//========================================================================
int _glfwGetClosestVideoModeBPP( int *w, int *h, int *bpp, int *refresh )
{
int mode, bestmode, match, bestmatch, rr, bestrr, success;
DEVMODE dm;
// Find best match
bestmatch = 0x7fffffff;
bestrr = 0x7fffffff;
mode = bestmode = 0;
do
{
dm.dmSize = sizeof( DEVMODE );
success = EnumDisplaySettings( NULL, mode, &dm );
if( success )
{
match = dm.dmBitsPerPel - *bpp;
if( match < 0 ) match = -match;
match = ( match << 25 ) |
( (dm.dmPelsWidth - *w) *
(dm.dmPelsWidth - *w) +
(dm.dmPelsHeight - *h) *
(dm.dmPelsHeight - *h) );
if( match < bestmatch )
{
bestmatch = match;
bestmode = mode;
bestrr = (dm.dmDisplayFrequency - *refresh) *
(dm.dmDisplayFrequency - *refresh);
}
else if( match == bestmatch && *refresh > 0 )
{
rr = (dm.dmDisplayFrequency - *refresh) *
(dm.dmDisplayFrequency - *refresh);
if( rr < bestrr )
{
bestmatch = match;
bestmode = mode;
bestrr = rr;
}
}
}
mode ++;
}
while( success );
// Get the parameters for the best matching display mode
dm.dmSize = sizeof( DEVMODE );
(void) EnumDisplaySettings( NULL, bestmode, &dm );
// Fill out actual width and height
*w = dm.dmPelsWidth;
*h = dm.dmPelsHeight;
// Return bits per pixel
*bpp = dm.dmBitsPerPel;
// Return vertical refresh rate
*refresh = dm.dmDisplayFrequency;
return bestmode;
}
//========================================================================
// _glfwGetClosestVideoMode()
//========================================================================
int _glfwGetClosestVideoMode( int *w, int *h, int *r, int *g, int *b,
int *refresh )
{
int bpp, bestmode;
// Colorbits = sum of red/green/blue bits
bpp = *r + *g + *b;
// If colorbits < 15 (e.g. 0) or >= 24, default to 32 bpp
if( bpp < 15 || bpp >= 24 )
{
bpp = 32;
}
// Find best match
bestmode = _glfwGetClosestVideoModeBPP( w, h, &bpp, refresh );
// Convert "bits per pixel" to red, green & blue sizes
_glfwBPP2RGB( bpp, r, g, b );
return bestmode;
}
//========================================================================
// Change the current video mode
//========================================================================
void _glfwSetVideoModeMODE( int mode )
{
DEVMODE dm;
int success;
// Get the parameters for the best matching display mode
dm.dmSize = sizeof( DEVMODE );
(void) EnumDisplaySettings( NULL, mode, &dm );
// Set which fields we want to specify
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
// Do we have a prefered refresh rate?
if( _glfwWin.DesiredRefreshRate > 0 )
{
dm.dmFields = dm.dmFields | DM_DISPLAYFREQUENCY;
dm.dmDisplayFrequency = _glfwWin.DesiredRefreshRate;
}
// Change display setting
dm.dmSize = sizeof( DEVMODE );
success = ChangeDisplaySettings( &dm, CDS_FULLSCREEN );
// If the mode change was not possible, query the current display
// settings (we'll use the desktop resolution for fullscreen mode)
if( success == DISP_CHANGE_SUCCESSFUL )
{
_glfwWin.ModeID = mode;
}
else
{
_glfwWin.ModeID = ENUM_REGISTRY_SETTINGS;
EnumDisplaySettings( NULL, ENUM_REGISTRY_SETTINGS, &dm );
}
// Set the window size to that of the display mode
_glfwWin.Width = dm.dmPelsWidth;
_glfwWin.Height = dm.dmPelsHeight;
}
//========================================================================
// _glfwSetVideoMode() - Change the current video mode
//========================================================================
void _glfwSetVideoMode( int *w, int *h, int r, int g, int b, int refresh )
{
int bestmode;
// Find a best match mode
bestmode = _glfwGetClosestVideoMode( w, h, &r, &g, &b, &refresh );
// Change mode
_glfwSetVideoModeMODE( bestmode );
}
//************************************************************************
//**** GLFW user functions ****
//************************************************************************
//========================================================================
// _glfwPlatformGetVideoModes() - Get a list of available video modes
//========================================================================
int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )
{
int count, success, mode, i, j;
int m1, m2, bpp, r, g, b;
DEVMODE dm;
// Loop through all video modes and extract all the UNIQUE modes
count = 0;
mode = 0;
do
{
// Get video mode properties
dm.dmSize = sizeof( DEVMODE );
success = EnumDisplaySettings( NULL, mode, &dm );
// Is it a valid mode? (only list depths >= 15 bpp)
if( success && dm.dmBitsPerPel >= 15 )
{
// Convert to RGB, and back to bpp ("mask out" alpha bits etc)
_glfwBPP2RGB( dm.dmBitsPerPel, &r, &g, &b );
bpp = r + g + b;
// Mode "code" for this mode
m1 = (bpp << 25) | (dm.dmPelsWidth * dm.dmPelsHeight);
// Insert mode in list (sorted), and avoid duplicates
for( i = 0; i < count; i ++ )
{
// Mode "code" for already listed mode
bpp = list[i].RedBits + list[i].GreenBits +
list[i].BlueBits;
m2 = (bpp << 25) | (list[i].Width * list[i].Height);
if( m1 <= m2 )
{
break;
}
}
// New entry at the end of the list?
if( i >= count )
{
list[count].Width = dm.dmPelsWidth;
list[count].Height = dm.dmPelsHeight;
list[count].RedBits = r;
list[count].GreenBits = g;
list[count].BlueBits = b;
count ++;
}
// Insert new entry in the list?
else if( m1 < m2 )
{
for( j = count; j > i; j -- )
{
list[j] = list[j-1];
}
list[i].Width = dm.dmPelsWidth;
list[i].Height = dm.dmPelsHeight;
list[i].RedBits = r;
list[i].GreenBits = g;
list[i].BlueBits = b;
count ++;
}
}
mode ++;
}
while( success && (count < maxcount) );
return count;
}
//========================================================================
// _glfwPlatformGetDesktopMode() - Get the desktop video mode
//========================================================================
void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )
{
DEVMODE dm;
// Get desktop display mode
dm.dmSize = sizeof( DEVMODE );
(void) EnumDisplaySettings( NULL, ENUM_REGISTRY_SETTINGS, &dm );
// Return desktop mode parameters
mode->Width = dm.dmPelsWidth;
mode->Height = dm.dmPelsHeight;
_glfwBPP2RGB( dm.dmBitsPerPel, &mode->RedBits, &mode->GreenBits,
&mode->BlueBits );
}

View File

@ -0,0 +1,85 @@
//========================================================================
// GLFW - An OpenGL framework
// File: win32_glext.c
// Platform: Windows
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// Check if an OpenGL extension is available at runtime (Windows version checks
// for WGL extensions)
//========================================================================
int _glfwPlatformExtensionSupported( const char *extension )
{
const GLubyte *extensions;
// Try wglGetExtensionsStringEXT
if( _glfwWin.GetExtensionsStringEXT != NULL )
{
extensions = (GLubyte *) _glfwWin.GetExtensionsStringEXT();
if( extensions != NULL )
{
if( _glfwStringInExtensionString( extension, extensions ) )
{
return GL_TRUE;
}
}
}
// Try wglGetExtensionsStringARB
if( _glfwWin.GetExtensionsStringARB != NULL )
{
extensions = (GLubyte *) _glfwWin.GetExtensionsStringARB( _glfwWin.DC );
if( extensions != NULL )
{
if( _glfwStringInExtensionString( extension, extensions ) )
{
return GL_TRUE;
}
}
}
return GL_FALSE;
}
//========================================================================
// Get the function pointer to an OpenGL function
//========================================================================
void * _glfwPlatformGetProcAddress( const char *procname )
{
return (void *) wglGetProcAddress( procname );
}

View File

@ -0,0 +1,356 @@
//========================================================================
// GLFW - An OpenGL framework
// File: win32_init.c
// Platform: Windows
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
// With the Borland C++ compiler, we want to disable FPU exceptions
#ifdef __BORLANDC__
#include <float.h>
#endif // __BORLANDC__
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwInitLibraries() - Load necessary libraries (DLLs)
//========================================================================
static int _glfwInitLibraries( void )
{
// gdi32.dll (OpenGL pixel format functions & SwapBuffers)
#ifndef _GLFW_NO_DLOAD_GDI32
_glfwLibrary.Libs.gdi32 = LoadLibrary( "gdi32.dll" );
if( _glfwLibrary.Libs.gdi32 != NULL )
{
_glfwLibrary.Libs.ChoosePixelFormat = (CHOOSEPIXELFORMAT_T)
GetProcAddress( _glfwLibrary.Libs.gdi32, "ChoosePixelFormat" );
_glfwLibrary.Libs.DescribePixelFormat = (DESCRIBEPIXELFORMAT_T)
GetProcAddress( _glfwLibrary.Libs.gdi32, "DescribePixelFormat" );
_glfwLibrary.Libs.GetPixelFormat = (GETPIXELFORMAT_T)
GetProcAddress( _glfwLibrary.Libs.gdi32, "GetPixelFormat" );
_glfwLibrary.Libs.SetPixelFormat = (SETPIXELFORMAT_T)
GetProcAddress( _glfwLibrary.Libs.gdi32, "SetPixelFormat" );
_glfwLibrary.Libs.SwapBuffers = (SWAPBUFFERS_T)
GetProcAddress( _glfwLibrary.Libs.gdi32, "SwapBuffers" );
if( _glfwLibrary.Libs.ChoosePixelFormat == NULL ||
_glfwLibrary.Libs.DescribePixelFormat == NULL ||
_glfwLibrary.Libs.GetPixelFormat == NULL ||
_glfwLibrary.Libs.SetPixelFormat == NULL ||
_glfwLibrary.Libs.SwapBuffers == NULL )
{
FreeLibrary( _glfwLibrary.Libs.gdi32 );
_glfwLibrary.Libs.gdi32 = NULL;
return GL_FALSE;
}
}
else
{
return GL_FALSE;
}
#endif // _GLFW_NO_DLOAD_GDI32
// winmm.dll (for joystick and timer support)
#ifndef _GLFW_NO_DLOAD_WINMM
_glfwLibrary.Libs.winmm = LoadLibrary( "winmm.dll" );
if( _glfwLibrary.Libs.winmm != NULL )
{
_glfwLibrary.Libs.joyGetDevCapsA = (JOYGETDEVCAPSA_T)
GetProcAddress( _glfwLibrary.Libs.winmm, "joyGetDevCapsA" );
_glfwLibrary.Libs.joyGetPos = (JOYGETPOS_T)
GetProcAddress( _glfwLibrary.Libs.winmm, "joyGetPos" );
_glfwLibrary.Libs.joyGetPosEx = (JOYGETPOSEX_T)
GetProcAddress( _glfwLibrary.Libs.winmm, "joyGetPosEx" );
_glfwLibrary.Libs.timeGetTime = (TIMEGETTIME_T)
GetProcAddress( _glfwLibrary.Libs.winmm, "timeGetTime" );
if( _glfwLibrary.Libs.joyGetDevCapsA == NULL ||
_glfwLibrary.Libs.joyGetPos == NULL ||
_glfwLibrary.Libs.joyGetPosEx == NULL ||
_glfwLibrary.Libs.timeGetTime == NULL )
{
FreeLibrary( _glfwLibrary.Libs.winmm );
_glfwLibrary.Libs.winmm = NULL;
return GL_FALSE;
}
}
else
{
return GL_FALSE;
}
#endif // _GLFW_NO_DLOAD_WINMM
return GL_TRUE;
}
//========================================================================
// _glfwFreeLibraries() - Unload used libraries (DLLs)
//========================================================================
static void _glfwFreeLibraries( void )
{
// gdi32.dll
#ifndef _GLFW_NO_DLOAD_GDI32
if( _glfwLibrary.Libs.gdi32 != NULL )
{
FreeLibrary( _glfwLibrary.Libs.gdi32 );
_glfwLibrary.Libs.gdi32 = NULL;
}
#endif // _GLFW_NO_DLOAD_GDI32
// winmm.dll
#ifndef _GLFW_NO_DLOAD_WINMM
if( _glfwLibrary.Libs.winmm != NULL )
{
FreeLibrary( _glfwLibrary.Libs.winmm );
_glfwLibrary.Libs.winmm = NULL;
}
#endif // _GLFW_NO_DLOAD_WINMM
}
//========================================================================
// _glfwInitThreads() - Initialize GLFW thread package
//========================================================================
static void _glfwInitThreads( void )
{
// Initialize critical section handle
InitializeCriticalSection( &_glfwThrd.CriticalSection );
// The first thread (the main thread) has ID 0
_glfwThrd.NextID = 0;
// Fill out information about the main thread (this thread)
_glfwThrd.First.ID = _glfwThrd.NextID ++;
_glfwThrd.First.Function = NULL;
_glfwThrd.First.Handle = GetCurrentThread();
_glfwThrd.First.WinID = GetCurrentThreadId();
_glfwThrd.First.Previous = NULL;
_glfwThrd.First.Next = NULL;
}
//========================================================================
// _glfwTerminateThreads() - Terminate GLFW thread package
//========================================================================
static void _glfwTerminateThreads( void )
{
_GLFWthread *t, *t_next;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Kill all threads (NOTE: THE USER SHOULD WAIT FOR ALL THREADS TO
// DIE, _BEFORE_ CALLING glfwTerminate()!!!)
t = _glfwThrd.First.Next;
while( t != NULL )
{
// Get pointer to next thread
t_next = t->Next;
// Simply murder the process, no mercy!
if( TerminateThread( t->Handle, 0 ) )
{
// Close thread handle
CloseHandle( t->Handle );
// Free memory allocated for this thread
free( (void *) t );
}
// Select next thread in list
t = t_next;
}
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Delete critical section handle
DeleteCriticalSection( &_glfwThrd.CriticalSection );
}
//========================================================================
// _glfwTerminate_atexit() - Terminate GLFW when exiting application
//========================================================================
void _glfwTerminate_atexit( void )
{
glfwTerminate();
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformInit() - Initialize various GLFW state
//========================================================================
int _glfwPlatformInit( void )
{
OSVERSIONINFO osi;
// To make SetForegroundWindow() work as we want, we need to fiddle
// with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
// as possible in the hope of still being the foreground process)
SystemParametersInfo( SPI_GETFOREGROUNDLOCKTIMEOUT, 0,
&_glfwLibrary.Sys.ForegroundLockTimeout, 0 );
SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0,
SPIF_SENDCHANGE );
// Check which OS version we are running
osi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
GetVersionEx( &osi );
_glfwLibrary.Sys.WinVer = _GLFW_WIN_UNKNOWN;
if( osi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
{
if( osi.dwMajorVersion == 4 && osi.dwMinorVersion < 10 )
{
_glfwLibrary.Sys.WinVer = _GLFW_WIN_95;
}
else if( osi.dwMajorVersion == 4 && osi.dwMinorVersion < 90 )
{
_glfwLibrary.Sys.WinVer = _GLFW_WIN_98;
}
else if( osi.dwMajorVersion == 4 && osi.dwMinorVersion == 90 )
{
_glfwLibrary.Sys.WinVer = _GLFW_WIN_ME;
}
else if( osi.dwMajorVersion >= 4 )
{
_glfwLibrary.Sys.WinVer = _GLFW_WIN_UNKNOWN_9x;
}
}
else if( osi.dwPlatformId == VER_PLATFORM_WIN32_NT )
{
if( osi.dwMajorVersion == 4 && osi.dwMinorVersion == 0 )
{
_glfwLibrary.Sys.WinVer = _GLFW_WIN_NT4;
}
else if( osi.dwMajorVersion == 5 && osi.dwMinorVersion == 0 )
{
_glfwLibrary.Sys.WinVer = _GLFW_WIN_2K;
}
else if( osi.dwMajorVersion == 5 && osi.dwMinorVersion == 1 )
{
_glfwLibrary.Sys.WinVer = _GLFW_WIN_XP;
}
else if( osi.dwMajorVersion == 5 && osi.dwMinorVersion == 2 )
{
_glfwLibrary.Sys.WinVer = _GLFW_WIN_NET_SERVER;
}
else if( osi.dwMajorVersion >= 5 )
{
_glfwLibrary.Sys.WinVer = _GLFW_WIN_UNKNOWN_NT;
}
}
// Do we have Unicode support?
if( _glfwLibrary.Sys.WinVer >= _GLFW_WIN_NT4 )
{
// Windows NT/2000/XP/.NET has Unicode support
_glfwLibrary.Sys.HasUnicode = GL_TRUE;
}
else
{
// Windows 9x/ME does not have Unicode support
_glfwLibrary.Sys.HasUnicode = GL_FALSE;
}
// Load libraries (DLLs)
if( !_glfwInitLibraries() )
{
return GL_FALSE;
}
// With the Borland C++ compiler, we want to disable FPU exceptions
// (this is recommended for OpenGL applications under Windows)
#ifdef __BORLANDC__
_control87( MCW_EM, MCW_EM );
#endif
// Retrieve GLFW instance handle
_glfwLibrary.Instance = GetModuleHandle( NULL );
// System keys are not disabled
_glfwWin.KeyboardHook = NULL;
// Initialise thread package
_glfwInitThreads();
// Install atexit() routine
atexit( _glfwTerminate_atexit );
// Start the timer
_glfwInitTimer();
return GL_TRUE;
}
//========================================================================
// _glfwPlatformTerminate() - Close window and kill all threads
//========================================================================
int _glfwPlatformTerminate( void )
{
// Only the main thread is allowed to do this...
if( GetCurrentThreadId() != _glfwThrd.First.WinID )
{
return GL_FALSE;
}
// Close OpenGL window
glfwCloseWindow();
// Kill thread package
_glfwTerminateThreads();
// Enable system keys again (if they were disabled)
glfwEnable( GLFW_SYSTEM_KEYS );
// Unload libraries (DLLs)
_glfwFreeLibraries();
// Restore FOREGROUNDLOCKTIMEOUT system setting
SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
(LPVOID)_glfwLibrary.Sys.ForegroundLockTimeout,
SPIF_SENDCHANGE );
return GL_TRUE;
}

View File

@ -0,0 +1,234 @@
//========================================================================
// GLFW - An OpenGL framework
// File: win32_joystick.c
// Platform: Windows
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwJoystickPresent() - Return GL_TRUE if joystick is present,
// else return GL_FALSE.
//========================================================================
static int _glfwJoystickPresent( int joy )
{
JOYINFO ji;
// Windows NT 4.0 MMSYSTEM only supports 2 sticks (other Windows
// versions support 16 sticks)
if( _glfwLibrary.Sys.WinVer == _GLFW_WIN_NT4 && joy > GLFW_JOYSTICK_2 )
{
return GL_FALSE;
}
// Is it a valid stick ID (Windows don't support more than 16 sticks)?
if( joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_16 )
{
return GL_FALSE;
}
// Is the joystick present?
if( _glfw_joyGetPos( joy - GLFW_JOYSTICK_1, &ji ) != JOYERR_NOERROR )
{
return GL_FALSE;
}
return GL_TRUE;
}
//========================================================================
// _glfwCalcJoystickPos() - Calculate joystick position
//========================================================================
static float _glfwCalcJoystickPos( DWORD pos, DWORD min, DWORD max )
{
float fpos = (float) pos;
float fmin = (float) min;
float fmax = (float) max;
return (2.0f*(fpos - fmin) / (fmax - fmin)) - 1.0f;
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformGetJoystickParam() - Determine joystick capabilities
//========================================================================
int _glfwPlatformGetJoystickParam( int joy, int param )
{
JOYCAPS jc;
// return 0;
// Is joystick present?
if( !_glfwJoystickPresent( joy ) )
{
return 0;
}
// We got this far, the joystick is present
if( param == GLFW_PRESENT )
{
return GL_TRUE;
}
// Get joystick capabilities
_glfw_joyGetDevCaps( joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS) );
switch( param )
{
case GLFW_AXES:
// Return number of joystick axes
return jc.wNumAxes;
case GLFW_BUTTONS:
// Return number of joystick axes
return jc.wNumButtons;
default:
break;
}
return 0;
}
//========================================================================
// _glfwPlatformGetJoystickPos() - Get joystick axis positions
//========================================================================
int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )
{
JOYCAPS jc;
JOYINFOEX ji;
int axis;
// return 0;
// Is joystick present?
if( !_glfwJoystickPresent( joy ) )
{
return 0;
}
// Get joystick capabilities
_glfw_joyGetDevCaps( joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS) );
// Get joystick state
ji.dwSize = sizeof( JOYINFOEX );
ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ |
JOY_RETURNR | JOY_RETURNU | JOY_RETURNV;
_glfw_joyGetPosEx( joy - GLFW_JOYSTICK_1, &ji );
// Get position values for all axes
axis = 0;
if( axis < numaxes )
{
pos[ axis++ ] = _glfwCalcJoystickPos( ji.dwXpos, jc.wXmin,
jc.wXmax );
}
if( axis < numaxes )
{
pos[ axis++ ] = -_glfwCalcJoystickPos( ji.dwYpos, jc.wYmin,
jc.wYmax );
}
if( axis < numaxes && jc.wCaps & JOYCAPS_HASZ )
{
pos[ axis++ ] = _glfwCalcJoystickPos( ji.dwZpos, jc.wZmin,
jc.wZmax );
}
if( axis < numaxes && jc.wCaps & JOYCAPS_HASR )
{
pos[ axis++ ] = _glfwCalcJoystickPos( ji.dwRpos, jc.wRmin,
jc.wRmax );
}
if( axis < numaxes && jc.wCaps & JOYCAPS_HASU )
{
pos[ axis++ ] = _glfwCalcJoystickPos( ji.dwUpos, jc.wUmin,
jc.wUmax );
}
if( axis < numaxes && jc.wCaps & JOYCAPS_HASV )
{
pos[ axis++ ] = -_glfwCalcJoystickPos( ji.dwVpos, jc.wVmin,
jc.wVmax );
}
// Return number of returned axes
return axis;
}
//========================================================================
// _glfwPlatformGetJoystickButtons() - Get joystick button states
//========================================================================
int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons,
int numbuttons )
{
JOYCAPS jc;
JOYINFOEX ji;
int button;
// return 0;
// Is joystick present?
if( !_glfwJoystickPresent( joy ) )
{
return 0;
}
// Get joystick capabilities
_glfw_joyGetDevCaps( joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS) );
// Get joystick state
ji.dwSize = sizeof( JOYINFOEX );
ji.dwFlags = JOY_RETURNBUTTONS;
_glfw_joyGetPosEx( joy - GLFW_JOYSTICK_1, &ji );
// Get states of all requested buttons
button = 0;
while( button < numbuttons && button < (int) jc.wNumButtons )
{
buttons[ button ] = (unsigned char)
(ji.dwButtons & (1UL << button) ? GLFW_PRESS : GLFW_RELEASE);
button ++;
}
return button;
}

View File

@ -0,0 +1,511 @@
//========================================================================
// GLFW - An OpenGL framework
// File: win32_thread.c
// Platform: Windows
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
// This is an implementation of POSIX "compatible" condition variables for
// Win32, as described by Douglas C. Schmidt and Irfan Pyarali:
// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
//************************************************************************
enum {
_GLFW_COND_SIGNAL = 0,
_GLFW_COND_BROADCAST = 1
};
typedef struct {
// Signal and broadcast event HANDLEs
HANDLE events[ 2 ];
// Count of the number of waiters
unsigned int waiters_count;
// Serialize access to <waiters_count>
CRITICAL_SECTION waiters_count_lock;
} _GLFWcond;
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwNewThread() - This is simply a "wrapper" for calling the user
// thread function.
//========================================================================
DWORD WINAPI _glfwNewThread( LPVOID lpParam )
{
GLFWthreadfun threadfun;
_GLFWthread *t;
// Get pointer to thread information for current thread
t = _glfwGetThreadPointer( _glfwPlatformGetThreadID() );
if( t == NULL )
{
return 0;
}
// Get user thread function pointer
threadfun = t->Function;
// Call the user thread function
threadfun( (void *) lpParam );
// Remove thread from thread list
ENTER_THREAD_CRITICAL_SECTION
_glfwRemoveThread( t );
LEAVE_THREAD_CRITICAL_SECTION
// When the thread function returns, the thread will die...
return 0;
}
//************************************************************************
//**** GLFW user functions ****
//************************************************************************
//========================================================================
// _glfwPlatformCreateThread() - Create a new thread
//========================================================================
GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )
{
GLFWthread ID;
_GLFWthread *t, *t_tmp;
HANDLE hThread;
DWORD dwThreadId;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Create a new thread information memory area
t = (_GLFWthread *) malloc( sizeof(_GLFWthread) );
if( t == NULL )
{
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
return -1;
}
// Get a new unique thread id
ID = _glfwThrd.NextID ++;
// Store thread information in the thread list
t->Function = fun;
t->ID = ID;
// Create thread
hThread = CreateThread(
NULL, // Default security attributes
0, // Default stack size (1 MB)
_glfwNewThread, // Thread function (a wrapper function)
(LPVOID)arg, // Argument to thread is the user argument
0, // Default creation flags
&dwThreadId // Returned thread identifier
);
// Did the thread creation fail?
if( hThread == NULL )
{
free( (void *) t );
LEAVE_THREAD_CRITICAL_SECTION
return -1;
}
// Store more thread information in the thread list
t->Handle = hThread;
t->WinID = dwThreadId;
// Append thread to thread list
t_tmp = &_glfwThrd.First;
while( t_tmp->Next != NULL )
{
t_tmp = t_tmp->Next;
}
t_tmp->Next = t;
t->Previous = t_tmp;
t->Next = NULL;
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Return the GLFW thread ID
return ID;
}
//========================================================================
// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY
// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME
// SITUATIONS!
//========================================================================
void _glfwPlatformDestroyThread( GLFWthread ID )
{
_GLFWthread *t;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Get thread information pointer
t = _glfwGetThreadPointer( ID );
if( t == NULL )
{
LEAVE_THREAD_CRITICAL_SECTION
return;
}
// Simply murder the process, no mercy!
if( TerminateThread( t->Handle, 0 ) )
{
// Close thread handle
CloseHandle( t->Handle );
// Remove thread from thread list
_glfwRemoveThread( t );
}
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
}
//========================================================================
// _glfwPlatformWaitThread() - Wait for a thread to die
//========================================================================
int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )
{
DWORD result;
HANDLE hThread;
_GLFWthread *t;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Get thread information pointer
t = _glfwGetThreadPointer( ID );
// Is the thread already dead?
if( t == NULL )
{
LEAVE_THREAD_CRITICAL_SECTION
return GL_TRUE;
}
// Get thread handle
hThread = t->Handle;
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Wait for thread to die
if( waitmode == GLFW_WAIT )
{
result = WaitForSingleObject( hThread, INFINITE );
}
else if( waitmode == GLFW_NOWAIT )
{
result = WaitForSingleObject( hThread, 0 );
}
else
{
return GL_FALSE;
}
// Did we have a time-out?
if( result == WAIT_TIMEOUT )
{
return GL_FALSE;
}
return GL_TRUE;
}
//========================================================================
// _glfwPlatformGetThreadID() - Return the thread ID for the current
// thread
//========================================================================
GLFWthread _glfwPlatformGetThreadID( void )
{
_GLFWthread *t;
GLFWthread ID = -1;
DWORD WinID;
// Get Windows thread ID
WinID = GetCurrentThreadId();
// Enter critical section (to avoid an inconsistent thread list)
ENTER_THREAD_CRITICAL_SECTION
// Loop through entire list of threads to find the matching Windows
// thread ID
for( t = &_glfwThrd.First; t != NULL; t = t->Next )
{
if( t->WinID == WinID )
{
ID = t->ID;
break;
}
}
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Return the found GLFW thread identifier
return ID;
}
//========================================================================
// _glfwPlatformCreateMutex() - Create a mutual exclusion object
//========================================================================
GLFWmutex _glfwPlatformCreateMutex( void )
{
CRITICAL_SECTION *mutex;
// Allocate memory for mutex
mutex = (CRITICAL_SECTION *) malloc( sizeof(CRITICAL_SECTION) );
if( !mutex )
{
return NULL;
}
// Initialize mutex
InitializeCriticalSection( mutex );
// Cast to GLFWmutex and return
return (GLFWmutex) mutex;
}
//========================================================================
// glfwDestroyMutex() - Destroy a mutual exclusion object
//========================================================================
void _glfwPlatformDestroyMutex( GLFWmutex mutex )
{
// Destroy mutex
DeleteCriticalSection( (CRITICAL_SECTION *) mutex );
free( mutex );
}
//========================================================================
// _glfwPlatformLockMutex() - Request access to a mutex
//========================================================================
void _glfwPlatformLockMutex( GLFWmutex mutex )
{
// Wait for mutex to be released
EnterCriticalSection( (CRITICAL_SECTION *) mutex );
}
//========================================================================
// _glfwPlatformUnlockMutex() - Release a mutex
//========================================================================
void _glfwPlatformUnlockMutex( GLFWmutex mutex )
{
// Release mutex
LeaveCriticalSection( (CRITICAL_SECTION *) mutex );
}
//========================================================================
// _glfwPlatformCreateCond() - Create a new condition variable object
//========================================================================
GLFWcond _glfwPlatformCreateCond( void )
{
_GLFWcond *cond;
// Allocate memory for condition variable
cond = (_GLFWcond *) malloc( sizeof(_GLFWcond) );
if( !cond )
{
return NULL;
}
// Initialize condition variable
cond->waiters_count = 0;
cond->events[ _GLFW_COND_SIGNAL ] = CreateEvent( NULL, FALSE,
FALSE, NULL );
cond->events[ _GLFW_COND_BROADCAST ] = CreateEvent( NULL, TRUE,
FALSE, NULL );
InitializeCriticalSection( &cond->waiters_count_lock );
// Cast to GLFWcond and return
return (GLFWcond) cond;
}
//========================================================================
// _glfwPlatformDestroyCond() - Destroy a condition variable object
//========================================================================
void _glfwPlatformDestroyCond( GLFWcond cond )
{
// Close the condition variable handles
CloseHandle( ((_GLFWcond *)cond)->events[ _GLFW_COND_SIGNAL ] );
CloseHandle( ((_GLFWcond *)cond)->events[ _GLFW_COND_BROADCAST ] );
// Delete critical section
DeleteCriticalSection( &((_GLFWcond *)cond)->waiters_count_lock );
// Free memory for condition variable
free( (void *) cond );
}
//========================================================================
// _glfwPlatformWaitCond() - Wait for a condition to be raised
//========================================================================
void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,
double timeout )
{
_GLFWcond *cv = (_GLFWcond *) cond;
int result, last_waiter;
DWORD timeout_ms;
// Avoid race conditions
EnterCriticalSection( &cv->waiters_count_lock );
cv->waiters_count ++;
LeaveCriticalSection( &cv->waiters_count_lock );
// It's ok to release the mutex here since Win32 manual-reset events
// maintain state when used with SetEvent()
LeaveCriticalSection( (CRITICAL_SECTION *) mutex );
// Translate timeout into milliseconds
if( timeout >= GLFW_INFINITY )
{
timeout_ms = INFINITE;
}
else
{
timeout_ms = (DWORD) (1000.0 * timeout + 0.5);
if( timeout_ms <= 0 )
{
timeout_ms = 1;
}
}
// Wait for either event to become signaled due to glfwSignalCond or
// glfwBroadcastCond being called
result = WaitForMultipleObjects( 2, cv->events, FALSE, timeout_ms );
// Check if we are the last waiter
EnterCriticalSection( &cv->waiters_count_lock );
cv->waiters_count --;
last_waiter = (result == WAIT_OBJECT_0 + _GLFW_COND_BROADCAST) &&
(cv->waiters_count == 0);
LeaveCriticalSection( &cv->waiters_count_lock );
// Some thread called glfwBroadcastCond
if( last_waiter )
{
// We're the last waiter to be notified or to stop waiting, so
// reset the manual event
ResetEvent( cv->events[ _GLFW_COND_BROADCAST ] );
}
// Reacquire the mutex
EnterCriticalSection( (CRITICAL_SECTION *) mutex );
}
//========================================================================
// _glfwPlatformSignalCond() - Signal a condition to one waiting thread
//========================================================================
void _glfwPlatformSignalCond( GLFWcond cond )
{
_GLFWcond *cv = (_GLFWcond *) cond;
int have_waiters;
// Avoid race conditions
EnterCriticalSection( &cv->waiters_count_lock );
have_waiters = cv->waiters_count > 0;
LeaveCriticalSection( &cv->waiters_count_lock );
if( have_waiters )
{
SetEvent( cv->events[ _GLFW_COND_SIGNAL ] );
}
}
//========================================================================
// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting
// threads
//========================================================================
void _glfwPlatformBroadcastCond( GLFWcond cond )
{
_GLFWcond *cv = (_GLFWcond *) cond;
int have_waiters;
// Avoid race conditions
EnterCriticalSection( &cv->waiters_count_lock );
have_waiters = cv->waiters_count > 0;
LeaveCriticalSection( &cv->waiters_count_lock );
if( have_waiters )
{
SetEvent( cv->events[ _GLFW_COND_BROADCAST ] );
}
}
//========================================================================
// _glfwPlatformGetNumberOfProcessors() - Return the number of processors
// in the system.
//========================================================================
int _glfwPlatformGetNumberOfProcessors( void )
{
SYSTEM_INFO si;
// Get hardware system information
GetSystemInfo( &si );
return (int) si.dwNumberOfProcessors;
}

View File

@ -0,0 +1,146 @@
//========================================================================
// GLFW - An OpenGL framework
// File: win32_time.c
// Platform: Windows
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwInitTimer() - Initialise timer
//========================================================================
void _glfwInitTimer( void )
{
__int64 freq;
// Check if we have a performance counter
if( QueryPerformanceFrequency( (LARGE_INTEGER *)&freq ) )
{
// Performance counter is available => use it!
_glfwLibrary.Timer.HasPerformanceCounter = GL_TRUE;
// Counter resolution is 1 / counter frequency
_glfwLibrary.Timer.Resolution = 1.0 / (double)freq;
// Set start time for timer
QueryPerformanceCounter( (LARGE_INTEGER *)&_glfwLibrary.Timer.t0_64 );
}
else
{
// No performace counter available => use the tick counter
_glfwLibrary.Timer.HasPerformanceCounter = GL_FALSE;
// Counter resolution is 1 ms
_glfwLibrary.Timer.Resolution = 0.001;
// Set start time for timer
_glfwLibrary.Timer.t0_32 = _glfw_timeGetTime();
}
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// Return timer value in seconds
//========================================================================
double _glfwPlatformGetTime( void )
{
double t;
__int64 t_64;
if( _glfwLibrary.Timer.HasPerformanceCounter )
{
QueryPerformanceCounter( (LARGE_INTEGER *)&t_64 );
t = (double)(t_64 - _glfwLibrary.Timer.t0_64);
}
else
{
t = (double)(_glfw_timeGetTime() - _glfwLibrary.Timer.t0_32);
}
// Calculate the current time in seconds
return t * _glfwLibrary.Timer.Resolution;
}
//========================================================================
// Set timer value in seconds
//========================================================================
void _glfwPlatformSetTime( double t )
{
__int64 t_64;
if( _glfwLibrary.Timer.HasPerformanceCounter )
{
QueryPerformanceCounter( (LARGE_INTEGER *)&t_64 );
_glfwLibrary.Timer.t0_64 = t_64 - (__int64)(t/_glfwLibrary.Timer.Resolution);
}
else
{
_glfwLibrary.Timer.t0_32 = _glfw_timeGetTime() - (int)(t*1000.0);
}
}
//========================================================================
// Put a thread to sleep for a specified amount of time
//========================================================================
void _glfwPlatformSleep( double time )
{
DWORD t;
if( time == 0.0 )
{
t = 0;
}
else if( time < 0.001 )
{
t = 1;
}
else if( time > 2147483647.0 )
{
t = 2147483647;
}
else
{
t = (DWORD)(time*1000.0 + 0.5);
}
Sleep( t );
}

File diff suppressed because it is too large Load Diff

727
libs/glfw/lib/window.c Normal file
View File

@ -0,0 +1,727 @@
//========================================================================
// GLFW - An OpenGL framework
// File: window.c
// Platform: Any
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// Clear all open window hints
//========================================================================
void _glfwClearWindowHints( void )
{
_glfwWinHints.RefreshRate = 0;
_glfwWinHints.AccumRedBits = 0;
_glfwWinHints.AccumGreenBits = 0;
_glfwWinHints.AccumBlueBits = 0;
_glfwWinHints.AccumAlphaBits = 0;
_glfwWinHints.AuxBuffers = 0;
_glfwWinHints.Stereo = 0;
_glfwWinHints.WindowNoResize = 0;
_glfwWinHints.Samples = 0;
}
//========================================================================
// Handle the input tracking part of window deactivation
//========================================================================
void _glfwInputDeactivation( void )
{
int i;
// Release all keyboard keys
for( i = 0; i <= GLFW_KEY_LAST; i ++ )
{
if( _glfwInput.Key[ i ] == GLFW_PRESS )
{
_glfwInputKey( i, GLFW_RELEASE );
}
}
// Release all mouse buttons
for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i ++ )
{
if( _glfwInput.MouseButton[ i ] == GLFW_PRESS )
{
_glfwInputMouseClick( i, GLFW_RELEASE );
}
}
}
//========================================================================
// _glfwClearInput() - Clear all input state
//========================================================================
void _glfwClearInput( void )
{
int i;
// Release all keyboard keys
for( i = 0; i <= GLFW_KEY_LAST; i ++ )
{
_glfwInput.Key[ i ] = GLFW_RELEASE;
}
// Clear last character
_glfwInput.LastChar = 0;
// Release all mouse buttons
for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i ++ )
{
_glfwInput.MouseButton[ i ] = GLFW_RELEASE;
}
// Set mouse position to (0,0)
_glfwInput.MousePosX = 0;
_glfwInput.MousePosY = 0;
// Set mouse wheel position to 0
_glfwInput.WheelPos = 0;
// The default is to use non sticky keys and mouse buttons
_glfwInput.StickyKeys = GL_FALSE;
_glfwInput.StickyMouseButtons = GL_FALSE;
// The default is to disable key repeat
_glfwInput.KeyRepeat = GL_FALSE;
}
//========================================================================
// _glfwInputKey() - Register keyboard activity
//========================================================================
void _glfwInputKey( int key, int action )
{
int keyrepeat = 0;
if( key < 0 || key > GLFW_KEY_LAST )
{
return;
}
// Are we trying to release an already released key?
if( action == GLFW_RELEASE && _glfwInput.Key[ key ] != GLFW_PRESS )
{
return;
}
// Register key action
if( action == GLFW_RELEASE && _glfwInput.StickyKeys )
{
_glfwInput.Key[ key ] = GLFW_STICK;
}
else
{
keyrepeat = (_glfwInput.Key[ key ] == GLFW_PRESS) &&
(action == GLFW_PRESS);
_glfwInput.Key[ key ] = (char) action;
}
// Call user callback function
if( _glfwWin.KeyCallback && (_glfwInput.KeyRepeat || !keyrepeat) )
{
_glfwWin.KeyCallback( key, action );
}
}
//========================================================================
// _glfwInputChar() - Register (keyboard) character activity
//========================================================================
void _glfwInputChar( int character, int action )
{
int keyrepeat = 0;
// Valid Unicode (ISO 10646) character?
if( !( (character >= 32 && character <= 126) || character >= 160 ) )
{
return;
}
// Is this a key repeat?
if( action == GLFW_PRESS && _glfwInput.LastChar == character )
{
keyrepeat = 1;
}
// Store this character as last character (or clear it, if released)
if( action == GLFW_PRESS )
{
_glfwInput.LastChar = character;
}
else
{
_glfwInput.LastChar = 0;
}
// Call user callback function
if( _glfwWin.CharCallback && (_glfwInput.KeyRepeat || !keyrepeat) )
{
_glfwWin.CharCallback( character, action );
}
}
//========================================================================
// _glfwInputMouseClick() - Register mouse button clicks
//========================================================================
void _glfwInputMouseClick( int button, int action )
{
if( button >= 0 && button <= GLFW_MOUSE_BUTTON_LAST )
{
// Register mouse button action
if( action == GLFW_RELEASE && _glfwInput.StickyMouseButtons )
{
_glfwInput.MouseButton[ button ] = GLFW_STICK;
}
else
{
_glfwInput.MouseButton[ button ] = (char) action;
}
// Call user callback function
if( _glfwWin.MouseButtonCallback )
{
_glfwWin.MouseButtonCallback( button, action );
}
}
}
//************************************************************************
//**** GLFW user functions ****
//************************************************************************
//========================================================================
// glfwOpenWindow() - Here is where the window is created, and the OpenGL
// rendering context is created
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwOpenWindow( int width, int height,
int redbits, int greenbits, int bluebits, int alphabits,
int depthbits, int stencilbits, int mode )
{
int x;
_GLFWhints hints;
// Is GLFW initialized?
if( !_glfwInitialized || _glfwWin.Opened )
{
return GL_FALSE;
}
// Copy and clear window hints
hints = _glfwWinHints;
_glfwClearWindowHints();
// Check input arguments
if( mode != GLFW_WINDOW && mode != GLFW_FULLSCREEN )
{
return GL_FALSE;
}
// Clear GLFW window state
_glfwWin.Active = GL_TRUE;
_glfwWin.Iconified = GL_FALSE;
_glfwWin.MouseLock = GL_FALSE;
_glfwWin.AutoPollEvents = GL_TRUE;
_glfwClearInput();
// Unregister all callback functions
_glfwWin.WindowSizeCallback = NULL;
_glfwWin.WindowCloseCallback = NULL;
_glfwWin.WindowRefreshCallback = NULL;
_glfwWin.KeyCallback = NULL;
_glfwWin.CharCallback = NULL;
_glfwWin.MousePosCallback = NULL;
_glfwWin.MouseButtonCallback = NULL;
_glfwWin.MouseWheelCallback = NULL;
// Check width & height
if( width > 0 && height <= 0 )
{
// Set the window aspect ratio to 4:3
height = (width * 3) / 4;
}
else if( width <= 0 && height > 0 )
{
// Set the window aspect ratio to 4:3
width = (height * 4) / 3;
}
else if( width <= 0 && height <= 0 )
{
// Default window size
width = 640;
height = 480;
}
// Remember window settings
_glfwWin.Width = width;
_glfwWin.Height = height;
_glfwWin.Fullscreen = (mode == GLFW_FULLSCREEN ? 1 : 0);
// Platform specific window opening routine
if( !_glfwPlatformOpenWindow( width, height, redbits, greenbits,
bluebits, alphabits, depthbits, stencilbits, mode, &hints ) )
{
return GL_FALSE;
}
// Flag that window is now opened
_glfwWin.Opened = GL_TRUE;
// Get window parameters (such as color buffer bits etc)
_glfwPlatformRefreshWindowParams();
// Get OpenGL version
glfwGetGLVersion( &_glfwWin.GLVerMajor, &_glfwWin.GLVerMinor, &x );
// Do we have non-power-of-two textures?
_glfwWin.Has_GL_ARB_texture_non_power_of_two =
glfwExtensionSupported( "GL_ARB_texture_non_power_of_two" );
// Do we have automatic mipmap generation?
_glfwWin.Has_GL_SGIS_generate_mipmap =
(_glfwWin.GLVerMajor >= 2) || (_glfwWin.GLVerMinor >= 4) ||
glfwExtensionSupported( "GL_SGIS_generate_mipmap" );
// If full-screen mode was requested, disable mouse cursor
if( mode == GLFW_FULLSCREEN )
{
glfwDisable( GLFW_MOUSE_CURSOR );
}
return GL_TRUE;
}
//========================================================================
// glfwOpenWindowHint() - Set hints for opening the window
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwOpenWindowHint( int target, int hint )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return;
}
switch( target )
{
case GLFW_REFRESH_RATE:
_glfwWinHints.RefreshRate = hint;
break;
case GLFW_ACCUM_RED_BITS:
_glfwWinHints.AccumRedBits = hint;
break;
case GLFW_ACCUM_GREEN_BITS:
_glfwWinHints.AccumGreenBits = hint;
break;
case GLFW_ACCUM_BLUE_BITS:
_glfwWinHints.AccumBlueBits = hint;
break;
case GLFW_ACCUM_ALPHA_BITS:
_glfwWinHints.AccumAlphaBits = hint;
break;
case GLFW_AUX_BUFFERS:
_glfwWinHints.AuxBuffers = hint;
break;
case GLFW_STEREO:
_glfwWinHints.Stereo = hint;
break;
case GLFW_WINDOW_NO_RESIZE:
_glfwWinHints.WindowNoResize = hint;
break;
case GLFW_FSAA_SAMPLES:
_glfwWinHints.Samples = hint;
break;
default:
break;
}
}
//========================================================================
// glfwCloseWindow() - Properly kill the window / video display
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwCloseWindow( void )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return;
}
// Show mouse pointer again (if hidden)
glfwEnable( GLFW_MOUSE_CURSOR );
// Close window
_glfwPlatformCloseWindow();
// Window is no longer opened
_glfwWin.Opened = GL_FALSE;
}
//========================================================================
// glfwSetWindowTitle() - Set the window title
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetWindowTitle( const char *title )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set window title
_glfwPlatformSetWindowTitle( title );
}
//========================================================================
// glfwGetWindowSize() - Get the window size
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwGetWindowSize( int *width, int *height )
{
if( width != NULL )
{
*width = _glfwWin.Width;
}
if( height != NULL )
{
*height = _glfwWin.Height;
}
}
//========================================================================
// glfwSetWindowSize() - Set the window size
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetWindowSize( int width, int height )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened || _glfwWin.Iconified )
{
return;
}
// Don't do anything if the window size did not change
if( width == _glfwWin.Width && height == _glfwWin.Height )
{
return;
}
// Change window size
_glfwPlatformSetWindowSize( width, height );
// Refresh window parameters (may have changed due to changed video
// modes)
_glfwPlatformRefreshWindowParams();
}
//========================================================================
// glfwSetWindowPos() - Set the window position
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetWindowPos( int x, int y )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened || _glfwWin.Fullscreen ||
_glfwWin.Iconified )
{
return;
}
// Set window position
_glfwPlatformSetWindowPos( x, y );
}
//========================================================================
// glfwIconfyWindow() - Window iconification
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwIconifyWindow( void )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened || _glfwWin.Iconified )
{
return;
}
// Iconify window
_glfwPlatformIconifyWindow();
}
//========================================================================
// glfwRestoreWindow() - Window un-iconification
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwRestoreWindow( void )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened || !_glfwWin.Iconified )
{
return;
}
// Restore iconified window
_glfwPlatformRestoreWindow();
// Refresh window parameters
_glfwPlatformRefreshWindowParams();
}
//========================================================================
// glfwSwapBuffers() - Swap buffers (double-buffering) and poll any new
// events
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSwapBuffers( void )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Check for window messages
if( _glfwWin.AutoPollEvents )
{
glfwPollEvents();
}
// Update display-buffer
if( _glfwWin.Opened )
{
_glfwPlatformSwapBuffers();
}
}
//========================================================================
// glfwSwapInterval() - Set double buffering swap interval (0 = vsync off)
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSwapInterval( int interval )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set double buffering swap interval
_glfwPlatformSwapInterval( interval );
}
//========================================================================
// glfwGetWindowParam() - Get window parameter
//========================================================================
GLFWAPI int GLFWAPIENTRY glfwGetWindowParam( int param )
{
// Is GLFW initialized?
if( !_glfwInitialized )
{
return 0;
}
// Is the window opened?
if( !_glfwWin.Opened )
{
if( param == GLFW_OPENED )
{
return GL_FALSE;
}
return 0;
}
// Window parameters
switch( param )
{
case GLFW_OPENED:
return GL_TRUE;
case GLFW_ACTIVE:
return _glfwWin.Active;
case GLFW_ICONIFIED:
return _glfwWin.Iconified;
case GLFW_ACCELERATED:
return _glfwWin.Accelerated;
case GLFW_RED_BITS:
return _glfwWin.RedBits;
case GLFW_GREEN_BITS:
return _glfwWin.GreenBits;
case GLFW_BLUE_BITS:
return _glfwWin.BlueBits;
case GLFW_ALPHA_BITS:
return _glfwWin.AlphaBits;
case GLFW_DEPTH_BITS:
return _glfwWin.DepthBits;
case GLFW_STENCIL_BITS:
return _glfwWin.StencilBits;
case GLFW_ACCUM_RED_BITS:
return _glfwWin.AccumRedBits;
case GLFW_ACCUM_GREEN_BITS:
return _glfwWin.AccumGreenBits;
case GLFW_ACCUM_BLUE_BITS:
return _glfwWin.AccumBlueBits;
case GLFW_ACCUM_ALPHA_BITS:
return _glfwWin.AccumAlphaBits;
case GLFW_AUX_BUFFERS:
return _glfwWin.AuxBuffers;
case GLFW_STEREO:
return _glfwWin.Stereo;
case GLFW_REFRESH_RATE:
return _glfwWin.RefreshRate;
case GLFW_WINDOW_NO_RESIZE:
return _glfwWin.WindowNoResize;
case GLFW_FSAA_SAMPLES:
return _glfwWin.Samples;
default:
return 0;
}
}
//========================================================================
// glfwSetWindowSizeCallback() - Set callback function for window size
// changes
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetWindowSizeCallback( GLFWwindowsizefun cbfun )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set callback function
_glfwWin.WindowSizeCallback = cbfun;
// Call the callback function to let the application know the current
// window size
if( cbfun )
{
cbfun( _glfwWin.Width, _glfwWin.Height );
}
}
//========================================================================
// glfwSetWindowCloseCallback() - Set callback function for window close
// events
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetWindowCloseCallback( GLFWwindowclosefun cbfun )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set callback function
_glfwWin.WindowCloseCallback = cbfun;
}
//========================================================================
// glfwSetWindowRefreshCallback() - Set callback function for window
// refresh events
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwSetWindowRefreshCallback( GLFWwindowrefreshfun cbfun )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Set callback function
_glfwWin.WindowRefreshCallback = cbfun;
}
//========================================================================
// glfwPollEvents() - Poll for new window and input events
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwPollEvents( void )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Poll for new events
_glfwPlatformPollEvents();
}
//========================================================================
// glfwWaitEvents() - Wait for new window and input events
//========================================================================
GLFWAPI void GLFWAPIENTRY glfwWaitEvents( void )
{
// Is GLFW initialized?
if( !_glfwInitialized || !_glfwWin.Opened )
{
return;
}
// Poll for new events
_glfwPlatformWaitEvents();
}

View File

@ -0,0 +1,11 @@
prefix=@PREFIX@
exec_prefix=@PREFIX@
libdir=@PREFIX@/lib
includedir=@PREFIX@/include
Name: GLFW
Description: A portable framework for OpenGL development
Version: 2.6.0
URL: http://glfw.sourceforge.net/
Libs: -L${libdir} -lglfw -lGL -lX11 -lXrandr -pthread -lm
Cflags: -I${includedir} -pthread

View File

@ -0,0 +1,415 @@
//========================================================================
// GLFW - An OpenGL framework
// File: platform.h
// Platform: X11 (Unix)
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef _platform_h_
#define _platform_h_
// This is the X11 version of GLFW
#define _GLFW_X11
// Include files
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <GL/glx.h>
#include "../../include/GL/glfw.h"
// Do we have pthread support?
#ifdef _GLFW_HAS_PTHREAD
#include <pthread.h>
#include <sched.h>
#endif
// With XFree86, we can use the XF86VidMode extension
#if defined( _GLFW_HAS_XF86VIDMODE )
#include <X11/extensions/xf86vmode.h>
#endif
#if defined( _GLFW_HAS_XRANDR )
#include <X11/extensions/Xrandr.h>
#endif
// Do we have support for dlopen/dlsym?
#if defined( _GLFW_HAS_DLOPEN )
#include <dlfcn.h>
#endif
// We support two different ways for getting the number of processors in
// the system: sysconf (POSIX) and sysctl (BSD?)
#if defined( _GLFW_HAS_SYSCONF )
// Use a single constant for querying number of online processors using
// the sysconf function (e.g. SGI defines _SC_NPROC_ONLN instead of
// _SC_NPROCESSORS_ONLN)
#ifndef _SC_NPROCESSORS_ONLN
#ifdef _SC_NPROC_ONLN
#define _SC_NPROCESSORS_ONLN _SC_NPROC_ONLN
#else
#error POSIX constant _SC_NPROCESSORS_ONLN not defined!
#endif
#endif
// Macro for querying the number of processors
#define _glfw_numprocessors(n) n=(int)sysconf(_SC_NPROCESSORS_ONLN)
#elif defined( _GLFW_HAS_SYSCTL )
#include <sys/types.h>
#include <sys/sysctl.h>
// Macro for querying the number of processors
#define _glfw_numprocessors(n) { \
int mib[2], ncpu; \
size_t len = 1; \
mib[0] = CTL_HW; \
mib[1] = HW_NCPU; \
n = 1; \
if( sysctl( mib, 2, &ncpu, &len, NULL, 0 ) != -1 ) \
{ \
if( len > 0 ) \
{ \
n = ncpu; \
} \
} \
}
#else
// If neither sysconf nor sysctl is supported, assume single processor
// system
#define _glfw_numprocessors(n) n=1
#endif
void (*glXGetProcAddress(const GLubyte *procName))();
void (*glXGetProcAddressARB(const GLubyte *procName))();
void (*glXGetProcAddressEXT(const GLubyte *procName))();
// We support four different ways for getting addresses for GL/GLX
// extension functions: glXGetProcAddress, glXGetProcAddressARB,
// glXGetProcAddressEXT, and dlsym
#if defined( _GLFW_HAS_GLXGETPROCADDRESSARB )
#define _glfw_glXGetProcAddress(x) glXGetProcAddressARB(x)
#elif defined( _GLFW_HAS_GLXGETPROCADDRESS )
#define _glfw_glXGetProcAddress(x) glXGetProcAddress(x)
#elif defined( _GLFW_HAS_GLXGETPROCADDRESSEXT )
#define _glfw_glXGetProcAddress(x) glXGetProcAddressEXT(x)
#elif defined( _GLFW_HAS_DLOPEN )
#define _glfw_glXGetProcAddress(x) dlsym(_glfwLibs.libGL,x)
#define _GLFW_DLOPEN_LIBGL
#else
#define _glfw_glXGetProcAddress(x) NULL
#endif
// glXSwapIntervalSGI typedef (X11 buffer-swap interval control)
typedef int ( * GLXSWAPINTERVALSGI_T) (int interval);
//========================================================================
// Global variables (GLFW internals)
//========================================================================
//------------------------------------------------------------------------
// Window structure
//------------------------------------------------------------------------
typedef struct _GLFWwin_struct _GLFWwin;
struct _GLFWwin_struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// User callback functions
GLFWwindowsizefun WindowSizeCallback;
GLFWwindowclosefun WindowCloseCallback;
GLFWwindowrefreshfun WindowRefreshCallback;
GLFWmousebuttonfun MouseButtonCallback;
GLFWmouseposfun MousePosCallback;
GLFWmousewheelfun MouseWheelCallback;
GLFWkeyfun KeyCallback;
GLFWcharfun CharCallback;
// User selected window settings
int Fullscreen; // Fullscreen flag
int MouseLock; // Mouse-lock flag
int AutoPollEvents; // Auto polling flag
int SysKeysDisabled; // System keys disabled flag
int WindowNoResize; // Resize- and maximize gadgets disabled flag
// Window status & parameters
int Opened; // Flag telling if window is opened or not
int Active; // Application active flag
int Iconified; // Window iconified flag
int Width, Height; // Window width and heigth
int Accelerated; // GL_TRUE if window is HW accelerated
int RedBits;
int GreenBits;
int BlueBits;
int AlphaBits;
int DepthBits;
int StencilBits;
int AccumRedBits;
int AccumGreenBits;
int AccumBlueBits;
int AccumAlphaBits;
int AuxBuffers;
int Stereo;
int RefreshRate; // Vertical monitor refresh rate
int Samples;
// Extensions & OpenGL version
int Has_GL_SGIS_generate_mipmap;
int Has_GL_ARB_texture_non_power_of_two;
int GLVerMajor,GLVerMinor;
// ========= PLATFORM SPECIFIC PART ======================================
// Platform specific window resources
Window Win; // Window
int Scrn; // Screen ID
XVisualInfo *VI; // Visual
GLXContext CX; // OpenGL rendering context
Atom WMDeleteWindow; // For WM close detection
Atom WMPing; // For WM ping response
XSizeHints *Hints; // WM size hints
// Platform specific extensions
GLXSWAPINTERVALSGI_T SwapInterval;
// Various platform specific internal variables
int OverrideRedirect; // True if window is OverrideRedirect
int KeyboardGrabbed; // True if keyboard is currently grabbed
int PointerGrabbed; // True if pointer is currently grabbed
int PointerHidden; // True if pointer is currently hidden
int MapNotifyCount; // Used for during processing
int FocusInCount; // Used for during processing
// Screensaver data
struct {
int Changed;
int Timeout;
int Interval;
int Blanking;
int Exposure;
} Saver;
// Fullscreen data
struct {
int ModeChanged;
#if defined( _GLFW_HAS_XF86VIDMODE )
XF86VidModeModeInfo OldMode;
#endif
#if defined( _GLFW_HAS_XRANDR )
SizeID OldSizeID;
int OldWidth;
int OldHeight;
Rotation OldRotation;
#endif
} FS;
};
GLFWGLOBAL _GLFWwin _glfwWin;
//------------------------------------------------------------------------
// User input status (most of this should go in _GLFWwin)
//------------------------------------------------------------------------
GLFWGLOBAL struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Mouse status
int MousePosX, MousePosY;
int WheelPos;
char MouseButton[ GLFW_MOUSE_BUTTON_LAST+1 ];
// Keyboard status
char Key[ GLFW_KEY_LAST+1 ];
int LastChar;
// User selected settings
int StickyKeys;
int StickyMouseButtons;
int KeyRepeat;
// ========= PLATFORM SPECIFIC PART ======================================
// Platform specific internal variables
int MouseMoved, CursorPosX, CursorPosY;
} _glfwInput;
//------------------------------------------------------------------------
// Library global data
//------------------------------------------------------------------------
GLFWGLOBAL struct {
// ========= PLATFORM SPECIFIC PART ======================================
Display *Dpy;
int NumScreens;
int DefaultScreen;
struct {
int Available;
int EventBase;
int ErrorBase;
} XF86VidMode;
struct {
int Available;
int EventBase;
int ErrorBase;
} XRandR;
// Timer data
struct {
double Resolution;
long long t0;
} Timer;
#if defined(_GLFW_DLOPEN_LIBGL)
struct {
void *libGL; // dlopen handle for libGL.so
} Libs;
#endif
} _glfwLibrary;
//------------------------------------------------------------------------
// Thread record (one for each thread)
//------------------------------------------------------------------------
typedef struct _GLFWthread_struct _GLFWthread;
struct _GLFWthread_struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Pointer to previous and next threads in linked list
_GLFWthread *Previous, *Next;
// GLFW user side thread information
GLFWthread ID;
GLFWthreadfun Function;
// ========= PLATFORM SPECIFIC PART ======================================
// System side thread information
#ifdef _GLFW_HAS_PTHREAD
pthread_t PosixID;
#endif
};
//------------------------------------------------------------------------
// General thread information
//------------------------------------------------------------------------
GLFWGLOBAL struct {
// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
// Next thread ID to use (increments for every created thread)
GLFWthread NextID;
// First thread in linked list (always the main thread)
_GLFWthread First;
// ========= PLATFORM SPECIFIC PART ======================================
// Critical section lock
#ifdef _GLFW_HAS_PTHREAD
pthread_mutex_t CriticalSection;
#endif
} _glfwThrd;
//------------------------------------------------------------------------
// Joystick information & state
//------------------------------------------------------------------------
GLFWGLOBAL struct {
int Present;
int fd;
int NumAxes;
int NumButtons;
float *Axis;
unsigned char *Button;
} _glfwJoy[ GLFW_JOYSTICK_LAST + 1 ];
//========================================================================
// Macros for encapsulating critical code sections (i.e. making parts
// of GLFW thread safe)
//========================================================================
// Thread list management
#ifdef _GLFW_HAS_PTHREAD
#define ENTER_THREAD_CRITICAL_SECTION \
pthread_mutex_lock( &_glfwThrd.CriticalSection );
#define LEAVE_THREAD_CRITICAL_SECTION \
pthread_mutex_unlock( &_glfwThrd.CriticalSection );
#else
#define ENTER_THREAD_CRITICAL_SECTION
#define LEAVE_THREAD_CRITICAL_SECTION
#endif
//========================================================================
// Prototypes for platform specific internal functions
//========================================================================
// Time
void _glfwInitTimer( void );
// Fullscreen support
int _glfwGetClosestVideoMode( int screen, int *width, int *height, int *rate );
void _glfwSetVideoModeMODE( int screen, int mode, int rate );
void _glfwSetVideoMode( int screen, int *width, int *height, int *rate );
// Cursor handling
Cursor _glfwCreateNULLCursor( Display *display, Window root );
// Joystick input
void _glfwInitJoysticks( void );
void _glfwTerminateJoysticks( void );
// Unicode support
long _glfwKeySym2Unicode( KeySym keysym );
#endif // _platform_h_

View File

@ -0,0 +1,51 @@
//========================================================================
// GLFW - An OpenGL framework
// File: x11_enable.c
// Platform: X11 (Unix)
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformEnableSystemKeys() - Enable system keys
// _glfwPlatformDisableSystemKeys() - Disable system keys
//========================================================================
void _glfwPlatformEnableSystemKeys( void )
{
// Not supported under X11 (yet)
}
void _glfwPlatformDisableSystemKeys( void )
{
// Not supported under X11 (yet)
}

View File

@ -0,0 +1,524 @@
//========================================================================
// GLFW - An OpenGL framework
// File: x11_fullscreen.c
// Platform: X11 (Unix)
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwBPP2RGB() - Convert BPP to RGB bits (based on "best guess")
//========================================================================
static void _glfwBPP2RGB( int bpp, int *r, int *g, int *b )
{
int delta;
// Special case: BPP = 32 (I don't think this is necessary for X11??)
if( bpp == 32 )
bpp = 24;
// Convert "bits per pixel" to red, green & blue sizes
*r = *g = *b = bpp / 3;
delta = bpp - (*r * 3);
if( delta >= 1 )
{
*g = *g + 1;
}
if( delta == 2 )
{
*r = *r + 1;
}
}
//========================================================================
// Finds the video mode closest in size to the specified desired size
//========================================================================
int _glfwGetClosestVideoMode( int screen, int *width, int *height, int *rate )
{
#if defined( _GLFW_HAS_XRANDR )
int i, match, bestmatch;
int sizecount, bestsize;
int ratecount, bestrate;
short *ratelist;
XRRScreenConfiguration *sc;
XRRScreenSize *sizelist;
if( _glfwLibrary.XRandR.Available )
{
sc = XRRGetScreenInfo( _glfwLibrary.Dpy,
RootWindow( _glfwLibrary.Dpy, screen ) );
sizelist = XRRConfigSizes( sc, &sizecount );
// Find the best matching mode
bestsize = -1;
bestmatch = 999999;
for( i = 0; i < sizecount; i++ )
{
match = (*width - sizelist[i].width) *
(*width - sizelist[i].width) +
(*height - sizelist[i].height) *
(*height - sizelist[i].height);
if( match < bestmatch )
{
bestmatch = match;
bestsize = i;
}
}
if( bestsize != -1 )
{
// Report width & height of best matching mode
*width = sizelist[bestsize].width;
*height = sizelist[bestsize].height;
if( *rate > 0 )
{
ratelist = XRRConfigRates( sc, bestsize, &ratecount );
bestrate = -1;
bestmatch = 999999;
for( i = 0; i < ratecount; i++ )
{
match = abs( ratelist[i] - *rate );
if( match < bestmatch )
{
bestmatch = match;
bestrate = ratelist[i];
}
}
if( bestrate != -1 )
{
*rate = bestrate;
}
}
}
// Free modelist
XRRFreeScreenConfigInfo( sc );
if( bestsize != -1 )
{
return bestsize;
}
}
#elif defined( _GLFW_HAS_XF86VIDMODE )
XF86VidModeModeInfo **modelist;
int modecount, i, bestmode, bestmatch, match;
// Use the XF86VidMode extension to control video resolution
if( _glfwLibrary.XF86VidMode.Available )
{
// Get a list of all available display modes
XF86VidModeGetAllModeLines( _glfwLibrary.Dpy, screen,
&modecount, &modelist );
// Find the best matching mode
bestmode = -1;
bestmatch = 999999;
for( i = 0; i < modecount; i++ )
{
match = (*width - modelist[i]->hdisplay) *
(*width - modelist[i]->hdisplay) +
(*height - modelist[i]->vdisplay) *
(*height - modelist[i]->vdisplay);
if( match < bestmatch )
{
bestmatch = match;
bestmode = i;
}
}
if( bestmode != -1 )
{
// Report width & height of best matching mode
*width = modelist[ bestmode ]->hdisplay;
*h = modelist[ bestmode ]->vdisplay;
}
// Free modelist
XFree( modelist );
if( bestmode != -1 )
{
return bestmode;
}
}
#endif
// Default: Simply use the screen resolution
*width = DisplayWidth( _glfwLibrary.Dpy, screen );
*height = DisplayHeight( _glfwLibrary.Dpy, screen );
return 0;
}
//========================================================================
// Change the current video mode
//========================================================================
void _glfwSetVideoModeMODE( int screen, int mode, int rate )
{
#if defined( _GLFW_HAS_XRANDR )
XRRScreenConfiguration *sc;
Window root;
if( _glfwLibrary.XRandR.Available )
{
root = RootWindow( _glfwLibrary.Dpy, screen );
sc = XRRGetScreenInfo( _glfwLibrary.Dpy, root );
// Remember old size and flag that we have changed the mode
if( !_glfwWin.FS.ModeChanged )
{
_glfwWin.FS.OldSizeID = XRRConfigCurrentConfiguration( sc, &_glfwWin.FS.OldRotation );
_glfwWin.FS.OldWidth = DisplayWidth( _glfwLibrary.Dpy, screen );
_glfwWin.FS.OldHeight = DisplayHeight( _glfwLibrary.Dpy, screen );
_glfwWin.FS.ModeChanged = GL_TRUE;
}
if( rate > 0 )
{
// Set desired configuration
XRRSetScreenConfigAndRate( _glfwLibrary.Dpy,
sc,
root,
mode,
RR_Rotate_0,
(short) rate,
CurrentTime );
}
else
{
// Set desired configuration
XRRSetScreenConfig( _glfwLibrary.Dpy,
sc,
root,
mode,
RR_Rotate_0,
CurrentTime );
}
XRRFreeScreenConfigInfo( sc );
}
#elif defined( _GLFW_HAS_XF86VIDMODE )
XF86VidModeModeInfo **modelist;
int modecount;
// Use the XF86VidMode extension to control video resolution
if( _glfwLibrary.XF86VidMode.Available )
{
// Get a list of all available display modes
XF86VidModeGetAllModeLines( _glfwLibrary.Dpy, screen,
&modecount, &modelist );
// Unlock mode switch if necessary
if( _glfwWin.FS.ModeChanged )
{
XF86VidModeLockModeSwitch( _glfwLibrary.Dpy, screen, 0 );
}
// Change the video mode to the desired mode
XF86VidModeSwitchToMode( _glfwLibrary.Dpy, screen,
modelist[ mode ] );
// Set viewport to upper left corner (where our window will be)
XF86VidModeSetViewPort( _glfwLibrary.Dpy, screen, 0, 0 );
// Lock mode switch
XF86VidModeLockModeSwitch( _glfwLibrary.Dpy, screen, 1 );
// Remember old mode and flag that we have changed the mode
if( !_glfwWin.FS.ModeChanged )
{
_glfwWin.FS.OldMode = *modelist[ 0 ];
_glfwWin.FS.ModeChanged = GL_TRUE;
}
// Free mode list
XFree( modelist );
}
#endif
}
//========================================================================
// Change the current video mode
//========================================================================
void _glfwSetVideoMode( int screen, int *width, int *height, int *rate )
{
int bestmode;
// Find a best match mode
bestmode = _glfwGetClosestVideoMode( screen, width, height, rate );
// Change mode
_glfwSetVideoModeMODE( screen, bestmode, *rate );
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
struct _glfwResolution {
int width;
int height;
};
//========================================================================
// List available video modes
//========================================================================
int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )
{
int count, k, l, r, g, b, rgba, gl;
int depth, screen;
Display *dpy;
XVisualInfo *vislist, dummy;
int viscount, rgbcount, rescount;
int *rgbarray;
struct _glfwResolution *resarray;
#if defined( _GLFW_HAS_XRANDR )
XRRScreenConfiguration *sc;
XRRScreenSize *sizelist;
int sizecount;
#elif defined( _GLFW_HAS_XF86VIDMODE )
XF86VidModeModeInfo **modelist;
int modecount, width, height;
#endif
// Get display and screen
dpy = _glfwLibrary.Dpy;
screen = DefaultScreen( dpy );
// Get list of visuals
vislist = XGetVisualInfo( dpy, 0, &dummy, &viscount );
if( vislist == NULL )
{
return 0;
}
rgbarray = (int*) malloc( sizeof(int) * viscount );
rgbcount = 0;
// Build RGB array
for( k = 0; k < viscount; k++ )
{
// Does the visual support OpenGL & true color?
glXGetConfig( dpy, &vislist[k], GLX_USE_GL, &gl );
glXGetConfig( dpy, &vislist[k], GLX_RGBA, &rgba );
if( gl && rgba )
{
// Get color depth for this visual
depth = vislist[k].depth;
// Convert to RGB
_glfwBPP2RGB( depth, &r, &g, &b );
depth = (r<<16) | (g<<8) | b;
// Is this mode unique?
for( l = 0; l < rgbcount; l++ )
{
if( depth == rgbarray[ l ] )
{
break;
}
}
if( l >= rgbcount )
{
rgbarray[ rgbcount ] = depth;
rgbcount++;
}
}
}
rescount = 0;
resarray = NULL;
// Build resolution array
#if defined( _GLFW_HAS_XRANDR )
if( _glfwLibrary.XRandR.Available )
{
sc = XRRGetScreenInfo( dpy, RootWindow( dpy, screen ) );
sizelist = XRRConfigSizes( sc, &sizecount );
resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * sizecount );
for( k = 0; k < sizecount; k++ )
{
resarray[ rescount ].width = sizelist[ k ].width;
resarray[ rescount ].height = sizelist[ k ].height;
rescount++;
}
XRRFreeScreenConfigInfo( sc );
}
#elif defined( _GLFW_HAS_XF86VIDMODE )
if( _glfwLibrary.XF86VidMode.Available )
{
XF86VidModeGetAllModeLines( dpy, screen, &modecount, &modelist );
resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * modecount );
for( k = 0; k < modecount; k++ )
{
width = modelist[ k ]->hdisplay;
height = modelist[ k ]->vdisplay;
// Is this mode unique?
for( l = 0; l < rescount; l++ )
{
if( width == resarray[ l ].width && height == resarray[ l ].height )
{
break;
}
}
if( l >= rescount )
{
resarray[ rescount ].width = width;
resarray[ rescount ].height = height;
rescount++;
}
}
XFree( modelist );
}
#endif
if( !resarray )
{
rescount = 1;
resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * rescount );
resarray[ 0 ].width = DisplayWidth( dpy, screen );
resarray[ 0 ].height = DisplayHeight( dpy, screen );
}
// Build permutations of colors and resolutions
count = 0;
for( k = 0; k < rgbcount && count < maxcount; k++ )
{
for( l = 0; l < rescount && count < maxcount; l++ )
{
list[count].Width = resarray[ l ].width;
list[count].Height = resarray[ l ].height;
list[count].RedBits = (rgbarray[ k ] >> 16) & 255;
list[count].GreenBits = (rgbarray[ k ] >> 8) & 255;
list[count].BlueBits = rgbarray[ k ] & 255;
count++;
}
}
// Free visuals list
XFree( vislist );
free( resarray );
free( rgbarray );
return count;
}
//========================================================================
// Get the desktop video mode
//========================================================================
void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )
{
Display *dpy;
int bpp, screen;
#if defined( _GLFW_HAS_XF86VIDMODE )
XF86VidModeModeInfo **modelist;
int modecount;
#endif
// Get display and screen
dpy = _glfwLibrary.Dpy;
screen = DefaultScreen( dpy );
// Get display depth
bpp = DefaultDepth( dpy, screen );
// Convert BPP to RGB bits
_glfwBPP2RGB( bpp, &mode->RedBits, &mode->GreenBits, &mode->BlueBits );
#if defined( _GLFW_HAS_XRANDR )
if( _glfwLibrary.XRandR.Available )
{
if( _glfwWin.FS.ModeChanged )
{
mode->Width = _glfwWin.FS.OldWidth;
mode->Height = _glfwWin.FS.OldHeight;
return;
}
}
#elif defined( _GLFW_HAS_XF86VIDMODE )
if( _glfwLibrary.XF86VidMode.Available )
{
if( _glfwWin.FS.ModeChanged )
{
// The old (desktop) mode is stored in _glfwWin.FS.OldMode
mode->Width = _glfwWin.FS.OldMode.hdisplay;
mode->Height = _glfwWin.FS.OldMode.vdisplay;
}
else
{
// Use the XF86VidMode extension to get list of video modes
XF86VidModeGetAllModeLines( dpy, screen, &modecount,
&modelist );
// The first mode in the list is the current (desktio) mode
mode->Width = modelist[ 0 ]->hdisplay;
mode->Height = modelist[ 0 ]->vdisplay;
// Free list
XFree( modelist );
}
return;
}
#endif
// Get current display width and height
mode->Width = DisplayWidth( dpy, screen );
mode->Height = DisplayHeight( dpy, screen );
}

View File

@ -0,0 +1,69 @@
//========================================================================
// GLFW - An OpenGL framework
// File: x11_glext.c
// Platform: X11 (Unix)
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// Check if an OpenGL extension is available at runtime
//========================================================================
int _glfwPlatformExtensionSupported( const char *extension )
{
const GLubyte *extensions;
// Get list of GLX extensions
extensions = (const GLubyte*) glXQueryExtensionsString( _glfwLibrary.Dpy,
_glfwWin.Scrn );
if( extensions != NULL )
{
if( _glfwStringInExtensionString( extension, extensions ) )
{
return GL_TRUE;
}
}
return GL_FALSE;
}
//========================================================================
// Get the function pointer to an OpenGL function
//========================================================================
void * _glfwPlatformGetProcAddress( const char *procname )
{
return (void *) _glfw_glXGetProcAddress( (const GLubyte *) procname );
}

View File

@ -0,0 +1,275 @@
//========================================================================
// GLFW - An OpenGL framework
// File: x11_init.c
// Platform: X11 (Unix)
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// Initialize GLFW thread package
//========================================================================
static void _glfwInitThreads( void )
{
// Initialize critical section handle
#ifdef _GLFW_HAS_PTHREAD
(void) pthread_mutex_init( &_glfwThrd.CriticalSection, NULL );
#endif
// The first thread (the main thread) has ID 0
_glfwThrd.NextID = 0;
// Fill out information about the main thread (this thread)
_glfwThrd.First.ID = _glfwThrd.NextID++;
_glfwThrd.First.Function = NULL;
_glfwThrd.First.Previous = NULL;
_glfwThrd.First.Next = NULL;
#ifdef _GLFW_HAS_PTHREAD
_glfwThrd.First.PosixID = pthread_self();
#endif
}
//========================================================================
// Terminate GLFW thread package
//========================================================================
static void _glfwTerminateThreads( void )
{
#ifdef _GLFW_HAS_PTHREAD
_GLFWthread *t, *t_next;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Kill all threads (NOTE: THE USER SHOULD WAIT FOR ALL THREADS TO
// DIE, _BEFORE_ CALLING glfwTerminate()!!!)
t = _glfwThrd.First.Next;
while( t != NULL )
{
// Get pointer to next thread
t_next = t->Next;
// Simply murder the process, no mercy!
pthread_kill( t->PosixID, SIGKILL );
// Free memory allocated for this thread
free( (void *) t );
// Select next thread in list
t = t_next;
}
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Delete critical section handle
pthread_mutex_destroy( &_glfwThrd.CriticalSection );
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// Dynamically load libraries
//========================================================================
#ifdef _GLFW_DLOPEN_LIBGL
static char * _glfw_libGL_name[ ] =
{
"libGL.so",
"libGL.so.1",
"/usr/lib/libGL.so",
"/usr/lib/libGL.so.1",
NULL
};
#endif
static void _glfwInitLibraries( void )
{
#ifdef _GLFW_DLOPEN_LIBGL
int i;
_glfwLibrary.Libs.libGL = NULL;
for( i = 0; !_glfw_libGL_name[ i ] != NULL; i ++ )
{
_glfwLibrary.Libs.libGL = dlopen( _glfw_libGL_name[ i ],
RTLD_LAZY | RTLD_GLOBAL );
if( _glfwLibrary.Libs.libGL )
break;
}
#endif
}
//========================================================================
// Terminate GLFW when exiting application
//========================================================================
void _glfwTerminate_atexit( void )
{
glfwTerminate();
}
//========================================================================
// Initialize X11 display
//========================================================================
static int _glfwInitDisplay( void )
{
// Open display
_glfwLibrary.Dpy = XOpenDisplay( 0 );
if( !_glfwLibrary.Dpy )
{
return GL_FALSE;
}
// Check screens
_glfwLibrary.NumScreens = ScreenCount( _glfwLibrary.Dpy );
_glfwLibrary.DefaultScreen = DefaultScreen( _glfwLibrary.Dpy );
// Check for XF86VidMode extension
#ifdef _GLFW_HAS_XF86VIDMODE
_glfwLibrary.XF86VidMode.Available =
XF86VidModeQueryExtension( _glfwLibrary.Dpy,
&_glfwLibrary.XF86VidMode.EventBase,
&_glfwLibrary.XF86VidMode.ErrorBase);
#else
_glfwLibrary.XF86VidMode.Available = 0;
#endif
// Check for XRandR extension
#ifdef _GLFW_HAS_XRANDR
_glfwLibrary.XRandR.Available =
XRRQueryExtension( _glfwLibrary.Dpy,
&_glfwLibrary.XRandR.EventBase,
&_glfwLibrary.XRandR.ErrorBase );
#else
_glfwLibrary.XRandR.Available = 0;
#endif
return GL_TRUE;
}
//========================================================================
// Terminate X11 display
//========================================================================
static void _glfwTerminateDisplay( void )
{
// Open display
if( _glfwLibrary.Dpy )
{
XCloseDisplay( _glfwLibrary.Dpy );
_glfwLibrary.Dpy = NULL;
}
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// Initialize various GLFW state
//========================================================================
int _glfwPlatformInit( void )
{
// Initialize display
if( !_glfwInitDisplay() )
{
return GL_FALSE;
}
// Initialize thread package
_glfwInitThreads();
// Try to load libGL.so if necessary
_glfwInitLibraries();
// Install atexit() routine
atexit( _glfwTerminate_atexit );
// Initialize joysticks
_glfwInitJoysticks();
// Start the timer
_glfwInitTimer();
return GL_TRUE;
}
//========================================================================
// Close window and kill all threads
//========================================================================
int _glfwPlatformTerminate( void )
{
#ifdef _GLFW_HAS_PTHREAD
// Only the main thread is allowed to do this...
if( pthread_self() != _glfwThrd.First.PosixID )
{
return GL_FALSE;
}
#endif // _GLFW_HAS_PTHREAD
// Close OpenGL window
glfwCloseWindow();
// Kill thread package
_glfwTerminateThreads();
// Terminate display
_glfwTerminateDisplay();
// Terminate joysticks
_glfwTerminateJoysticks();
// Unload libGL.so if necessary
#ifdef _GLFW_DLOPEN_LIBGL
if( _glfwLibrary.Libs.libGL != NULL )
{
dlclose( _glfwLibrary.Libs.libGL );
_glfwLibrary.Libs.libGL = NULL;
}
#endif
return GL_TRUE;
}

View File

@ -0,0 +1,371 @@
//========================================================================
// GLFW - An OpenGL framework
// File: x11_joystick.c
// Platform: X11 (Unix)
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//========================================================================
// Note: Only Linux joystick input is supported at the moment. Other
// systems will behave as if there are no joysticks connected.
//========================================================================
#ifdef linux
#define _GLFW_USE_LINUX_JOYSTICKS
#endif // linux
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
#ifdef _GLFW_USE_LINUX_JOYSTICKS
//------------------------------------------------------------------------
// Here are the Linux joystick driver v1.x interface definitions that we
// use (we do not want to rely on <linux/joystick.h>):
//------------------------------------------------------------------------
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
// Joystick event types
#define JS_EVENT_BUTTON 0x01 /* button pressed/released */
#define JS_EVENT_AXIS 0x02 /* joystick moved */
#define JS_EVENT_INIT 0x80 /* initial state of device */
// Joystick event structure
struct js_event {
unsigned int time; /* (u32) event timestamp in milliseconds */
signed short value; /* (s16) value */
unsigned char type; /* (u8) event type */
unsigned char number; /* (u8) axis/button number */
};
// Joystick IOCTL commands
#define JSIOCGVERSION _IOR('j', 0x01, int) /* get driver version (u32) */
#define JSIOCGAXES _IOR('j', 0x11, char) /* get number of axes (u8) */
#define JSIOCGBUTTONS _IOR('j', 0x12, char) /* get number of buttons (u8) */
#endif // _GLFW_USE_LINUX_JOYSTICKS
//========================================================================
// _glfwInitJoysticks() - Initialize joystick interface
//========================================================================
void _glfwInitJoysticks( void )
{
#ifdef _GLFW_USE_LINUX_JOYSTICKS
int k, n, fd, joy_count;
char *joy_base_name, joy_dev_name[ 20 ];
int driver_version = 0x000800;
char ret_data;
#endif // _GLFW_USE_LINUX_JOYSTICKS
int i;
// Start by saying that there are no sticks
for( i = 0; i <= GLFW_JOYSTICK_LAST; ++ i )
{
_glfwJoy[ i ].Present = GL_FALSE;
}
#ifdef _GLFW_USE_LINUX_JOYSTICKS
// Try to open joysticks (nonblocking)
joy_count = 0;
for( k = 0; k <= 1 && joy_count <= GLFW_JOYSTICK_LAST; ++ k )
{
// Pick joystick base name
switch( k )
{
case 0:
joy_base_name = "/dev/input/js"; // USB sticks
break;
case 1:
joy_base_name = "/dev/js"; // "Legacy" sticks
break;
default:
continue; // (should never happen)
}
// Try to open a few of these sticks
for( i = 0; i <= 50 && joy_count <= GLFW_JOYSTICK_LAST; ++ i )
{
sprintf( joy_dev_name, "%s%d", joy_base_name, i );
fd = open( joy_dev_name, O_NONBLOCK );
if( fd != -1 )
{
// Remember fd
_glfwJoy[ joy_count ].fd = fd;
// Check that the joystick driver version is 1.0+
ioctl( fd, JSIOCGVERSION, &driver_version );
if( driver_version < 0x010000 )
{
// It's an old 0.x interface (we don't support it)
close( fd );
continue;
}
// Get number of joystick axes
ioctl( fd, JSIOCGAXES, &ret_data );
_glfwJoy[ joy_count ].NumAxes = (int) ret_data;
// Get number of joystick buttons
ioctl( fd, JSIOCGBUTTONS, &ret_data );
_glfwJoy[ joy_count ].NumButtons = (int) ret_data;
// Allocate memory for joystick state
_glfwJoy[ joy_count ].Axis =
(float *) malloc( sizeof(float) *
_glfwJoy[ joy_count ].NumAxes );
if( _glfwJoy[ joy_count ].Axis == NULL )
{
close( fd );
continue;
}
_glfwJoy[ joy_count ].Button =
(char *) malloc( sizeof(char) *
_glfwJoy[ joy_count ].NumButtons );
if( _glfwJoy[ joy_count ].Button == NULL )
{
free( _glfwJoy[ joy_count ].Axis );
close( fd );
continue;
}
// Clear joystick state
for( n = 0; n < _glfwJoy[ joy_count ].NumAxes; ++ n )
{
_glfwJoy[ joy_count ].Axis[ n ] = 0.0f;
}
for( n = 0; n < _glfwJoy[ joy_count ].NumButtons; ++ n )
{
_glfwJoy[ joy_count ].Button[ n ] = GLFW_RELEASE;
}
// The joystick is supported and connected
_glfwJoy[ joy_count ].Present = GL_TRUE;
joy_count ++;
}
}
}
#endif // _GLFW_USE_LINUX_JOYSTICKS
}
//========================================================================
// _glfwTerminateJoysticks() - Close all opened joystick handles
//========================================================================
void _glfwTerminateJoysticks( void )
{
#ifdef _GLFW_USE_LINUX_JOYSTICKS
int i;
// Close any opened joysticks
for( i = 0; i <= GLFW_JOYSTICK_LAST; ++ i )
{
if( _glfwJoy[ i ].Present )
{
close( _glfwJoy[ i ].fd );
free( _glfwJoy[ i ].Axis );
free( _glfwJoy[ i ].Button );
_glfwJoy[ i ].Present = GL_FALSE;
}
}
#endif // _GLFW_USE_LINUX_JOYSTICKS
}
//========================================================================
// _glfwPollJoystickEvents() - Empty joystick event queue
//========================================================================
static void _glfwPollJoystickEvents( void )
{
#ifdef _GLFW_USE_LINUX_JOYSTICKS
struct js_event e;
int i;
// Get joystick events for all GLFW joysticks
for( i = 0; i <= GLFW_JOYSTICK_LAST; ++ i )
{
// Is the stick present?
if( _glfwJoy[ i ].Present )
{
// Read all queued events (non-blocking)
while( read(_glfwJoy[i].fd, &e, sizeof(struct js_event)) > 0 )
{
// We don't care if it's an init event or not
e.type &= ~JS_EVENT_INIT;
// Check event type
switch( e.type )
{
case JS_EVENT_AXIS:
_glfwJoy[ i ].Axis[ e.number ] = (float) e.value /
32767.0f;
// We need to change the sign for the Y axes, so that
// positive = up/forward, according to the GLFW spec.
if( e.number & 1 )
{
_glfwJoy[ i ].Axis[ e.number ] =
-_glfwJoy[ i ].Axis[ e.number ];
}
break;
case JS_EVENT_BUTTON:
_glfwJoy[ i ].Button[ e.number ] =
e.value ? GLFW_PRESS : GLFW_RELEASE;
break;
default:
break;
}
}
}
}
#endif // _GLFW_USE_LINUX_JOYSTICKS
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformGetJoystickParam() - Determine joystick capabilities
//========================================================================
int _glfwPlatformGetJoystickParam( int joy, int param )
{
// Is joystick present?
if( !_glfwJoy[ joy ].Present )
{
return 0;
}
switch( param )
{
case GLFW_PRESENT:
return GL_TRUE;
case GLFW_AXES:
return _glfwJoy[ joy ].NumAxes;
case GLFW_BUTTONS:
return _glfwJoy[ joy ].NumButtons;
default:
break;
}
return 0;
}
//========================================================================
// _glfwPlatformGetJoystickPos() - Get joystick axis positions
//========================================================================
int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )
{
int i;
// Is joystick present?
if( !_glfwJoy[ joy ].Present )
{
return 0;
}
// Update joystick state
_glfwPollJoystickEvents();
// Does the joystick support less axes than requested?
if( _glfwJoy[ joy ].NumAxes < numaxes )
{
numaxes = _glfwJoy[ joy ].NumAxes;
}
// Copy axis positions from internal state
for( i = 0; i < numaxes; ++ i )
{
pos[ i ] = _glfwJoy[ joy ].Axis[ i ];
}
return numaxes;
}
//========================================================================
// _glfwPlatformGetJoystickButtons() - Get joystick button states
//========================================================================
int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons,
int numbuttons )
{
int i;
// Is joystick present?
if( !_glfwJoy[ joy ].Present )
{
return 0;
}
// Update joystick state
_glfwPollJoystickEvents();
// Does the joystick support less buttons than requested?
if( _glfwJoy[ joy ].NumButtons < numbuttons )
{
numbuttons = _glfwJoy[ joy ].NumButtons;
}
// Copy button states from internal state
for( i = 0; i < numbuttons; ++ i )
{
buttons[ i ] = _glfwJoy[ joy ].Button[ i ];
}
return numbuttons;
}

View File

@ -0,0 +1,902 @@
//========================================================================
// GLFW - An OpenGL framework
// File: x11_keysym2unicode.c
// Platform: X11 (Unix)
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
/*
* Marcus: This code was originally written by Markus G. Kuhn.
* I have made some slight changes (trimmed it down a bit from >60 KB to
* 20 KB), but the functionality is the same.
*/
/*
* This module converts keysym values into the corresponding ISO 10646
* (UCS, Unicode) values.
*
* The array keysymtab[] contains pairs of X11 keysym values for graphical
* characters and the corresponding Unicode value. The function
* _glfwKeySym2Unicode() maps a keysym onto a Unicode value using a binary
* search, therefore keysymtab[] must remain SORTED by keysym value.
*
* We allow to represent any UCS character in the range U-00000000 to
* U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
* This admittedly does not cover the entire 31-bit space of UCS, but
* it does cover all of the characters up to U-10FFFF, which can be
* represented by UTF-16, and more, and it is very unlikely that higher
* UCS codes will ever be assigned by ISO. So to get Unicode character
* U+ABCD you can directly use keysym 0x0100abcd.
*
* Original author: Markus G. Kuhn <mkuhn@acm.org>, University of
* Cambridge, April 2001
*
* Special thanks to Richard Verhoeven <river@win.tue.nl> for preparing
* an initial draft of the mapping table.
*
*/
//************************************************************************
//**** KeySym to Unicode mapping table ****
//************************************************************************
static struct codepair {
unsigned short keysym;
unsigned short ucs;
} keysymtab[] = {
{ 0x01a1, 0x0104 },
{ 0x01a2, 0x02d8 },
{ 0x01a3, 0x0141 },
{ 0x01a5, 0x013d },
{ 0x01a6, 0x015a },
{ 0x01a9, 0x0160 },
{ 0x01aa, 0x015e },
{ 0x01ab, 0x0164 },
{ 0x01ac, 0x0179 },
{ 0x01ae, 0x017d },
{ 0x01af, 0x017b },
{ 0x01b1, 0x0105 },
{ 0x01b2, 0x02db },
{ 0x01b3, 0x0142 },
{ 0x01b5, 0x013e },
{ 0x01b6, 0x015b },
{ 0x01b7, 0x02c7 },
{ 0x01b9, 0x0161 },
{ 0x01ba, 0x015f },
{ 0x01bb, 0x0165 },
{ 0x01bc, 0x017a },
{ 0x01bd, 0x02dd },
{ 0x01be, 0x017e },
{ 0x01bf, 0x017c },
{ 0x01c0, 0x0154 },
{ 0x01c3, 0x0102 },
{ 0x01c5, 0x0139 },
{ 0x01c6, 0x0106 },
{ 0x01c8, 0x010c },
{ 0x01ca, 0x0118 },
{ 0x01cc, 0x011a },
{ 0x01cf, 0x010e },
{ 0x01d0, 0x0110 },
{ 0x01d1, 0x0143 },
{ 0x01d2, 0x0147 },
{ 0x01d5, 0x0150 },
{ 0x01d8, 0x0158 },
{ 0x01d9, 0x016e },
{ 0x01db, 0x0170 },
{ 0x01de, 0x0162 },
{ 0x01e0, 0x0155 },
{ 0x01e3, 0x0103 },
{ 0x01e5, 0x013a },
{ 0x01e6, 0x0107 },
{ 0x01e8, 0x010d },
{ 0x01ea, 0x0119 },
{ 0x01ec, 0x011b },
{ 0x01ef, 0x010f },
{ 0x01f0, 0x0111 },
{ 0x01f1, 0x0144 },
{ 0x01f2, 0x0148 },
{ 0x01f5, 0x0151 },
{ 0x01f8, 0x0159 },
{ 0x01f9, 0x016f },
{ 0x01fb, 0x0171 },
{ 0x01fe, 0x0163 },
{ 0x01ff, 0x02d9 },
{ 0x02a1, 0x0126 },
{ 0x02a6, 0x0124 },
{ 0x02a9, 0x0130 },
{ 0x02ab, 0x011e },
{ 0x02ac, 0x0134 },
{ 0x02b1, 0x0127 },
{ 0x02b6, 0x0125 },
{ 0x02b9, 0x0131 },
{ 0x02bb, 0x011f },
{ 0x02bc, 0x0135 },
{ 0x02c5, 0x010a },
{ 0x02c6, 0x0108 },
{ 0x02d5, 0x0120 },
{ 0x02d8, 0x011c },
{ 0x02dd, 0x016c },
{ 0x02de, 0x015c },
{ 0x02e5, 0x010b },
{ 0x02e6, 0x0109 },
{ 0x02f5, 0x0121 },
{ 0x02f8, 0x011d },
{ 0x02fd, 0x016d },
{ 0x02fe, 0x015d },
{ 0x03a2, 0x0138 },
{ 0x03a3, 0x0156 },
{ 0x03a5, 0x0128 },
{ 0x03a6, 0x013b },
{ 0x03aa, 0x0112 },
{ 0x03ab, 0x0122 },
{ 0x03ac, 0x0166 },
{ 0x03b3, 0x0157 },
{ 0x03b5, 0x0129 },
{ 0x03b6, 0x013c },
{ 0x03ba, 0x0113 },
{ 0x03bb, 0x0123 },
{ 0x03bc, 0x0167 },
{ 0x03bd, 0x014a },
{ 0x03bf, 0x014b },
{ 0x03c0, 0x0100 },
{ 0x03c7, 0x012e },
{ 0x03cc, 0x0116 },
{ 0x03cf, 0x012a },
{ 0x03d1, 0x0145 },
{ 0x03d2, 0x014c },
{ 0x03d3, 0x0136 },
{ 0x03d9, 0x0172 },
{ 0x03dd, 0x0168 },
{ 0x03de, 0x016a },
{ 0x03e0, 0x0101 },
{ 0x03e7, 0x012f },
{ 0x03ec, 0x0117 },
{ 0x03ef, 0x012b },
{ 0x03f1, 0x0146 },
{ 0x03f2, 0x014d },
{ 0x03f3, 0x0137 },
{ 0x03f9, 0x0173 },
{ 0x03fd, 0x0169 },
{ 0x03fe, 0x016b },
{ 0x047e, 0x203e },
{ 0x04a1, 0x3002 },
{ 0x04a2, 0x300c },
{ 0x04a3, 0x300d },
{ 0x04a4, 0x3001 },
{ 0x04a5, 0x30fb },
{ 0x04a6, 0x30f2 },
{ 0x04a7, 0x30a1 },
{ 0x04a8, 0x30a3 },
{ 0x04a9, 0x30a5 },
{ 0x04aa, 0x30a7 },
{ 0x04ab, 0x30a9 },
{ 0x04ac, 0x30e3 },
{ 0x04ad, 0x30e5 },
{ 0x04ae, 0x30e7 },
{ 0x04af, 0x30c3 },
{ 0x04b0, 0x30fc },
{ 0x04b1, 0x30a2 },
{ 0x04b2, 0x30a4 },
{ 0x04b3, 0x30a6 },
{ 0x04b4, 0x30a8 },
{ 0x04b5, 0x30aa },
{ 0x04b6, 0x30ab },
{ 0x04b7, 0x30ad },
{ 0x04b8, 0x30af },
{ 0x04b9, 0x30b1 },
{ 0x04ba, 0x30b3 },
{ 0x04bb, 0x30b5 },
{ 0x04bc, 0x30b7 },
{ 0x04bd, 0x30b9 },
{ 0x04be, 0x30bb },
{ 0x04bf, 0x30bd },
{ 0x04c0, 0x30bf },
{ 0x04c1, 0x30c1 },
{ 0x04c2, 0x30c4 },
{ 0x04c3, 0x30c6 },
{ 0x04c4, 0x30c8 },
{ 0x04c5, 0x30ca },
{ 0x04c6, 0x30cb },
{ 0x04c7, 0x30cc },
{ 0x04c8, 0x30cd },
{ 0x04c9, 0x30ce },
{ 0x04ca, 0x30cf },
{ 0x04cb, 0x30d2 },
{ 0x04cc, 0x30d5 },
{ 0x04cd, 0x30d8 },
{ 0x04ce, 0x30db },
{ 0x04cf, 0x30de },
{ 0x04d0, 0x30df },
{ 0x04d1, 0x30e0 },
{ 0x04d2, 0x30e1 },
{ 0x04d3, 0x30e2 },
{ 0x04d4, 0x30e4 },
{ 0x04d5, 0x30e6 },
{ 0x04d6, 0x30e8 },
{ 0x04d7, 0x30e9 },
{ 0x04d8, 0x30ea },
{ 0x04d9, 0x30eb },
{ 0x04da, 0x30ec },
{ 0x04db, 0x30ed },
{ 0x04dc, 0x30ef },
{ 0x04dd, 0x30f3 },
{ 0x04de, 0x309b },
{ 0x04df, 0x309c },
{ 0x05ac, 0x060c },
{ 0x05bb, 0x061b },
{ 0x05bf, 0x061f },
{ 0x05c1, 0x0621 },
{ 0x05c2, 0x0622 },
{ 0x05c3, 0x0623 },
{ 0x05c4, 0x0624 },
{ 0x05c5, 0x0625 },
{ 0x05c6, 0x0626 },
{ 0x05c7, 0x0627 },
{ 0x05c8, 0x0628 },
{ 0x05c9, 0x0629 },
{ 0x05ca, 0x062a },
{ 0x05cb, 0x062b },
{ 0x05cc, 0x062c },
{ 0x05cd, 0x062d },
{ 0x05ce, 0x062e },
{ 0x05cf, 0x062f },
{ 0x05d0, 0x0630 },
{ 0x05d1, 0x0631 },
{ 0x05d2, 0x0632 },
{ 0x05d3, 0x0633 },
{ 0x05d4, 0x0634 },
{ 0x05d5, 0x0635 },
{ 0x05d6, 0x0636 },
{ 0x05d7, 0x0637 },
{ 0x05d8, 0x0638 },
{ 0x05d9, 0x0639 },
{ 0x05da, 0x063a },
{ 0x05e0, 0x0640 },
{ 0x05e1, 0x0641 },
{ 0x05e2, 0x0642 },
{ 0x05e3, 0x0643 },
{ 0x05e4, 0x0644 },
{ 0x05e5, 0x0645 },
{ 0x05e6, 0x0646 },
{ 0x05e7, 0x0647 },
{ 0x05e8, 0x0648 },
{ 0x05e9, 0x0649 },
{ 0x05ea, 0x064a },
{ 0x05eb, 0x064b },
{ 0x05ec, 0x064c },
{ 0x05ed, 0x064d },
{ 0x05ee, 0x064e },
{ 0x05ef, 0x064f },
{ 0x05f0, 0x0650 },
{ 0x05f1, 0x0651 },
{ 0x05f2, 0x0652 },
{ 0x06a1, 0x0452 },
{ 0x06a2, 0x0453 },
{ 0x06a3, 0x0451 },
{ 0x06a4, 0x0454 },
{ 0x06a5, 0x0455 },
{ 0x06a6, 0x0456 },
{ 0x06a7, 0x0457 },
{ 0x06a8, 0x0458 },
{ 0x06a9, 0x0459 },
{ 0x06aa, 0x045a },
{ 0x06ab, 0x045b },
{ 0x06ac, 0x045c },
{ 0x06ae, 0x045e },
{ 0x06af, 0x045f },
{ 0x06b0, 0x2116 },
{ 0x06b1, 0x0402 },
{ 0x06b2, 0x0403 },
{ 0x06b3, 0x0401 },
{ 0x06b4, 0x0404 },
{ 0x06b5, 0x0405 },
{ 0x06b6, 0x0406 },
{ 0x06b7, 0x0407 },
{ 0x06b8, 0x0408 },
{ 0x06b9, 0x0409 },
{ 0x06ba, 0x040a },
{ 0x06bb, 0x040b },
{ 0x06bc, 0x040c },
{ 0x06be, 0x040e },
{ 0x06bf, 0x040f },
{ 0x06c0, 0x044e },
{ 0x06c1, 0x0430 },
{ 0x06c2, 0x0431 },
{ 0x06c3, 0x0446 },
{ 0x06c4, 0x0434 },
{ 0x06c5, 0x0435 },
{ 0x06c6, 0x0444 },
{ 0x06c7, 0x0433 },
{ 0x06c8, 0x0445 },
{ 0x06c9, 0x0438 },
{ 0x06ca, 0x0439 },
{ 0x06cb, 0x043a },
{ 0x06cc, 0x043b },
{ 0x06cd, 0x043c },
{ 0x06ce, 0x043d },
{ 0x06cf, 0x043e },
{ 0x06d0, 0x043f },
{ 0x06d1, 0x044f },
{ 0x06d2, 0x0440 },
{ 0x06d3, 0x0441 },
{ 0x06d4, 0x0442 },
{ 0x06d5, 0x0443 },
{ 0x06d6, 0x0436 },
{ 0x06d7, 0x0432 },
{ 0x06d8, 0x044c },
{ 0x06d9, 0x044b },
{ 0x06da, 0x0437 },
{ 0x06db, 0x0448 },
{ 0x06dc, 0x044d },
{ 0x06dd, 0x0449 },
{ 0x06de, 0x0447 },
{ 0x06df, 0x044a },
{ 0x06e0, 0x042e },
{ 0x06e1, 0x0410 },
{ 0x06e2, 0x0411 },
{ 0x06e3, 0x0426 },
{ 0x06e4, 0x0414 },
{ 0x06e5, 0x0415 },
{ 0x06e6, 0x0424 },
{ 0x06e7, 0x0413 },
{ 0x06e8, 0x0425 },
{ 0x06e9, 0x0418 },
{ 0x06ea, 0x0419 },
{ 0x06eb, 0x041a },
{ 0x06ec, 0x041b },
{ 0x06ed, 0x041c },
{ 0x06ee, 0x041d },
{ 0x06ef, 0x041e },
{ 0x06f0, 0x041f },
{ 0x06f1, 0x042f },
{ 0x06f2, 0x0420 },
{ 0x06f3, 0x0421 },
{ 0x06f4, 0x0422 },
{ 0x06f5, 0x0423 },
{ 0x06f6, 0x0416 },
{ 0x06f7, 0x0412 },
{ 0x06f8, 0x042c },
{ 0x06f9, 0x042b },
{ 0x06fa, 0x0417 },
{ 0x06fb, 0x0428 },
{ 0x06fc, 0x042d },
{ 0x06fd, 0x0429 },
{ 0x06fe, 0x0427 },
{ 0x06ff, 0x042a },
{ 0x07a1, 0x0386 },
{ 0x07a2, 0x0388 },
{ 0x07a3, 0x0389 },
{ 0x07a4, 0x038a },
{ 0x07a5, 0x03aa },
{ 0x07a7, 0x038c },
{ 0x07a8, 0x038e },
{ 0x07a9, 0x03ab },
{ 0x07ab, 0x038f },
{ 0x07ae, 0x0385 },
{ 0x07af, 0x2015 },
{ 0x07b1, 0x03ac },
{ 0x07b2, 0x03ad },
{ 0x07b3, 0x03ae },
{ 0x07b4, 0x03af },
{ 0x07b5, 0x03ca },
{ 0x07b6, 0x0390 },
{ 0x07b7, 0x03cc },
{ 0x07b8, 0x03cd },
{ 0x07b9, 0x03cb },
{ 0x07ba, 0x03b0 },
{ 0x07bb, 0x03ce },
{ 0x07c1, 0x0391 },
{ 0x07c2, 0x0392 },
{ 0x07c3, 0x0393 },
{ 0x07c4, 0x0394 },
{ 0x07c5, 0x0395 },
{ 0x07c6, 0x0396 },
{ 0x07c7, 0x0397 },
{ 0x07c8, 0x0398 },
{ 0x07c9, 0x0399 },
{ 0x07ca, 0x039a },
{ 0x07cb, 0x039b },
{ 0x07cc, 0x039c },
{ 0x07cd, 0x039d },
{ 0x07ce, 0x039e },
{ 0x07cf, 0x039f },
{ 0x07d0, 0x03a0 },
{ 0x07d1, 0x03a1 },
{ 0x07d2, 0x03a3 },
{ 0x07d4, 0x03a4 },
{ 0x07d5, 0x03a5 },
{ 0x07d6, 0x03a6 },
{ 0x07d7, 0x03a7 },
{ 0x07d8, 0x03a8 },
{ 0x07d9, 0x03a9 },
{ 0x07e1, 0x03b1 },
{ 0x07e2, 0x03b2 },
{ 0x07e3, 0x03b3 },
{ 0x07e4, 0x03b4 },
{ 0x07e5, 0x03b5 },
{ 0x07e6, 0x03b6 },
{ 0x07e7, 0x03b7 },
{ 0x07e8, 0x03b8 },
{ 0x07e9, 0x03b9 },
{ 0x07ea, 0x03ba },
{ 0x07eb, 0x03bb },
{ 0x07ec, 0x03bc },
{ 0x07ed, 0x03bd },
{ 0x07ee, 0x03be },
{ 0x07ef, 0x03bf },
{ 0x07f0, 0x03c0 },
{ 0x07f1, 0x03c1 },
{ 0x07f2, 0x03c3 },
{ 0x07f3, 0x03c2 },
{ 0x07f4, 0x03c4 },
{ 0x07f5, 0x03c5 },
{ 0x07f6, 0x03c6 },
{ 0x07f7, 0x03c7 },
{ 0x07f8, 0x03c8 },
{ 0x07f9, 0x03c9 },
{ 0x08a1, 0x23b7 },
{ 0x08a2, 0x250c },
{ 0x08a3, 0x2500 },
{ 0x08a4, 0x2320 },
{ 0x08a5, 0x2321 },
{ 0x08a6, 0x2502 },
{ 0x08a7, 0x23a1 },
{ 0x08a8, 0x23a3 },
{ 0x08a9, 0x23a4 },
{ 0x08aa, 0x23a6 },
{ 0x08ab, 0x239b },
{ 0x08ac, 0x239d },
{ 0x08ad, 0x239e },
{ 0x08ae, 0x23a0 },
{ 0x08af, 0x23a8 },
{ 0x08b0, 0x23ac },
{ 0x08bc, 0x2264 },
{ 0x08bd, 0x2260 },
{ 0x08be, 0x2265 },
{ 0x08bf, 0x222b },
{ 0x08c0, 0x2234 },
{ 0x08c1, 0x221d },
{ 0x08c2, 0x221e },
{ 0x08c5, 0x2207 },
{ 0x08c8, 0x223c },
{ 0x08c9, 0x2243 },
{ 0x08cd, 0x21d4 },
{ 0x08ce, 0x21d2 },
{ 0x08cf, 0x2261 },
{ 0x08d6, 0x221a },
{ 0x08da, 0x2282 },
{ 0x08db, 0x2283 },
{ 0x08dc, 0x2229 },
{ 0x08dd, 0x222a },
{ 0x08de, 0x2227 },
{ 0x08df, 0x2228 },
{ 0x08ef, 0x2202 },
{ 0x08f6, 0x0192 },
{ 0x08fb, 0x2190 },
{ 0x08fc, 0x2191 },
{ 0x08fd, 0x2192 },
{ 0x08fe, 0x2193 },
{ 0x09e0, 0x25c6 },
{ 0x09e1, 0x2592 },
{ 0x09e2, 0x2409 },
{ 0x09e3, 0x240c },
{ 0x09e4, 0x240d },
{ 0x09e5, 0x240a },
{ 0x09e8, 0x2424 },
{ 0x09e9, 0x240b },
{ 0x09ea, 0x2518 },
{ 0x09eb, 0x2510 },
{ 0x09ec, 0x250c },
{ 0x09ed, 0x2514 },
{ 0x09ee, 0x253c },
{ 0x09ef, 0x23ba },
{ 0x09f0, 0x23bb },
{ 0x09f1, 0x2500 },
{ 0x09f2, 0x23bc },
{ 0x09f3, 0x23bd },
{ 0x09f4, 0x251c },
{ 0x09f5, 0x2524 },
{ 0x09f6, 0x2534 },
{ 0x09f7, 0x252c },
{ 0x09f8, 0x2502 },
{ 0x0aa1, 0x2003 },
{ 0x0aa2, 0x2002 },
{ 0x0aa3, 0x2004 },
{ 0x0aa4, 0x2005 },
{ 0x0aa5, 0x2007 },
{ 0x0aa6, 0x2008 },
{ 0x0aa7, 0x2009 },
{ 0x0aa8, 0x200a },
{ 0x0aa9, 0x2014 },
{ 0x0aaa, 0x2013 },
{ 0x0aae, 0x2026 },
{ 0x0aaf, 0x2025 },
{ 0x0ab0, 0x2153 },
{ 0x0ab1, 0x2154 },
{ 0x0ab2, 0x2155 },
{ 0x0ab3, 0x2156 },
{ 0x0ab4, 0x2157 },
{ 0x0ab5, 0x2158 },
{ 0x0ab6, 0x2159 },
{ 0x0ab7, 0x215a },
{ 0x0ab8, 0x2105 },
{ 0x0abb, 0x2012 },
{ 0x0abc, 0x2329 },
{ 0x0abe, 0x232a },
{ 0x0ac3, 0x215b },
{ 0x0ac4, 0x215c },
{ 0x0ac5, 0x215d },
{ 0x0ac6, 0x215e },
{ 0x0ac9, 0x2122 },
{ 0x0aca, 0x2613 },
{ 0x0acc, 0x25c1 },
{ 0x0acd, 0x25b7 },
{ 0x0ace, 0x25cb },
{ 0x0acf, 0x25af },
{ 0x0ad0, 0x2018 },
{ 0x0ad1, 0x2019 },
{ 0x0ad2, 0x201c },
{ 0x0ad3, 0x201d },
{ 0x0ad4, 0x211e },
{ 0x0ad6, 0x2032 },
{ 0x0ad7, 0x2033 },
{ 0x0ad9, 0x271d },
{ 0x0adb, 0x25ac },
{ 0x0adc, 0x25c0 },
{ 0x0add, 0x25b6 },
{ 0x0ade, 0x25cf },
{ 0x0adf, 0x25ae },
{ 0x0ae0, 0x25e6 },
{ 0x0ae1, 0x25ab },
{ 0x0ae2, 0x25ad },
{ 0x0ae3, 0x25b3 },
{ 0x0ae4, 0x25bd },
{ 0x0ae5, 0x2606 },
{ 0x0ae6, 0x2022 },
{ 0x0ae7, 0x25aa },
{ 0x0ae8, 0x25b2 },
{ 0x0ae9, 0x25bc },
{ 0x0aea, 0x261c },
{ 0x0aeb, 0x261e },
{ 0x0aec, 0x2663 },
{ 0x0aed, 0x2666 },
{ 0x0aee, 0x2665 },
{ 0x0af0, 0x2720 },
{ 0x0af1, 0x2020 },
{ 0x0af2, 0x2021 },
{ 0x0af3, 0x2713 },
{ 0x0af4, 0x2717 },
{ 0x0af5, 0x266f },
{ 0x0af6, 0x266d },
{ 0x0af7, 0x2642 },
{ 0x0af8, 0x2640 },
{ 0x0af9, 0x260e },
{ 0x0afa, 0x2315 },
{ 0x0afb, 0x2117 },
{ 0x0afc, 0x2038 },
{ 0x0afd, 0x201a },
{ 0x0afe, 0x201e },
{ 0x0ba3, 0x003c },
{ 0x0ba6, 0x003e },
{ 0x0ba8, 0x2228 },
{ 0x0ba9, 0x2227 },
{ 0x0bc0, 0x00af },
{ 0x0bc2, 0x22a5 },
{ 0x0bc3, 0x2229 },
{ 0x0bc4, 0x230a },
{ 0x0bc6, 0x005f },
{ 0x0bca, 0x2218 },
{ 0x0bcc, 0x2395 },
{ 0x0bce, 0x22a4 },
{ 0x0bcf, 0x25cb },
{ 0x0bd3, 0x2308 },
{ 0x0bd6, 0x222a },
{ 0x0bd8, 0x2283 },
{ 0x0bda, 0x2282 },
{ 0x0bdc, 0x22a2 },
{ 0x0bfc, 0x22a3 },
{ 0x0cdf, 0x2017 },
{ 0x0ce0, 0x05d0 },
{ 0x0ce1, 0x05d1 },
{ 0x0ce2, 0x05d2 },
{ 0x0ce3, 0x05d3 },
{ 0x0ce4, 0x05d4 },
{ 0x0ce5, 0x05d5 },
{ 0x0ce6, 0x05d6 },
{ 0x0ce7, 0x05d7 },
{ 0x0ce8, 0x05d8 },
{ 0x0ce9, 0x05d9 },
{ 0x0cea, 0x05da },
{ 0x0ceb, 0x05db },
{ 0x0cec, 0x05dc },
{ 0x0ced, 0x05dd },
{ 0x0cee, 0x05de },
{ 0x0cef, 0x05df },
{ 0x0cf0, 0x05e0 },
{ 0x0cf1, 0x05e1 },
{ 0x0cf2, 0x05e2 },
{ 0x0cf3, 0x05e3 },
{ 0x0cf4, 0x05e4 },
{ 0x0cf5, 0x05e5 },
{ 0x0cf6, 0x05e6 },
{ 0x0cf7, 0x05e7 },
{ 0x0cf8, 0x05e8 },
{ 0x0cf9, 0x05e9 },
{ 0x0cfa, 0x05ea },
{ 0x0da1, 0x0e01 },
{ 0x0da2, 0x0e02 },
{ 0x0da3, 0x0e03 },
{ 0x0da4, 0x0e04 },
{ 0x0da5, 0x0e05 },
{ 0x0da6, 0x0e06 },
{ 0x0da7, 0x0e07 },
{ 0x0da8, 0x0e08 },
{ 0x0da9, 0x0e09 },
{ 0x0daa, 0x0e0a },
{ 0x0dab, 0x0e0b },
{ 0x0dac, 0x0e0c },
{ 0x0dad, 0x0e0d },
{ 0x0dae, 0x0e0e },
{ 0x0daf, 0x0e0f },
{ 0x0db0, 0x0e10 },
{ 0x0db1, 0x0e11 },
{ 0x0db2, 0x0e12 },
{ 0x0db3, 0x0e13 },
{ 0x0db4, 0x0e14 },
{ 0x0db5, 0x0e15 },
{ 0x0db6, 0x0e16 },
{ 0x0db7, 0x0e17 },
{ 0x0db8, 0x0e18 },
{ 0x0db9, 0x0e19 },
{ 0x0dba, 0x0e1a },
{ 0x0dbb, 0x0e1b },
{ 0x0dbc, 0x0e1c },
{ 0x0dbd, 0x0e1d },
{ 0x0dbe, 0x0e1e },
{ 0x0dbf, 0x0e1f },
{ 0x0dc0, 0x0e20 },
{ 0x0dc1, 0x0e21 },
{ 0x0dc2, 0x0e22 },
{ 0x0dc3, 0x0e23 },
{ 0x0dc4, 0x0e24 },
{ 0x0dc5, 0x0e25 },
{ 0x0dc6, 0x0e26 },
{ 0x0dc7, 0x0e27 },
{ 0x0dc8, 0x0e28 },
{ 0x0dc9, 0x0e29 },
{ 0x0dca, 0x0e2a },
{ 0x0dcb, 0x0e2b },
{ 0x0dcc, 0x0e2c },
{ 0x0dcd, 0x0e2d },
{ 0x0dce, 0x0e2e },
{ 0x0dcf, 0x0e2f },
{ 0x0dd0, 0x0e30 },
{ 0x0dd1, 0x0e31 },
{ 0x0dd2, 0x0e32 },
{ 0x0dd3, 0x0e33 },
{ 0x0dd4, 0x0e34 },
{ 0x0dd5, 0x0e35 },
{ 0x0dd6, 0x0e36 },
{ 0x0dd7, 0x0e37 },
{ 0x0dd8, 0x0e38 },
{ 0x0dd9, 0x0e39 },
{ 0x0dda, 0x0e3a },
{ 0x0ddf, 0x0e3f },
{ 0x0de0, 0x0e40 },
{ 0x0de1, 0x0e41 },
{ 0x0de2, 0x0e42 },
{ 0x0de3, 0x0e43 },
{ 0x0de4, 0x0e44 },
{ 0x0de5, 0x0e45 },
{ 0x0de6, 0x0e46 },
{ 0x0de7, 0x0e47 },
{ 0x0de8, 0x0e48 },
{ 0x0de9, 0x0e49 },
{ 0x0dea, 0x0e4a },
{ 0x0deb, 0x0e4b },
{ 0x0dec, 0x0e4c },
{ 0x0ded, 0x0e4d },
{ 0x0df0, 0x0e50 },
{ 0x0df1, 0x0e51 },
{ 0x0df2, 0x0e52 },
{ 0x0df3, 0x0e53 },
{ 0x0df4, 0x0e54 },
{ 0x0df5, 0x0e55 },
{ 0x0df6, 0x0e56 },
{ 0x0df7, 0x0e57 },
{ 0x0df8, 0x0e58 },
{ 0x0df9, 0x0e59 },
{ 0x0ea1, 0x3131 },
{ 0x0ea2, 0x3132 },
{ 0x0ea3, 0x3133 },
{ 0x0ea4, 0x3134 },
{ 0x0ea5, 0x3135 },
{ 0x0ea6, 0x3136 },
{ 0x0ea7, 0x3137 },
{ 0x0ea8, 0x3138 },
{ 0x0ea9, 0x3139 },
{ 0x0eaa, 0x313a },
{ 0x0eab, 0x313b },
{ 0x0eac, 0x313c },
{ 0x0ead, 0x313d },
{ 0x0eae, 0x313e },
{ 0x0eaf, 0x313f },
{ 0x0eb0, 0x3140 },
{ 0x0eb1, 0x3141 },
{ 0x0eb2, 0x3142 },
{ 0x0eb3, 0x3143 },
{ 0x0eb4, 0x3144 },
{ 0x0eb5, 0x3145 },
{ 0x0eb6, 0x3146 },
{ 0x0eb7, 0x3147 },
{ 0x0eb8, 0x3148 },
{ 0x0eb9, 0x3149 },
{ 0x0eba, 0x314a },
{ 0x0ebb, 0x314b },
{ 0x0ebc, 0x314c },
{ 0x0ebd, 0x314d },
{ 0x0ebe, 0x314e },
{ 0x0ebf, 0x314f },
{ 0x0ec0, 0x3150 },
{ 0x0ec1, 0x3151 },
{ 0x0ec2, 0x3152 },
{ 0x0ec3, 0x3153 },
{ 0x0ec4, 0x3154 },
{ 0x0ec5, 0x3155 },
{ 0x0ec6, 0x3156 },
{ 0x0ec7, 0x3157 },
{ 0x0ec8, 0x3158 },
{ 0x0ec9, 0x3159 },
{ 0x0eca, 0x315a },
{ 0x0ecb, 0x315b },
{ 0x0ecc, 0x315c },
{ 0x0ecd, 0x315d },
{ 0x0ece, 0x315e },
{ 0x0ecf, 0x315f },
{ 0x0ed0, 0x3160 },
{ 0x0ed1, 0x3161 },
{ 0x0ed2, 0x3162 },
{ 0x0ed3, 0x3163 },
{ 0x0ed4, 0x11a8 },
{ 0x0ed5, 0x11a9 },
{ 0x0ed6, 0x11aa },
{ 0x0ed7, 0x11ab },
{ 0x0ed8, 0x11ac },
{ 0x0ed9, 0x11ad },
{ 0x0eda, 0x11ae },
{ 0x0edb, 0x11af },
{ 0x0edc, 0x11b0 },
{ 0x0edd, 0x11b1 },
{ 0x0ede, 0x11b2 },
{ 0x0edf, 0x11b3 },
{ 0x0ee0, 0x11b4 },
{ 0x0ee1, 0x11b5 },
{ 0x0ee2, 0x11b6 },
{ 0x0ee3, 0x11b7 },
{ 0x0ee4, 0x11b8 },
{ 0x0ee5, 0x11b9 },
{ 0x0ee6, 0x11ba },
{ 0x0ee7, 0x11bb },
{ 0x0ee8, 0x11bc },
{ 0x0ee9, 0x11bd },
{ 0x0eea, 0x11be },
{ 0x0eeb, 0x11bf },
{ 0x0eec, 0x11c0 },
{ 0x0eed, 0x11c1 },
{ 0x0eee, 0x11c2 },
{ 0x0eef, 0x316d },
{ 0x0ef0, 0x3171 },
{ 0x0ef1, 0x3178 },
{ 0x0ef2, 0x317f },
{ 0x0ef3, 0x3181 },
{ 0x0ef4, 0x3184 },
{ 0x0ef5, 0x3186 },
{ 0x0ef6, 0x318d },
{ 0x0ef7, 0x318e },
{ 0x0ef8, 0x11eb },
{ 0x0ef9, 0x11f0 },
{ 0x0efa, 0x11f9 },
{ 0x0eff, 0x20a9 },
{ 0x13a4, 0x20ac },
{ 0x13bc, 0x0152 },
{ 0x13bd, 0x0153 },
{ 0x13be, 0x0178 },
{ 0x20ac, 0x20ac },
// Numeric keypad with numlock on
{ XK_KP_Space, ' ' },
{ XK_KP_Equal, '=' },
{ XK_KP_Multiply, '*' },
{ XK_KP_Add, '+' },
{ XK_KP_Separator, ',' },
{ XK_KP_Subtract, '-' },
{ XK_KP_Decimal, '.' },
{ XK_KP_Divide, '/' },
{ XK_KP_0, 0x0030 },
{ XK_KP_1, 0x0031 },
{ XK_KP_2, 0x0032 },
{ XK_KP_3, 0x0033 },
{ XK_KP_4, 0x0034 },
{ XK_KP_5, 0x0035 },
{ XK_KP_6, 0x0036 },
{ XK_KP_7, 0x0037 },
{ XK_KP_8, 0x0038 },
{ XK_KP_9, 0x0039 }
};
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwKeySym2Unicode() - Convert X11 KeySym to Unicode
//========================================================================
long _glfwKeySym2Unicode( KeySym keysym )
{
int min = 0;
int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
int mid;
/* First check for Latin-1 characters (1:1 mapping) */
if( (keysym >= 0x0020 && keysym <= 0x007e) ||
(keysym >= 0x00a0 && keysym <= 0x00ff) )
{
return keysym;
}
/* Also check for directly encoded 24-bit UCS characters */
if( (keysym & 0xff000000) == 0x01000000 )
{
return keysym & 0x00ffffff;
}
/* Binary search in table */
while( max >= min )
{
mid = (min + max) / 2;
if( keysymtab[mid].keysym < keysym )
{
min = mid + 1;
}
else if( keysymtab[mid].keysym > keysym )
{
max = mid - 1;
}
else
{
/* Found it! */
return keysymtab[mid].ucs;
}
}
/* No matching Unicode value found */
return -1;
}

View File

@ -0,0 +1,507 @@
//========================================================================
// GLFW - An OpenGL framework
// File: x11_thread.c
// Platform: X11 (Unix)
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
#ifdef _GLFW_HAS_PTHREAD
//========================================================================
// _glfwNewThread() - This is simply a "wrapper" for calling the user
// thread function.
//========================================================================
void * _glfwNewThread( void * arg )
{
GLFWthreadfun threadfun;
_GLFWthread *t;
pthread_t posixID;
// Get current thread ID
posixID = pthread_self();
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Loop through entire list of threads to find the matching POSIX
// thread ID
for( t = &_glfwThrd.First; t != NULL; t = t->Next )
{
if( t->PosixID == posixID )
{
break;
}
}
if( t == NULL )
{
LEAVE_THREAD_CRITICAL_SECTION
return NULL;
}
// Get user thread function pointer
threadfun = t->Function;
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Call the user thread function
threadfun( arg );
// Remove thread from thread list
ENTER_THREAD_CRITICAL_SECTION
_glfwRemoveThread( t );
LEAVE_THREAD_CRITICAL_SECTION
// When the thread function returns, the thread will die...
return NULL;
}
#endif // _GLFW_HAS_PTHREAD
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformCreateThread() - Create a new thread
//========================================================================
GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )
{
#ifdef _GLFW_HAS_PTHREAD
GLFWthread ID;
_GLFWthread *t;
int result;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Create a new thread information memory area
t = (_GLFWthread *) malloc( sizeof(_GLFWthread) );
if( t == NULL )
{
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
return -1;
}
// Get a new unique thread id
ID = _glfwThrd.NextID ++;
// Store thread information in the thread list
t->Function = fun;
t->ID = ID;
// Create thread
result = pthread_create(
&t->PosixID, // Thread handle
NULL, // Default thread attributes
_glfwNewThread, // Thread function (a wrapper function)
(void *)arg // Argument to thread is user argument
);
// Did the thread creation fail?
if( result != 0 )
{
free( (void *) t );
LEAVE_THREAD_CRITICAL_SECTION
return -1;
}
// Append thread to thread list
_glfwAppendThread( t );
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Return the GLFW thread ID
return ID;
#else
return -1;
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY
// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME
// SITUATIONS!
//========================================================================
void _glfwPlatformDestroyThread( GLFWthread ID )
{
#ifdef _GLFW_HAS_PTHREAD
_GLFWthread *t;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Get thread information pointer
t = _glfwGetThreadPointer( ID );
if( t == NULL )
{
LEAVE_THREAD_CRITICAL_SECTION
return;
}
// Simply murder the process, no mercy!
pthread_kill( t->PosixID, SIGKILL );
// Remove thread from thread list
_glfwRemoveThread( t );
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformWaitThread() - Wait for a thread to die
//========================================================================
int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )
{
#ifdef _GLFW_HAS_PTHREAD
pthread_t thread;
_GLFWthread *t;
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Get thread information pointer
t = _glfwGetThreadPointer( ID );
// Is the thread already dead?
if( t == NULL )
{
LEAVE_THREAD_CRITICAL_SECTION
return GL_TRUE;
}
// If got this far, the thread is alive => polling returns FALSE
if( waitmode == GLFW_NOWAIT )
{
LEAVE_THREAD_CRITICAL_SECTION
return GL_FALSE;
}
// Get thread handle
thread = t->PosixID;
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Wait for thread to die
(void) pthread_join( thread, NULL );
return GL_TRUE;
#else
return GL_TRUE;
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformGetThreadID() - Return the thread ID for the current
// thread
//========================================================================
GLFWthread _glfwPlatformGetThreadID( void )
{
#ifdef _GLFW_HAS_PTHREAD
_GLFWthread *t;
GLFWthread ID = -1;
pthread_t posixID;
// Get current thread ID
posixID = pthread_self();
// Enter critical section
ENTER_THREAD_CRITICAL_SECTION
// Loop through entire list of threads to find the matching POSIX
// thread ID
for( t = &_glfwThrd.First; t != NULL; t = t->Next )
{
if( t->PosixID == posixID )
{
ID = t->ID;
break;
}
}
// Leave critical section
LEAVE_THREAD_CRITICAL_SECTION
// Return the found GLFW thread identifier
return ID;
#else
return 0;
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformCreateMutex() - Create a mutual exclusion object
//========================================================================
GLFWmutex _glfwPlatformCreateMutex( void )
{
#ifdef _GLFW_HAS_PTHREAD
pthread_mutex_t *mutex;
// Allocate memory for mutex
mutex = (pthread_mutex_t *) malloc( sizeof( pthread_mutex_t ) );
if( !mutex )
{
return NULL;
}
// Initialise a mutex object
(void) pthread_mutex_init( mutex, NULL );
// Cast to GLFWmutex and return
return (GLFWmutex) mutex;
#else
return (GLFWmutex) 0;
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformDestroyMutex() - Destroy a mutual exclusion object
//========================================================================
void _glfwPlatformDestroyMutex( GLFWmutex mutex )
{
#ifdef _GLFW_HAS_PTHREAD
// Destroy the mutex object
pthread_mutex_destroy( (pthread_mutex_t *) mutex );
// Free memory for mutex object
free( (void *) mutex );
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformLockMutex() - Request access to a mutex
//========================================================================
void _glfwPlatformLockMutex( GLFWmutex mutex )
{
#ifdef _GLFW_HAS_PTHREAD
// Wait for mutex to be released
(void) pthread_mutex_lock( (pthread_mutex_t *) mutex );
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformUnlockMutex() - Release a mutex
//========================================================================
void _glfwPlatformUnlockMutex( GLFWmutex mutex )
{
#ifdef _GLFW_HAS_PTHREAD
// Release mutex
pthread_mutex_unlock( (pthread_mutex_t *) mutex );
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformCreateCond() - Create a new condition variable object
//========================================================================
GLFWcond _glfwPlatformCreateCond( void )
{
#ifdef _GLFW_HAS_PTHREAD
pthread_cond_t *cond;
// Allocate memory for condition variable
cond = (pthread_cond_t *) malloc( sizeof(pthread_cond_t) );
if( !cond )
{
return NULL;
}
// Initialise condition variable
(void) pthread_cond_init( cond, NULL );
// Cast to GLFWcond and return
return (GLFWcond) cond;
#else
return (GLFWcond) 0;
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformDestroyCond() - Destroy a condition variable object
//========================================================================
void _glfwPlatformDestroyCond( GLFWcond cond )
{
#ifdef _GLFW_HAS_PTHREAD
// Destroy the condition variable object
(void) pthread_cond_destroy( (pthread_cond_t *) cond );
// Free memory for condition variable object
free( (void *) cond );
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformWaitCond() - Wait for a condition to be raised
//========================================================================
void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,
double timeout )
{
#ifdef _GLFW_HAS_PTHREAD
struct timeval currenttime;
struct timespec wait;
long dt_sec, dt_usec;
// Select infinite or timed wait
if( timeout >= GLFW_INFINITY )
{
// Wait for condition (infinite wait)
(void) pthread_cond_wait( (pthread_cond_t *) cond,
(pthread_mutex_t *) mutex );
}
else
{
// Set timeout time, relatvie to current time
gettimeofday( &currenttime, NULL );
dt_sec = (long) timeout;
dt_usec = (long) ((timeout - (double)dt_sec) * 1000000.0);
wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;
if( wait.tv_nsec > 1000000000L )
{
wait.tv_nsec -= 1000000000L;
dt_sec ++;
}
wait.tv_sec = currenttime.tv_sec + dt_sec;
// Wait for condition (timed wait)
(void) pthread_cond_timedwait( (pthread_cond_t *) cond,
(pthread_mutex_t *) mutex, &wait );
}
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformSignalCond() - Signal a condition to one waiting thread
//========================================================================
void _glfwPlatformSignalCond( GLFWcond cond )
{
#ifdef _GLFW_HAS_PTHREAD
// Signal condition
(void) pthread_cond_signal( (pthread_cond_t *) cond );
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting
// threads
//========================================================================
void _glfwPlatformBroadcastCond( GLFWcond cond )
{
#ifdef _GLFW_HAS_PTHREAD
// Broadcast condition
(void) pthread_cond_broadcast( (pthread_cond_t *) cond );
#endif // _GLFW_HAS_PTHREAD
}
//========================================================================
// _glfwPlatformGetNumberOfProcessors() - Return the number of processors
// in the system.
//========================================================================
int _glfwPlatformGetNumberOfProcessors( void )
{
int n;
// Get number of processors online
_glfw_numprocessors( n );
return n;
}

View File

@ -0,0 +1,154 @@
//========================================================================
// GLFW - An OpenGL framework
// File: x11_time.c
// Platform: X11 (Unix)
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//========================================================================
// Initialise timer
//========================================================================
void _glfwInitTimer( void )
{
struct timeval tv;
// "Resolution" is 1 us
_glfwLibrary.Timer.Resolution = 1e-6;
// Set start-time for timer
gettimeofday( &tv, NULL );
_glfwLibrary.Timer.t0 = (long long) tv.tv_sec * (long long) 1000000 +
(long long) tv.tv_usec;
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// Return timer value in seconds
//========================================================================
double _glfwPlatformGetTime( void )
{
long long t;
struct timeval tv;
gettimeofday( &tv, NULL );
t = (long long) tv.tv_sec * (long long) 1000000 +
(long long) tv.tv_usec;
return (double)(t - _glfwLibrary.Timer.t0) * _glfwLibrary.Timer.Resolution;
}
//========================================================================
// Set timer value in seconds
//========================================================================
void _glfwPlatformSetTime( double t )
{
long long t0;
struct timeval tv;
gettimeofday( &tv, NULL );
t0 = (long long) tv.tv_sec * (long long) 1000000 +
(long long) tv.tv_usec;
// Calulate new starting time
_glfwLibrary.Timer.t0 = t0 - (long long)(t/_glfwLibrary.Timer.Resolution);
}
//========================================================================
// Put a thread to sleep for a specified amount of time
//========================================================================
void _glfwPlatformSleep( double time )
{
#ifdef _GLFW_HAS_PTHREAD
if( time == 0.0 )
{
#ifdef _GLFW_HAS_SCHED_YIELD
sched_yield();
#endif
return;
}
struct timeval currenttime;
struct timespec wait;
pthread_mutex_t mutex;
pthread_cond_t cond;
long dt_sec, dt_usec;
// Not all pthread implementations have a pthread_sleep() function. We
// do it the portable way, using a timed wait for a condition that we
// will never signal. NOTE: The unistd functions sleep/usleep suspends
// the entire PROCESS, not a signle thread, which is why we can not
// use them to implement glfwSleep.
// Set timeout time, relatvie to current time
gettimeofday( &currenttime, NULL );
dt_sec = (long) time;
dt_usec = (long) ((time - (double)dt_sec) * 1000000.0);
wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;
if( wait.tv_nsec > 1000000000L )
{
wait.tv_nsec -= 1000000000L;
dt_sec++;
}
wait.tv_sec = currenttime.tv_sec + dt_sec;
// Initialize condition and mutex objects
pthread_mutex_init( &mutex, NULL );
pthread_cond_init( &cond, NULL );
// Do a timed wait
pthread_mutex_lock( &mutex );
pthread_cond_timedwait( &cond, &mutex, &wait );
pthread_mutex_unlock( &mutex );
// Destroy condition and mutex objects
pthread_mutex_destroy( &mutex );
pthread_cond_destroy( &cond );
#else
// For systems without PTHREAD, use unistd usleep
if( time > 0 )
{
usleep( (unsigned int) (time*1000000) );
}
#endif // _GLFW_HAS_PTHREAD
}

File diff suppressed because it is too large Load Diff

31
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,31 @@
# find external software
find_package(OpenGL)
# set includes
include_directories (${GREMLIN_SOURCE_DIR}/libs/glfw/include)
include_directories (${GREMLIN_SOURCE_DIR}/libs/enet/include)
include_directories (${GREMLIN_SOURCE_DIR}/src)
# define executable
add_executable( gremlin
main.cpp
)
# set dependencies
add_dependencies( gremlin
glfw enet
)
if (WIN32)
set(PLATFORM_LIBRARIES ws2_32 winmm)
endif(WIN32)
if(UNIX)
set(PLATFORM_LIBRARIES GL X11 Xrandr -pthread)
endif(UNIX)
target_link_libraries(gremlin
glfw enet ${OPENGL_LIBRARY} ${PLATFORM_LIBRARIES}
)

225
src/main.cpp Normal file
View File

@ -0,0 +1,225 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glfw.h>
#define MAX_PLAYERS_PER_TEAM 8
#define MAX_TEAMS 8
typedef struct _player {
unsigned int session;
double x, y, z;
double rx, ry, rz, rw;
double vx, vy, vz;
} player;
typedef struct _team {
player players[MAX_PLAYERS_PER_TEAM];
double x, y, z;
GLfloat color[4];
} team;
GLUquadricObj *quadratic;
void setup_opengl()
{
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
exit( EXIT_FAILURE );
}
// Open OpenGL window
if( !glfwOpenWindow( 640, 480, 0,0,0,0, 0,0, GLFW_FULLSCREEN ) )
{
fprintf( stderr, "Failed to open GLFW window\n" );
glfwTerminate();
exit( EXIT_FAILURE );
}
glfwDisable(GLFW_MOUSE_CURSOR);
glfwSetWindowTitle( "Trilinear interpolation" );
// Enable sticky keys
glfwEnable( GLFW_STICKY_KEYS );
// general settings
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_CULL_FACE);
// setup depth buffer
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
GLfloat LightAmbient[]= { 0.1f, 0.1f, 0.1f, 1.0f };
GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 0.0f };
// setup directional light
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
// Enable vertical sync (on cards that support it)
glfwSwapInterval( 1 );
}
void setup_team(team *team, size_t id)
{
team->color[0] = 1.0f * (id+1 & (1 << 0));
team->color[1] = 1.0f * (id+1 & (1 << 1));
team->color[2] = 1.0f * (id+1 & (1 << 2));
team->color[3] = 1.0f;
team->x = 2000.0 * (id & (1 << 0));
team->y = 2000.0 * (id & (1 << 1));
team->z = 2000.0 * (id & (1 << 2));
size_t i = 0;
for (i = 0; i < MAX_PLAYERS_PER_TEAM; i++)
{
team->players[i].session = 0;
team->players[i].x = team->x + i * 50.;
team->players[i].y = team->y;
team->players[i].z = team->z;
team->players[i].vx = i * 5.;
team->players[i].vy = i * 5.;
team->players[i].vz = i * 5.;
}
}
void update_team(team *team, double dt)
{
size_t i;
for (i = 0; i < MAX_PLAYERS_PER_TEAM; i++)
{
if (team->players[i].session == 0)
continue;
team->players[i].x += team->players[i].vx * dt;
team->players[i].y += team->players[i].vy * dt;
team->players[i].z += team->players[i].vz * dt;
}
}
void draw_team(team *team)
{
size_t i = 0;
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, team->color);
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glTranslated(team->x, team->y, team->z);
gluSphere(quadratic,50.f,32,32);
glPopMatrix();
for (i = 0; i < MAX_PLAYERS_PER_TEAM; i++)
{
if (team->players[i].session == 0)
continue;
glPushMatrix();
glTranslated(team->players[i].x, team->players[i].y, team->players[i].z);
gluSphere(quadratic,10.f,32,32);
glPopMatrix();
}
}
int main( void )
{
int width, height, x, y, last_x, last_y;
double time, last_time, phi = 0.0, theta = 0.0;
GLboolean running;
quadratic = gluNewQuadric();
gluQuadricNormals(quadratic, GLU_SMOOTH);
gluQuadricTexture(quadratic, GL_TRUE);
team teams[MAX_TEAMS];
setup_opengl();
size_t i;
for (i = 0; i < MAX_TEAMS; i++)
setup_team(&teams[i], i);
running = GL_TRUE;
last_time = glfwGetTime();
glfwGetMousePos( &last_x, &last_y );
while( running )
{
// Get time and mouse position
time = glfwGetTime();
glfwGetMousePos( &x, &y );
phi += (x - last_x) * -0.001;
theta += (y - last_y) * 0.001;
if (theta > 1.5)
theta = 1.5;
if (theta < -1.5)
theta = -1.5;
last_x = x;
last_y = y;
// Get window size (may be different than the requested size)
glfwGetWindowSize( &width, &height );
height = height > 0 ? height : 1;
// Set viewport
glViewport( 0, 0, width, height );
// Clear color buffer
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Select and setup the projection matrix
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60.0f, (GLfloat)width / (GLfloat)height, 1.0f,
10000.0f );
// Select and setup the modelview matrix
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt( 100.0f, 100.0f, 100.0f, // Eye-position
100.0f + cos(phi) * cos(theta) * 10.0f, 100.0f +sin(theta)*10.0f, 100.0f+ sin(phi)*cos(theta)*10.0f, // View-point
0.0f, 1.0f, 0.0f ); // Up-vector
// Draw a textured quad
glBegin( GL_QUADS );
glVertex3f( -5000.0f, 5000.0f, -5000.0f );
glVertex3f( 5000.0f, 5000.0f, -5000.0f );
glVertex3f( 5000.0f, 5000.0f, 5000.0f );
glVertex3f( -5000.0f, 5000.0f, 5000.0f );
glEnd();
for (i = 0; i < MAX_TEAMS; i++)
update_team(&teams[i], time-last_time);
for (i = 0; i < MAX_TEAMS; i++)
draw_team(&teams[i]);
// Swap buffers
glfwSwapBuffers();
// Check if the ESC key was pressed or the window was closed
running = !glfwGetKey( GLFW_KEY_ESC ) &&
glfwGetWindowParam( GLFW_OPENED );
last_time = time;
}
gluDeleteQuadric(quadratic);
// Close OpenGL window and terminate GLFW
glfwTerminate();
exit( EXIT_SUCCESS );
}