From 7953872267290612ebf6dd76181d3b6113c89bec Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 19 Aug 2012 23:53:47 +0200 Subject: [PATCH] Initial import. --- Makefile | 8 ++ src/Makefile | 7 ++ src/OGKDisplay.h | 37 +++++++++ src/OGKDisplay.m | 82 ++++++++++++++++++++ src/OGKEvent.h | 67 +++++++++++++++++ src/OGKEvent.m | 81 ++++++++++++++++++++ src/OGKEventQueue.h | 55 ++++++++++++++ src/OGKEventQueue.m | 177 ++++++++++++++++++++++++++++++++++++++++++++ test/Makefile | 7 ++ test/TestMain.h | 32 ++++++++ test/TestMain.m | 94 +++++++++++++++++++++++ 11 files changed, 647 insertions(+) create mode 100644 Makefile create mode 100644 src/Makefile create mode 100644 src/OGKDisplay.h create mode 100644 src/OGKDisplay.m create mode 100644 src/OGKEvent.h create mode 100644 src/OGKEvent.m create mode 100644 src/OGKEventQueue.h create mode 100644 src/OGKEventQueue.m create mode 100644 test/Makefile create mode 100644 test/TestMain.h create mode 100644 test/TestMain.m diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d1b86cb --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +all: + @cd src && ${MAKE} ${MFLAGS} + @cd test && ${MAKE} ${MFLAGS} + +clean: + @cd src && ${MAKE} ${MFLAGS} clean + @cd test && ${MAKE} ${MFLAGS} clean + @rm -f *~ diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..8b13c4a --- /dev/null +++ b/src/Makefile @@ -0,0 +1,7 @@ +all: + @mkdir -p build + @objfw-compile --lib 0.0 -o objgamekit --builddir build *.m \ + --arc `pkg-config --cflags --libs allegro-5.0 allegro_main-5.0` + +clean: + @rm -fr build libobjgamekit.* *~ diff --git a/src/OGKDisplay.h b/src/OGKDisplay.h new file mode 100644 index 0000000..56a49e7 --- /dev/null +++ b/src/OGKDisplay.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012 Jonathan Schleifer + * + * 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 + +#import + +@interface OGKDisplay: OFObject +{ + ALLEGRO_DISPLAY *display; +} + ++ displayWithSize: (of_dimension_t)size + fullscreen: (BOOL)fullscreen + resizable: (BOOL)resizable; +- initWithSize: (of_dimension_t)size + fullscreen: (BOOL)fullscreen + resizable: (BOOL)resizable; +- (ALLEGRO_DISPLAY*)OGK_allegroDisplay; +@end diff --git a/src/OGKDisplay.m b/src/OGKDisplay.m new file mode 100644 index 0000000..25d293f --- /dev/null +++ b/src/OGKDisplay.m @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2012 Jonathan Schleifer + * + * 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. + */ + +#import "OGKDisplay.h" + +@implementation OGKDisplay ++ (void)initialize +{ + if (self != [OGKDisplay class]) + return; + + if (!al_install_system(ALLEGRO_VERSION_INT, NULL)) + @throw [OFInitializationFailedException + exceptionWithClass: self]; +} + ++ displayWithSize: (of_dimension_t)size + fullscreen: (BOOL)fullscreen + resizable: (BOOL)resizable +{ + return [[self alloc] initWithSize: size + fullscreen: fullscreen + resizable: resizable]; +} + +- initWithSize: (of_dimension_t)size + fullscreen: (BOOL)fullscreen + resizable: (BOOL)resizable +{ + int flags = 0; + + self = [super init]; + +#if 0 + /* TODO: Find a nice way to set these when requested */ + flags |= ALLEGRO_OPENGL_3_0; + flags |= ALLEGRO_OPENGL_FORWARD_COMPATIBLE; +#endif + + if (fullscreen) + flags |= ALLEGRO_FULLSCREEN; + else if (resizable) + flags |= ALLEGRO_RESIZABLE; + + al_set_new_display_flags(flags); + display = al_create_display(size.width, size.height); + + if (display == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: [self class]]; + + return self; +} + +- (void)dealloc +{ + if (display != NULL) + al_destroy_display(display); +} + +- (ALLEGRO_DISPLAY*)OGK_allegroDisplay +{ + return display; +} +@end diff --git a/src/OGKEvent.h b/src/OGKEvent.h new file mode 100644 index 0000000..dbc9840 --- /dev/null +++ b/src/OGKEvent.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012 Jonathan Schleifer + * + * 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 + +#import + +typedef enum ogk_event_type_t { + OGK_EVENT_TYPE_CLOSE = 1 +} ogk_event_type_t; + +@interface OGKEvent: OFObject +{ + ALLEGRO_EVENT event; +} + +- (ALLEGRO_EVENT*)OGK_allegroEvent; +@end + +@interface OGKCloseEvent: OGKEvent +@end + +@interface OGKKeyboardEvent: OGKEvent +@property (readonly, assign) int keycode; +@end + +@interface OGKKeyPressEvent: OGKKeyboardEvent +@end + +@interface OGKKeyReleaseEvent: OGKKeyboardEvent +@end + +@interface OGKMouseEvent: OGKEvent +@property (readonly, assign) of_point_t cursor; +@property (readonly, assign) of_point_t wheel; +@end + +@interface OGKMouseMovedEvent: OGKMouseEvent +@property (readonly, assign) of_point_t deltaCursor, deltaWheel; +@end + +@interface OGKMouseButtonEvent: OGKMouseEvent +@property (readonly, assign) unsigned button; +@end + +@interface OGKMouseButtonPressedEvent: OGKMouseButtonEvent +@end + +@interface OGKMouseButtonReleasedEvent: OGKMouseButtonEvent +@end diff --git a/src/OGKEvent.m b/src/OGKEvent.m new file mode 100644 index 0000000..3767009 --- /dev/null +++ b/src/OGKEvent.m @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2012 Jonathan Schleifer + * + * 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. + */ + +#import "OGKEvent.h" + +@implementation OGKEvent +- (ALLEGRO_EVENT*)OGK_allegroEvent +{ + return &event; +} +@end + +@implementation OGKCloseEvent +@end + +@implementation OGKKeyboardEvent +- (int)keycode +{ + return event.keyboard.keycode; +} +@end + +@implementation OGKKeyPressEvent +@end + +@implementation OGKKeyReleaseEvent +@end + +@implementation OGKMouseEvent +- (of_point_t)cursor +{ + return of_point(event.mouse.x, event.mouse.y); +} + +- (of_point_t)wheel +{ + return of_point(event.mouse.w, event.mouse.z); +} +@end + +@implementation OGKMouseMovedEvent +- (of_point_t)deltaCursor +{ + return of_point(event.mouse.dx, event.mouse.dy); +} + +- (of_point_t)deltaWheel +{ + return of_point(event.mouse.dw, event.mouse.dz); +} +@end + +@implementation OGKMouseButtonEvent +- (unsigned)button +{ + return event.mouse.button; +} +@end + +@implementation OGKMouseButtonPressedEvent +@end + +@implementation OGKMouseButtonReleasedEvent +@end diff --git a/src/OGKEventQueue.h b/src/OGKEventQueue.h new file mode 100644 index 0000000..3599852 --- /dev/null +++ b/src/OGKEventQueue.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012 Jonathan Schleifer + * + * 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 + +#import + +#import "OGKEvent.h" +#import "OGKDisplay.h" + +@protocol OGKEventQueueDelegate +@optional +- (void)displayWasClosed: (OGKCloseEvent*)event; +// FIXME: Those need to get the OGKDisplay passed! +- (void)keyWasPressed: (OGKKeyPressEvent*)event; +- (void)keyWasReleased: (OGKKeyReleaseEvent*)event; +- (void)mouseWasMoved: (OGKMouseMovedEvent*)event; +- (void)mouseButtonWasPressed: (OGKMouseButtonPressedEvent*)event; +- (void)mouseButtonWasReleased: (OGKMouseButtonReleasedEvent*)event; +@end + +@interface OGKEventQueue: OFObject +{ + ALLEGRO_EVENT_QUEUE *eventQueue; + /* FIXME: Make this weak once there is support in ObjFW for it */ + __unsafe_unretained id delegate; +} + +@property (unsafe_unretained) id delegate; + +- (void)handleNextEvent; +- (void)registerDisplay: (OGKDisplay*)display; +- (void)unregisterDisplay: (OGKDisplay*)display; +- (void)registerKeyboard; +- (void)unregisterKeyboard; +- (void)registerMouse; +- (void)unregisterMouse; +@end diff --git a/src/OGKEventQueue.m b/src/OGKEventQueue.m new file mode 100644 index 0000000..ba9e703 --- /dev/null +++ b/src/OGKEventQueue.m @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2012 Jonathan Schleifer + * + * 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. + */ + +#import "OGKEventQueue.h" +#import "OGKEvent.h" +#import "OGKDisplay.h" + +static int keyboard_retain_count = 0; +static int mouse_retain_count = 0; + +@implementation OGKEventQueue +@synthesize delegate; + ++ (void)initialize +{ + if (self != [OGKEventQueue class]) + return; + + if (!al_install_system(ALLEGRO_VERSION_INT, NULL)) + @throw [OFInitializationFailedException + exceptionWithClass: self]; +} + +- init +{ + self = [super init]; + + eventQueue = al_create_event_queue(); + + return self; +} + +- (void)dealloc +{ + al_destroy_event_queue(eventQueue); +} + +- (void)handleNextEvent +{ + OGKEvent *event = [[OGKEvent alloc] init]; + ALLEGRO_EVENT *allegroEvent = [event OGK_allegroEvent]; + + while (al_get_next_event(eventQueue, allegroEvent)) { + switch (allegroEvent->type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + object_setClass(event, [OGKCloseEvent class]); + + if ([delegate respondsToSelector: + @selector(displayWasClosed:)]) + [delegate displayWasClosed: + (OGKCloseEvent*)event]; + + break; + case ALLEGRO_EVENT_KEY_DOWN: + object_setClass(event, [OGKKeyPressEvent class]); + + if ([delegate respondsToSelector: + @selector(keyWasPressed:)]) + [delegate keyWasPressed: + (OGKKeyPressEvent*)event]; + + break; + case ALLEGRO_EVENT_KEY_UP: + object_setClass(event, [OGKKeyReleaseEvent class]); + + if ([delegate respondsToSelector: + @selector(keyWasReleased:)]) + [delegate keyWasReleased: + (OGKKeyReleaseEvent*)event]; + + break; + case ALLEGRO_EVENT_MOUSE_AXES: + object_setClass(event, [OGKMouseMovedEvent class]); + + if ([delegate respondsToSelector: + @selector(mouseWasMoved:)]) + [delegate mouseWasMoved: + (OGKMouseMovedEvent*)event]; + + break; + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + object_setClass(event, + [OGKMouseButtonPressedEvent class]); + + if ([delegate respondsToSelector: + @selector(mouseButtonWasPressed:)]) + [delegate mouseButtonWasPressed: + (OGKMouseButtonPressedEvent*)event]; + + break; + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + object_setClass(event, + [OGKMouseButtonReleasedEvent class]); + + if ([delegate respondsToSelector: + @selector(mouseButtonWasReleased:)]) + [delegate mouseButtonWasReleased: + (OGKMouseButtonReleasedEvent*)event]; + + break; + } + } +} + +- (void)registerDisplay: (OGKDisplay*)display +{ + ALLEGRO_EVENT_SOURCE *eventSource; + + eventSource = al_get_display_event_source([display OGK_allegroDisplay]); + al_register_event_source(eventQueue, eventSource); +} + +- (void)unregisterDisplay: (OGKDisplay*)display +{ + ALLEGRO_EVENT_SOURCE *eventSource; + + eventSource = al_get_display_event_source([display OGK_allegroDisplay]); + al_unregister_event_source(eventQueue, eventSource); +} + +- (void)registerKeyboard +{ + of_atomic_inc_int(&keyboard_retain_count); + + if (!al_is_keyboard_installed()) + if (!al_install_keyboard()) + @throw [OFInitializationFailedException + exceptionWithClass: [self class]]; + + al_register_event_source(eventQueue, al_get_keyboard_event_source()); +} + +- (void)unregisterKeyboard +{ + al_unregister_event_source(eventQueue, al_get_keyboard_event_source()); + + if (of_atomic_dec_int(&keyboard_retain_count) == 0) + al_uninstall_keyboard(); +} + +- (void)registerMouse +{ + of_atomic_inc_int(&mouse_retain_count); + + if (!al_is_mouse_installed()) + if (!al_install_mouse()) + @throw [OFInitializationFailedException + exceptionWithClass: [self class]]; + + al_register_event_source(eventQueue, al_get_mouse_event_source()); +} + +- (void)unregisterMouse +{ + al_unregister_event_source(eventQueue, al_get_mouse_event_source()); + + if (of_atomic_dec_int(&mouse_retain_count)) + al_uninstall_mouse(); +} +@end diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..2464cf6 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,7 @@ +all: + @objfw-compile -o test --arc *.m \ + -I../src -L../src -lobjgamekit \ + `pkg-config --cflags --libs allegro-5.0 allegro_main-5.0` + +clean: + @rm -f test *.o *~ diff --git a/test/TestMain.h b/test/TestMain.h new file mode 100644 index 0000000..79f630d --- /dev/null +++ b/test/TestMain.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012 Jonathan Schleifer + * + * 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. + */ + +#import + +#import "OGKDisplay.h" +#import "OGKEventQueue.h" + +@interface TestMain: OFObject +{ + OGKDisplay *display; + OGKEventQueue *eventQueue; + BOOL running; +} +@end diff --git a/test/TestMain.m b/test/TestMain.m new file mode 100644 index 0000000..3e57f0e --- /dev/null +++ b/test/TestMain.m @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012 Jonathan Schleifer + * + * 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. + */ + +#import "OGKDisplay.h" +#import "OGKEvent.h" +#import "OGKEventQueue.h" +#import "TestMain.h" + +OF_APPLICATION_DELEGATE(TestMain) + +@implementation TestMain +- (void)displayWasClosed: (OGKCloseEvent*)event +{ + running = NO; +} + +- (void)keyWasPressed: (OGKKeyPressEvent*)event +{ + of_log(@"Pressed: %d", event.keycode); +} + +- (void)keyWasReleased: (OGKKeyReleaseEvent*)event +{ + of_log(@"Released: %d", event.keycode); +} + +- (void)mouseWasMoved: (OGKMouseMovedEvent*)event +{ + of_log(@"Mouse moved: X=%.f(%.f) Y=%.f(%.f) WX=%.f(%.f) WY=%.f(%.f)", + event.cursor.x, event.deltaCursor.x, + event.cursor.y, event.deltaCursor.y, + event.wheel.x, event.deltaWheel.x, + event.wheel.y, event.deltaWheel.y); +} + +- (void)mouseButtonWasPressed: (OGKMouseButtonPressedEvent*)event +{ + of_log(@"Mouse button was pressed: %d (X=%.f Y=%.f WX=%.f WY=%.f)", + event.button, event.cursor.x, event.cursor.y, + event.wheel.x, event.wheel.y); +} + +- (void)mouseButtonWasReleased: (OGKMouseButtonPressedEvent*)event +{ + of_log(@"Mouse button was released: %d (X=%.f Y=%.f WX=%.f WY=%.f)", + event.button, event.cursor.x, event.cursor.y, + event.wheel.x, event.wheel.y); +} + +- (void)applicationDidFinishLaunching +{ + display = [[OGKDisplay alloc] initWithSize: of_dimension(640, 480) + fullscreen: NO + resizable: NO]; + eventQueue = [[OGKEventQueue alloc] init]; + eventQueue.delegate = self; + + [eventQueue registerDisplay: display]; + [eventQueue registerKeyboard]; + [eventQueue registerMouse]; + + for (running = YES; running;) { + @autoreleasepool { + [eventQueue handleNextEvent]; + } + } +} + +- (void)applicationWillTerminate +{ + /* Make sure they don't get deallocated after al_uninstall_system() */ + display = nil; + eventQueue = nil; + + al_uninstall_system(); +} +@end