From 3902165c9649684f898f98988029a20a92752d1a Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 25 Dec 2022 16:37:58 +0000 Subject: [PATCH] Add initial O3DEngine and O3DRenderer Only supports querying resolutions so far. FossilOrigin-Name: c504ea5dd9a25bfe49c16f256d64f3bf8c16fc78fa03c2cad2561fbbb10eb720 --- src/Makefile | 3 + src/O3DEngine.h | 36 ++++++++ src/O3DEngine.m | 49 +++++++++++ src/O3DGlide3Renderer.h | 23 +++++ src/O3DGlide3Renderer.m | 178 +++++++++++++++++++++++++++++++++++++++ src/O3DRenderer.h | 37 ++++++++ src/O3DRenderer.m | 18 ++++ tests/TestsAppDelegate.m | 11 +++ 8 files changed, 355 insertions(+) create mode 100644 src/O3DEngine.h create mode 100644 src/O3DEngine.m create mode 100644 src/O3DGlide3Renderer.h create mode 100644 src/O3DGlide3Renderer.m create mode 100644 src/O3DRenderer.h create mode 100644 src/O3DRenderer.m diff --git a/src/Makefile b/src/Makefile index cba7528..0f50e18 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,6 +8,9 @@ FRAMEWORK = ${OBJ3DENGINE_FRAMEWORK} LIB_MAJOR = ${OBJ3DENGINE_LIB_MAJOR} LIB_MINOR = ${OBJ3DENGINE_LIB_MINOR} +SRCS = O3DEngine.m \ + O3DGlide3Renderer.m \ + O3DRenderer.m INCLUDES := ${SRCS:.m=.h} OBJS_EXTRA = ${EXCEPTIONS_EXCEPTIONS_A} diff --git a/src/O3DEngine.h b/src/O3DEngine.h new file mode 100644 index 0000000..cf0947d --- /dev/null +++ b/src/O3DEngine.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 Jonathan Schleifer + * + * 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. + */ + +#import + +#import "O3DRenderer.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface O3DEngine: OFObject +{ + id _renderer; +} + +@property (readonly, nonatomic) id renderer; + ++ (OFArray OF_GENERIC(Class ) *)availableRenderers; + +- (instancetype)initWithRenderer: (Class )renderer + options: (nullable OFDictionary + OF_GENERIC(OFString *, id) *)options; +@end + +OF_ASSUME_NONNULL_END diff --git a/src/O3DEngine.m b/src/O3DEngine.m new file mode 100644 index 0000000..06a1337 --- /dev/null +++ b/src/O3DEngine.m @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Jonathan Schleifer + * + * 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. + */ + +#import "O3DEngine.h" +#import "O3DGlide3Renderer.h" + +@implementation O3DEngine +@synthesize renderer = _renderer; + ++ (OFArray OF_GENERIC(Class ) *)availableRenderers +{ + return [OFArray arrayWithObject: [O3DGlide3Renderer class]]; +} + +- (instancetype) + initWithRenderer: (Class )renderer + options: (OFDictionary OF_GENERIC(OFString *, id) *)options +{ + self = [super init]; + + @try { + _renderer = [[renderer alloc] initWithOptions: options]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_renderer release]; + + [super dealloc]; +} +@end diff --git a/src/O3DGlide3Renderer.h b/src/O3DGlide3Renderer.h new file mode 100644 index 0000000..08cc110 --- /dev/null +++ b/src/O3DGlide3Renderer.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 Jonathan Schleifer + * + * 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. + */ + +#import "O3DRenderer.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface O3DGlide3Renderer: OFObject +@end + +OF_ASSUME_NONNULL_END diff --git a/src/O3DGlide3Renderer.m b/src/O3DGlide3Renderer.m new file mode 100644 index 0000000..3e000a5 --- /dev/null +++ b/src/O3DGlide3Renderer.m @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2022 Jonathan Schleifer + * + * 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 + +#import "O3DGlide3Renderer.h" + +static OFSize +resolutionToSize(GrScreenResolution_t resolution) +{ + switch (resolution) { + case GR_RESOLUTION_320x200: + return OFMakeSize(320, 200); + case GR_RESOLUTION_320x240: + return OFMakeSize(320, 240); + case GR_RESOLUTION_400x256: + return OFMakeSize(400, 256); + case GR_RESOLUTION_512x384: + return OFMakeSize(512, 384); + case GR_RESOLUTION_640x200: + return OFMakeSize(640, 200); + case GR_RESOLUTION_640x350: + return OFMakeSize(640, 350); + case GR_RESOLUTION_640x400: + return OFMakeSize(640, 400); + case GR_RESOLUTION_640x480: + return OFMakeSize(640, 480); + case GR_RESOLUTION_800x600: + return OFMakeSize(800, 600); + case GR_RESOLUTION_960x720: + return OFMakeSize(960, 720); + case GR_RESOLUTION_856x480: + return OFMakeSize(856, 480); + case GR_RESOLUTION_512x256: + return OFMakeSize(512, 256); + case GR_RESOLUTION_1024x768: + return OFMakeSize(1024, 768); + case GR_RESOLUTION_1280x1024: + return OFMakeSize(1280, 1024); + case GR_RESOLUTION_1600x1200: + return OFMakeSize(1600, 1200); + case GR_RESOLUTION_400x300: + return OFMakeSize(400, 300); + case GR_RESOLUTION_1152x864: + return OFMakeSize(1152, 864); + case GR_RESOLUTION_1280x960: + return OFMakeSize(1280, 960); + case GR_RESOLUTION_1600x1024: + return OFMakeSize(1600, 1024); + case GR_RESOLUTION_1792x1344: + return OFMakeSize(1792, 1344); + case GR_RESOLUTION_1856x1392: + return OFMakeSize(1856, 1392); + case GR_RESOLUTION_1920x1440: + return OFMakeSize(1920, 1440); + case GR_RESOLUTION_2048x1536: + return OFMakeSize(2048, 1536); + case GR_RESOLUTION_2048x2048: + return OFMakeSize(2048, 2048); + default: + return OFMakeSize(0, 0); + } +} + +static float +refreshEnumToFloat(GrScreenRefresh_t refresh) +{ + switch (refresh) { + case GR_REFRESH_60Hz: + return 60; + case GR_REFRESH_70Hz: + return 70; + case GR_REFRESH_72Hz: + return 72; + case GR_REFRESH_75Hz: + return 75; + case GR_REFRESH_80Hz: + return 80; + case GR_REFRESH_90Hz: + return 90; + case GR_REFRESH_100Hz: + return 100; + case GR_REFRESH_85Hz: + return 85; + case GR_REFRESH_120Hz: + return 120; + default: + return 0; + } +} + +@implementation O3DGlide3Renderer +- (instancetype)initWithOptions: + (OFDictionary OF_GENERIC(OFString *, id) *)options +{ + self = [super init]; + + @try { + long long deviceIndex = [[options objectForKey: + O3DRendererDeviceIndex] longLongValue]; + FxI32 numDevices; + + grGlideInit(); + + if (!grGet(GR_NUM_BOARDS, sizeof(numDevices), &numDevices)) + @throw [OFInitializationFailedException exception]; + + if (deviceIndex > numDevices) + @throw [OFInvalidArgumentException exception]; + + grSstSelect((int)deviceIndex); + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + grGlideShutdown(); + + [super dealloc]; +} + +- (OFSet OF_GENERIC(OFPair OF_GENERIC(OFValue *, OFNumber *) *) *) + availableResolutions +{ + OFMutableSet *ret = [OFMutableSet set]; + GrResolution *resolutions; + GrResolution query = { + .resolution = GR_QUERY_ANY, + .refresh = GR_QUERY_ANY, + .numColorBuffers = GR_QUERY_ANY, + .numAuxBuffers = 1 + }; + size_t size = grQueryResolutions(&query, NULL); + + resolutions = OFAllocMemory(1, size); + @try { + void *pool; + size = grQueryResolutions(&query, resolutions); + + pool = objc_autoreleasePoolPush(); + + for (size_t i = 0; i < size / sizeof(*resolutions); i++) { + OFValue *resolution = [OFValue valueWithSize: + resolutionToSize(resolutions[i].resolution)]; + OFNumber *refresh = [OFNumber numberWithFloat: + refreshEnumToFloat(resolutions[i].refresh)]; + + [ret addObject: [OFPair pairWithFirstObject: resolution + secondObject: refresh]]; + } + + objc_autoreleasePoolPop(pool); + } @finally { + OFFreeMemory(resolutions); + } + + [ret makeImmutable]; + + return ret; +} +@end diff --git a/src/O3DRenderer.h b/src/O3DRenderer.h new file mode 100644 index 0000000..3e2b7ed --- /dev/null +++ b/src/O3DRenderer.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Jonathan Schleifer + * + * 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. + */ + +#import + +OF_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif +extern OFString *const O3DRendererDeviceIndex; +#ifdef __cplusplus +} +#endif + +@protocol O3DRenderer +@property (readonly, nonatomic) OFSet OF_GENERIC(OFPair OF_GENERIC(OFValue *, + OFNumber *) *) *availableResolutions; + ++ (instancetype)alloc; +- (instancetype)initWithOptions: + (nullable OFDictionary OF_GENERIC(OFString *, id) *)options; +@end + +OF_ASSUME_NONNULL_END diff --git a/src/O3DRenderer.m b/src/O3DRenderer.m new file mode 100644 index 0000000..af3c071 --- /dev/null +++ b/src/O3DRenderer.m @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2022 Jonathan Schleifer + * + * 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. + */ + +#import "O3DRenderer.h" + +OFString *const O3DRendererDeviceIndex = @"O3DRendererDeviceIndex"; diff --git a/tests/TestsAppDelegate.m b/tests/TestsAppDelegate.m index fb030e3..7f1219c 100644 --- a/tests/TestsAppDelegate.m +++ b/tests/TestsAppDelegate.m @@ -15,6 +15,8 @@ #import +#import "O3DEngine.h" + @interface TestsAppDelegate: OFObject @end @@ -23,6 +25,15 @@ OF_APPLICATION_DELEGATE(TestsAppDelegate) @implementation TestsAppDelegate - (void)applicationDidFinishLaunching: (OFNotification *)notification { + Class renderer = + [O3DEngine availableRenderers].firstObject; + O3DEngine *engine = + [[[O3DEngine alloc] initWithRenderer: renderer + options: nil] autorelease]; + + [OFStdOut writeFormat: @"Available resolutions: %@", + engine.renderer.availableResolutions]; + [OFApplication terminate]; } @end