Backport to Glide 2
Most games were using Glide 2, meaning there is more wrappers for Glide 2 available than for Glide 3. In particular, it seems there is no open source Glide 3 wrapper. FossilOrigin-Name: 16bb6bc399e5b4db4f5117199f6b534231c42072555575b70f40795651805648
This commit is contained in:
parent
c322610fe4
commit
4ea8389306
10 changed files with 255 additions and 543 deletions
228
src/O3DGlideRenderer.m
Normal file
228
src/O3DGlideRenderer.m
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Jonathan Schleifer <js@nil.im>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of Obj3DEngine. It may be distributed under the terms of
|
||||
* the Q Public License 1.0, which can be found in the file LICENSE.QPL
|
||||
* included in the packaging of this file.
|
||||
*
|
||||
* Alternatively, it may be distributed under the terms of the GNU General
|
||||
* Public License, either version 2 or 3, which can be found in the file
|
||||
* LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of
|
||||
* this file.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#import "O3DGlideRenderer.h"
|
||||
#import "O3DWinAPIWindow.h"
|
||||
|
||||
static GrScreenResolution_t
|
||||
sizeToScreenResolution(OFSize size)
|
||||
{
|
||||
if (size.width == 320 && size.height == 200)
|
||||
return GR_RESOLUTION_320x200;
|
||||
if (size.width == 320 && size.height == 240)
|
||||
return GR_RESOLUTION_320x240;
|
||||
if (size.width == 400 && size.height == 256)
|
||||
return GR_RESOLUTION_400x256;
|
||||
if (size.width == 512 && size.height == 384)
|
||||
return GR_RESOLUTION_512x384;
|
||||
if (size.width == 640 && size.height == 200)
|
||||
return GR_RESOLUTION_640x200;
|
||||
if (size.width == 640 && size.height == 350)
|
||||
return GR_RESOLUTION_640x350;
|
||||
if (size.width == 640 && size.height == 400)
|
||||
return GR_RESOLUTION_640x400;
|
||||
if (size.width == 640 && size.height == 480)
|
||||
return GR_RESOLUTION_640x480;
|
||||
if (size.width == 800 && size.height == 600)
|
||||
return GR_RESOLUTION_800x600;
|
||||
if (size.width == 960 && size.height == 720)
|
||||
return GR_RESOLUTION_960x720;
|
||||
if (size.width == 856 && size.height == 480)
|
||||
return GR_RESOLUTION_856x480;
|
||||
if (size.width == 512 && size.height == 256)
|
||||
return GR_RESOLUTION_512x256;
|
||||
if (size.width == 1024 && size.height == 768)
|
||||
return GR_RESOLUTION_1024x768;
|
||||
if (size.width == 1280 && size.height == 1024)
|
||||
return GR_RESOLUTION_1280x1024;
|
||||
if (size.width == 1600 && size.height == 1200)
|
||||
return GR_RESOLUTION_1600x1200;
|
||||
if (size.width == 400 && size.height == 300)
|
||||
return GR_RESOLUTION_400x300;
|
||||
if (size.width == 1152 && size.height == 864)
|
||||
return GR_RESOLUTION_1152x864;
|
||||
if (size.width == 1280 && size.height == 960)
|
||||
return GR_RESOLUTION_1280x960;
|
||||
if (size.width == 1600 && size.height == 1024)
|
||||
return GR_RESOLUTION_1600x1024;
|
||||
if (size.width == 1792 && size.height == 1344)
|
||||
return GR_RESOLUTION_1792x1344;
|
||||
if (size.width == 1856 && size.height == 1392)
|
||||
return GR_RESOLUTION_1856x1392;
|
||||
if (size.width == 1920 && size.height == 1440)
|
||||
return GR_RESOLUTION_1920x1440;
|
||||
if (size.width == 2048 && size.height == 1536)
|
||||
return GR_RESOLUTION_2048x1536;
|
||||
if (size.width == 2048 && size.height == 2048)
|
||||
return GR_RESOLUTION_2048x2048;
|
||||
|
||||
@throw [OFInvalidArgumentException exception];
|
||||
}
|
||||
|
||||
static GrScreenRefresh_t
|
||||
floatToScreenRefresh(float refresh)
|
||||
{
|
||||
if (refresh == 60)
|
||||
return GR_REFRESH_60Hz;
|
||||
if (refresh == 70)
|
||||
return GR_REFRESH_70Hz;
|
||||
if (refresh == 72)
|
||||
return GR_REFRESH_72Hz;
|
||||
if (refresh == 75)
|
||||
return GR_REFRESH_75Hz;
|
||||
if (refresh == 80)
|
||||
return GR_REFRESH_80Hz;
|
||||
if (refresh == 90)
|
||||
return GR_REFRESH_90Hz;
|
||||
if (refresh == 100)
|
||||
return GR_REFRESH_100Hz;
|
||||
if (refresh == 85)
|
||||
return GR_REFRESH_85Hz;
|
||||
if (refresh == 120)
|
||||
return GR_REFRESH_120Hz;
|
||||
|
||||
@throw [OFInvalidArgumentException exception];
|
||||
}
|
||||
|
||||
@implementation O3DGlideRenderer
|
||||
@synthesize syncsToVerticalBlank = _syncsToVerticalBlank;
|
||||
|
||||
static void
|
||||
grGlideShutdownCdecl(void)
|
||||
{
|
||||
grGlideShutdown();
|
||||
}
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self != [O3DGlideRenderer class])
|
||||
return;
|
||||
|
||||
grGlideInit();
|
||||
atexit(grGlideShutdownCdecl);
|
||||
}
|
||||
|
||||
+ (unsigned int)numAvailableDevices
|
||||
{
|
||||
GrHwConfiguration config;
|
||||
if (!grSstQueryHardware(&config))
|
||||
return 0;
|
||||
|
||||
if (config.num_sst < 0)
|
||||
return 0;
|
||||
|
||||
return (unsigned int)config.num_sst;
|
||||
}
|
||||
|
||||
- (instancetype)initWithResolution: (OFSize)resolution
|
||||
bitsPerPixel: (uint8_t)bitsPerPixel
|
||||
refreshRate: (float)refreshRate
|
||||
options: (nullable OFDictionary *)options
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
@try {
|
||||
if (bitsPerPixel != 16)
|
||||
@throw [OFInvalidArgumentException exception];
|
||||
|
||||
long long deviceIndex = [[options objectForKey:
|
||||
O3DRendererDeviceIndex] longLongValue];
|
||||
if (deviceIndex > [self.class numAvailableDevices])
|
||||
@throw [OFInvalidArgumentException exception];
|
||||
|
||||
grSstSelect((int)deviceIndex);
|
||||
|
||||
FxU32 hWnd = 0;
|
||||
#ifdef OF_WINDOWS
|
||||
_winAPIWindow = [[O3DWinAPIWindow alloc]
|
||||
initWithSize: resolution];
|
||||
hWnd = (FxU32)_winAPIWindow.hWnd;
|
||||
#endif
|
||||
|
||||
if (!grSstWinOpen(hWnd, sizeToScreenResolution(resolution),
|
||||
floatToScreenRefresh(refreshRate), GR_COLORFORMAT_RGBA,
|
||||
GR_ORIGIN_LOWER_LEFT, 2, 1))
|
||||
@throw [OFInitializationFailedException
|
||||
exceptionWithClass: self.class];
|
||||
} @catch (id e) {
|
||||
[self release];
|
||||
@throw e;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
grSstWinClose();
|
||||
|
||||
#ifdef OF_WINDOWS
|
||||
[_winAPIWindow release];
|
||||
#endif
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)beginFrame
|
||||
{
|
||||
grBufferClear(0, 0, 0);
|
||||
}
|
||||
|
||||
- (void)setColor: (OFColor *)color
|
||||
{
|
||||
float values[4];
|
||||
[color getRed: &values[0]
|
||||
green: &values[1]
|
||||
blue: &values[2]
|
||||
alpha: &values[3]];
|
||||
for (uint_fast8_t i = 0; i < 4; i++)
|
||||
values[i] *= 255;
|
||||
grColorCombine(GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,
|
||||
GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE, FXFALSE);
|
||||
grConstantColorValue((((GrColor_t)values[0]) << 24) |
|
||||
(((GrColor_t)values[1]) << 16) | (((GrColor_t)values[2]) << 8) |
|
||||
(GrColor_t)values[2]);
|
||||
}
|
||||
|
||||
- (void)drawPolygonVertices: (const O3DVertex *)vertices count: (size_t)count
|
||||
{
|
||||
/*
|
||||
* Range is -1 to 1, we add 1, so we get 0 to 2 - so we need to
|
||||
* multiply with half the width / height.
|
||||
*/
|
||||
float halfWidth = grSstScreenWidth() / 2;
|
||||
float halfHeight = grSstScreenHeight() / 2;
|
||||
|
||||
GrVertex *glideVertices = OFAllocMemory(count, sizeof(GrVertex));
|
||||
@try {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
glideVertices[i].x = (vertices[i].x + 1) * halfWidth;
|
||||
glideVertices[i].y = (vertices[i].y + 1) * halfHeight;
|
||||
}
|
||||
|
||||
grDrawPolygonVertexList((int)count, glideVertices);
|
||||
} @finally {
|
||||
OFFreeMemory(glideVertices);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)endFrame
|
||||
{
|
||||
grBufferSwap(_syncsToVerticalBlank ? 1 : 0);
|
||||
}
|
||||
@end
|
Loading…
Add table
Add a link
Reference in a new issue