320 lines
9.9 KiB
C
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 );
|
||
|
}
|