gremlin/libs/glfw/lib/amigaos/amigaos_fullscreen.c
2011-01-04 18:11:59 +01:00

320 lines
9.9 KiB
C

//========================================================================
// 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 );
}