// C++ Headers
#include <ctime>
// Windows Headers
#ifdef _WIN32
#define Rectangle WinRectangle
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#undef Rectangle
#endif
// Project Headers
#include "Application.h"
#include "Window.h"
#include "Common.h"
BEGIN_NAMESPACE
struct ApplicationData
{
int screenW, screenH;
clock_t lastTick;
Window* mainWindow;
};
#ifdef _WIN32
extern LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
Application::Application()
{
m_data = new ApplicationData;
m_data->screenW = GetSystemMetrics(SM_CXSCREEN);
m_data->screenH= GetSystemMetrics(SM_CYSCREEN);
WNDCLASSEXW wcx = { sizeof(WNDCLASSEXA), CS_OWNDC | CS_HREDRAW | CS_VREDRAW, MainWndProc,
0, 0, GetModuleHandle(0), NULL, NULL, NULL, NULL, L"MainWClass", NULL };
RegisterClassExW(&wcx);
//m_data->mainWindow = new Window("Test", a_fullscreen);
//ShowCursor(FALSE);
}
Application::~Application()
{
//delete m_data->mainWindow;
delete m_data;
}
int Application::exec()
{
normalLoop();
return 0;
}
void Application::normalLoop()
{
MSG msg;
while (GetMessageW(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
void Application::gameLoop()
{
MSG msg;
while (true)
{
// Remove all messages off the queue ... makes it look like we are responding
while ( GetQueueStatus(QS_ALLEVENTS) )
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
clock_t tick = clock();
m_data->lastTick = tick;
SHORT escape = GetAsyncKeyState(VK_ESCAPE);
if ( escape )
break;
m_data->mainWindow->repaint();
}
}
#else
END_NAMESPACE
// C/C++ API for Mac OS X Windowing - windowing.cpp
// Created by John Ryland (jryland@xiaofrog.com), 29/10/2017
// Copyright (c) 2017 InvertedLogic
// All rights reserved.
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <objc/message.h>
#include <objc/runtime.h>
#include <ApplicationServices/ApplicationServices.h>
//#include <OpenGL/gl.h>
extern id NSApp;
class NSString;
typedef NSString* NSRunLoopMode;
typedef unsigned long long NSEventMask;
const NSEventMask NSAnyEventMask = UINT64_MAX;
extern "C" NSRunLoopMode NSDefaultRunLoopMode;
BEGIN_NAMESPACE
bool s_started = false;
BOOL AppDidFinishLaunching(id self, SEL _cmd, id notification)
{
Application* appPtr = 0;
object_getInstanceVariable(self, "ApplicationPtr", (void**)&appPtr);
printf("AppDidFinishLaunching %i\n", __LINE__);
s_started = true;
printf("AppDidFinishLaunching %i\n", __LINE__);
return YES;
}
struct NSPoint { double x, y; };
struct NSSize { double width, height; };
struct NSRect { double x, y, width, height; };
struct NSEvent;
void WindowOnDraw(id self, SEL _cmd, NSRect rect);
void WindowOnResize(id self, SEL _cmd, NSSize newSize);
void WindowOnMouseEvent(id self, SEL _cmd, NSEvent* event);
void ProcessTimerEvent(id self, SEL _cmd, void* timerEvent);
Application::Application()
{
m_data = new ApplicationData;
//m_data->screenW = xx;
//m_data->screenH = xx;
Class AppDelClass;
AppDelClass = objc_allocateClassPair((Class)objc_getClass("NSObject"), "AppDelegate", 0);
class_addMethod(AppDelClass, sel_getUid("applicationDidFinishLaunching:"), (IMP)AppDidFinishLaunching, "i@:@");
class_addIvar(AppDelClass, "ApplicationPtr", sizeof(Application*), sizeof(Application*), "Application*");
objc_registerClassPair(AppDelClass);
Class ViewClass;
#if 1 // USE_OPENGL
ViewClass = objc_allocateClassPair((Class)objc_getClass("NSOpenGLView"), "View", 0);
#else
ViewClass = objc_allocateClassPair((Class)objc_getClass("NSView"), "View", 0);
#endif
class_addMethod(ViewClass, sel_getUid("drawRect:"), (IMP)WindowOnDraw, "v@:");
class_addMethod(ViewClass, sel_getUid("setFrameSize:"), (IMP)WindowOnResize, "v@:");
class_addMethod(ViewClass, sel_getUid("mouseDown:"), (IMP)WindowOnMouseEvent, "v@:");
class_addMethod(ViewClass, sel_getUid("mouseDragged:"), (IMP)WindowOnMouseEvent, "v@:");
class_addMethod(ViewClass, sel_getUid("mouseUp:"), (IMP)WindowOnMouseEvent, "v@:");
class_addMethod(ViewClass, sel_getUid("mouseMoved:"), (IMP)WindowOnMouseEvent, "v@:");
class_addMethod(ViewClass, sel_getUid("processTimerEvent:"), (IMP)ProcessTimerEvent, "v@:");
class_addIvar(ViewClass, "WindowPtr", sizeof(Window*), sizeof(Window*), "Window*");
objc_registerClassPair(ViewClass);
objc_msgSend((id)objc_getClass("NSApplication"), sel_getUid("sharedApplication"));
id appDelObj = objc_msgSend((id)objc_getClass("AppDelegate"), sel_getUid("alloc"));
appDelObj = objc_msgSend(appDelObj, sel_getUid("init"));
object_setInstanceVariable(appDelObj, "ApplicationPtr", (void*)this);
objc_msgSend(NSApp, sel_getUid("setDelegate:"), appDelObj);
printf("waiting for AppDidFinishLaunching\n");
objc_msgSend(NSApp, sel_getUid("finishLaunching"));
while (!s_started)
{
printf("waiting for event\n");
//CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, YES);
id event = objc_msgSend(NSApp, sel_getUid("nextEventMatchingMask:untilDate:inMode:dequeue:"), NSAnyEventMask, nil, NSDefaultRunLoopMode, YES);
objc_msgSend(NSApp, sel_getUid("sendEvent:"), event);
objc_msgSend(NSApp, sel_getUid("updateWindows"));
printf("got event\n");
}
printf("finished waiting for AppDidFinishLaunching\n");
}
Application::~Application()
{
// any shut down code needed
delete m_data;
}
int Application::exec()
{
/*
// Objective-C version that emulates what "run" does internally
- (void)run
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[self finishLaunching];
shouldKeepRunning = YES;
do
{
[pool release];
pool = [[NSAutoreleasePool alloc] init];
NSEvent *event =
[self
nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantFuture]
inMode:NSDefaultRunLoopMode
dequeue:YES];
[self sendEvent:event];
[self updateWindows];
} while (shouldKeepRunning);
[pool release];
}
- (void)terminate:(id)sender
{
shouldKeepRunning = NO;
}
*/
printf("run loop\n");
id pool = objc_msgSend((id)objc_getClass("NSAutoreleasePool"), sel_getUid("alloc"));
pool = objc_msgSend(pool, sel_getUid("init"));
objc_msgSend(NSApp, sel_getUid("run"));
objc_msgSend(pool, sel_getUid("release"));
return 0;
}
void Application::normalLoop()
{
}
void Application::gameLoop()
{
}
#endif
END_NAMESPACE