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

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_