summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/haiku/SCsub14
-rw-r--r--platform/haiku/context_gl_haiku.cpp46
-rw-r--r--platform/haiku/context_gl_haiku.h29
-rw-r--r--platform/haiku/detect.py61
-rw-r--r--platform/haiku/godot_haiku.cpp19
-rw-r--r--platform/haiku/haiku_application.cpp7
-rw-r--r--platform/haiku/haiku_application.h15
-rw-r--r--platform/haiku/haiku_direct_window.cpp243
-rw-r--r--platform/haiku/haiku_direct_window.h51
-rw-r--r--platform/haiku/haiku_gl_view.cpp31
-rw-r--r--platform/haiku/haiku_gl_view.h17
-rw-r--r--platform/haiku/logo.pngbin0 -> 2055 bytes
-rw-r--r--platform/haiku/os_haiku.cpp305
-rw-r--r--platform/haiku/os_haiku.h97
-rw-r--r--platform/haiku/platform_config.h6
15 files changed, 941 insertions, 0 deletions
diff --git a/platform/haiku/SCsub b/platform/haiku/SCsub
new file mode 100644
index 0000000000..18fa2e2b15
--- /dev/null
+++ b/platform/haiku/SCsub
@@ -0,0 +1,14 @@
+Import('env')
+
+common_haiku = [
+ 'os_haiku.cpp',
+ 'context_gl_haiku.cpp',
+ 'haiku_application.cpp',
+ 'haiku_direct_window.cpp',
+ 'haiku_gl_view.cpp'
+]
+
+env.Program(
+ '#bin/godot',
+ ['godot_haiku.cpp'] + common_haiku
+)
diff --git a/platform/haiku/context_gl_haiku.cpp b/platform/haiku/context_gl_haiku.cpp
new file mode 100644
index 0000000000..8cb1adc360
--- /dev/null
+++ b/platform/haiku/context_gl_haiku.cpp
@@ -0,0 +1,46 @@
+#include "context_gl_haiku.h"
+
+#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+
+ContextGL_Haiku::ContextGL_Haiku(HaikuDirectWindow* p_window) {
+ window = p_window;
+
+ uint32 type = BGL_RGB | BGL_DOUBLE | BGL_DEPTH;
+ view = new HaikuGLView(window->Bounds(), type);
+}
+
+ContextGL_Haiku::~ContextGL_Haiku() {
+ delete view;
+}
+
+Error ContextGL_Haiku::initialize() {
+ window->AddChild(view);
+ view->LockGL();
+ window->SetHaikuGLView(view);
+
+ return OK;
+}
+
+void ContextGL_Haiku::release_current() {
+ //ERR_PRINT("release_current() NOT IMPLEMENTED");
+ view->UnlockGL();
+}
+
+void ContextGL_Haiku::make_current() {
+ view->LockGL();
+ //ERR_PRINT("make_current() NOT IMPLEMENTED");
+}
+
+void ContextGL_Haiku::swap_buffers() {
+ view->SwapBuffers();
+}
+
+int ContextGL_Haiku::get_window_width() {
+ return window->Bounds().IntegerWidth();
+}
+
+int ContextGL_Haiku::get_window_height() {
+ return window->Bounds().IntegerHeight();
+}
+
+#endif
diff --git a/platform/haiku/context_gl_haiku.h b/platform/haiku/context_gl_haiku.h
new file mode 100644
index 0000000000..e37fe14970
--- /dev/null
+++ b/platform/haiku/context_gl_haiku.h
@@ -0,0 +1,29 @@
+#ifndef CONTEXT_GL_HAIKU_H
+#define CONTEXT_GL_HAIKU_H
+
+#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+
+#include "drivers/gl_context/context_gl.h"
+
+#include "haiku_direct_window.h"
+#include "haiku_gl_view.h"
+
+class ContextGL_Haiku : public ContextGL {
+private:
+ HaikuGLView* view;
+ HaikuDirectWindow* window;
+
+public:
+ ContextGL_Haiku(HaikuDirectWindow* p_window);
+ ~ContextGL_Haiku();
+
+ virtual Error initialize();
+ virtual void release_current();
+ virtual void make_current();
+ virtual void swap_buffers();
+ virtual int get_window_width();
+ virtual int get_window_height();
+};
+
+#endif
+#endif
diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py
new file mode 100644
index 0000000000..587148838f
--- /dev/null
+++ b/platform/haiku/detect.py
@@ -0,0 +1,61 @@
+import os
+import sys
+
+def is_active():
+ return True
+
+def get_name():
+ return "Haiku"
+
+def can_build():
+ if (os.name != "posix"):
+ return False
+
+ if (sys.platform == "darwin"):
+ return False
+
+ return True
+
+def get_opts():
+ return []
+
+def get_flags():
+ return [
+ ('builtin_zlib', 'no')
+ ]
+
+def configure(env):
+ is64=sys.maxsize > 2**32
+
+ if (env["bits"]=="default"):
+ if (is64):
+ env["bits"]="64"
+ else:
+ env["bits"]="32"
+
+ env.Append(CPPPATH = ['#platform/haiku'])
+
+ # TODO: add clang and try gcc2 too
+ env["CC"] = "gcc-x86"
+ env["CXX"] = "g++-x86"
+
+ if (env["target"]=="release"):
+ if (env["debug_release"]=="yes"):
+ env.Append(CCFLAGS=['-g2','-fomit-frame-pointer'])
+ else:
+ env.Append(CCFLAGS=['-O2','-ffast-math','-fomit-frame-pointer'])
+ elif (env["target"]=="release_debug"):
+ env.Append(CCFLAGS=['-O2','-ffast-math','-DDEBUG_ENABLED'])
+ elif (env["target"]=="debug"):
+ env.Append(CCFLAGS=['-g2', '-Wall','-DDEBUG_ENABLED','-DDEBUG_MEMORY_ENABLED'])
+
+ #env.Append(CCFLAGS=['-DFREETYPE_ENABLED'])
+ env.Append(CPPFLAGS = ['-DGLEW_ENABLED'])
+ env.Append(CPPFLAGS = ['-DOPENGL_ENABLED'])
+ env.Append(CPPFLAGS = ['-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL'])
+ env.Append(LIBS = ['be', 'game', 'GL', 'GLEW', 'z', 'network', 'bnetapi'])
+
+ import methods
+ env.Append(BUILDERS = {'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl')})
+ env.Append(BUILDERS = {'GLSL' : env.Builder(action = methods.build_glsl_headers, suffix = 'glsl.h',src_suffix = '.glsl')})
+ env.Append(BUILDERS = {'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl')})
diff --git a/platform/haiku/godot_haiku.cpp b/platform/haiku/godot_haiku.cpp
new file mode 100644
index 0000000000..b4e5e50891
--- /dev/null
+++ b/platform/haiku/godot_haiku.cpp
@@ -0,0 +1,19 @@
+#include "main/main.h"
+#include "os_haiku.h"
+
+int main(int argc, char* argv[]) {
+ OS_Haiku os;
+
+ Error error = Main::setup(argv[0], argc-1, &argv[1]);
+ if (error != OK) {
+ return 255;
+ }
+
+ if (Main::start()) {
+ os.run();
+ }
+
+ Main::cleanup();
+
+ return os.get_exit_code();
+}
diff --git a/platform/haiku/haiku_application.cpp b/platform/haiku/haiku_application.cpp
new file mode 100644
index 0000000000..56024f605d
--- /dev/null
+++ b/platform/haiku/haiku_application.cpp
@@ -0,0 +1,7 @@
+#include "haiku_application.h"
+
+HaikuApplication::HaikuApplication()
+ : BApplication("application/x-vnd.Haiku-GLDirectMode")
+{
+
+}
diff --git a/platform/haiku/haiku_application.h b/platform/haiku/haiku_application.h
new file mode 100644
index 0000000000..995a917d62
--- /dev/null
+++ b/platform/haiku/haiku_application.h
@@ -0,0 +1,15 @@
+#ifndef HAIKU_APPLICATION_H
+#define HAIKU_APPLICATION_H
+
+#include <kernel/image.h> // needed for image_id
+#include <Application.h>
+
+class HaikuApplication : public BApplication
+{
+public:
+ HaikuApplication();
+//private:
+// HaikuDirectWindow* window;
+};
+
+#endif
diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp
new file mode 100644
index 0000000000..8c8069af49
--- /dev/null
+++ b/platform/haiku/haiku_direct_window.cpp
@@ -0,0 +1,243 @@
+#include "main/main.h"
+#include "haiku_direct_window.h"
+
+HaikuDirectWindow::HaikuDirectWindow(BRect p_frame)
+ : BDirectWindow(p_frame, "Godot", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE)
+{
+ last_mouse_pos_valid = false;
+ last_buttons_state = 0;
+ last_button_mask = 0;
+ last_key_modifier_state = 0;
+}
+
+
+HaikuDirectWindow::~HaikuDirectWindow() {
+ if (update_runner) {
+ delete update_runner;
+ }
+}
+
+void HaikuDirectWindow::SetHaikuGLView(HaikuGLView* p_view) {
+ view = p_view;
+}
+
+void HaikuDirectWindow::StartMessageRunner() {
+ update_runner = new BMessageRunner(BMessenger(this),
+ new BMessage(REDRAW_MSG), 1000000/60 /* 60 fps */);
+}
+
+void HaikuDirectWindow::StopMessageRunner() {
+ delete update_runner;
+}
+
+void HaikuDirectWindow::SetInput(InputDefault* p_input) {
+ input = p_input;
+}
+
+void HaikuDirectWindow::SetMainLoop(MainLoop* p_main_loop) {
+ main_loop = p_main_loop;
+}
+
+bool HaikuDirectWindow::QuitRequested() {
+ main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
+ return false;
+}
+
+void HaikuDirectWindow::DirectConnected(direct_buffer_info* info) {
+ view->DirectConnected(info);
+ view->EnableDirectMode(true);
+}
+
+void HaikuDirectWindow::MessageReceived(BMessage* message) {
+ switch (message->what) {
+ case REDRAW_MSG:
+ Sync();
+
+ if (Main::iteration() == true) {
+ view->EnableDirectMode(false);
+ Quit();
+ }
+ break;
+
+ default:
+ BDirectWindow::MessageReceived(message);
+ }
+}
+
+void HaikuDirectWindow::DispatchMessage(BMessage* message, BHandler* handler) {
+ switch (message->what) {
+ case B_MOUSE_DOWN:
+ case B_MOUSE_UP:
+ DispatchMouseButton(message);
+ break;
+
+ case B_MOUSE_MOVED:
+ DispatchMouseMoved(message);
+ break;
+
+ case B_MOUSE_WHEEL_CHANGED:
+ DispatchMouseWheelChanged(message);
+ break;
+
+ default:
+ BDirectWindow::DispatchMessage(message, handler);
+ }
+}
+
+void HaikuDirectWindow::DispatchMouseButton(BMessage* message) {
+ message->PrintToStream();
+
+ BPoint where;
+ if (message->FindPoint("where", &where) != B_OK) {
+ return;
+ }
+
+ uint32 modifiers = message->FindInt32("modifiers");
+ uint32 buttons = message->FindInt32("buttons");
+ uint32 button = buttons ^ last_buttons_state;
+ last_buttons_state = buttons;
+
+ // TODO: implement the mouse_mode checks
+ //if (mouse_mode == MOUSE_MODE_CAPTURED) {
+ // event.xbutton.x=last_mouse_pos.x;
+ // event.xbutton.y=last_mouse_pos.y;
+ //}
+
+ InputEvent mouse_event;
+ mouse_event.ID = ++event_id;
+ mouse_event.type = InputEvent::MOUSE_BUTTON;
+ mouse_event.device = 0;
+
+ mouse_event.mouse_button.mod = GetKeyModifierState(modifiers);
+ mouse_event.mouse_button.button_mask = GetMouseButtonState(buttons);
+ mouse_event.mouse_button.x = where.x;
+ mouse_event.mouse_button.y = where.y;
+ mouse_event.mouse_button.global_x = where.x;
+ mouse_event.mouse_button.global_y = where.y;
+
+ switch (button) {
+ default:
+ case B_PRIMARY_MOUSE_BUTTON:
+ mouse_event.mouse_button.button_index = 1;
+ break;
+
+ case B_SECONDARY_MOUSE_BUTTON:
+ mouse_event.mouse_button.button_index = 2;
+ break;
+
+ case B_TERTIARY_MOUSE_BUTTON:
+ mouse_event.mouse_button.button_index = 3;
+ break;
+ }
+
+ mouse_event.mouse_button.pressed = (message->what == B_MOUSE_DOWN);
+
+ if (message->what == B_MOUSE_DOWN && mouse_event.mouse_button.button_index == 1) {
+ int32 clicks = message->FindInt32("clicks");
+
+ if (clicks > 1) {
+ mouse_event.mouse_button.doubleclick=true;
+ }
+ }
+
+ input->parse_input_event(mouse_event);
+}
+
+void HaikuDirectWindow::DispatchMouseMoved(BMessage* message) {
+ BPoint where;
+ if (message->FindPoint("where", &where) != B_OK) {
+ return;
+ }
+
+ Point2i pos(where.x, where.y);
+ uint32 modifiers = message->FindInt32("modifiers");
+ uint32 buttons = message->FindInt32("buttons");
+
+ if (!last_mouse_pos_valid) {
+ last_mouse_position = pos;
+ last_mouse_pos_valid = true;
+ }
+
+ Point2i rel = pos - last_mouse_position;
+
+ InputEvent motion_event;
+ motion_event.ID = ++event_id;
+ motion_event.type = InputEvent::MOUSE_MOTION;
+ motion_event.device = 0;
+
+ motion_event.mouse_motion.mod = GetKeyModifierState(modifiers);
+ motion_event.mouse_motion.button_mask = GetMouseButtonState(buttons);
+ motion_event.mouse_motion.x = pos.x;
+ motion_event.mouse_motion.y = pos.y;
+ input->set_mouse_pos(pos);
+ motion_event.mouse_motion.global_x = pos.x;
+ motion_event.mouse_motion.global_y = pos.y;
+ motion_event.mouse_motion.speed_x = input->get_mouse_speed().x;
+ motion_event.mouse_motion.speed_y = input->get_mouse_speed().y;
+
+ motion_event.mouse_motion.relative_x = rel.x;
+ motion_event.mouse_motion.relative_y = rel.y;
+
+ last_mouse_position = pos;
+
+ input->parse_input_event(motion_event);
+}
+
+void HaikuDirectWindow::DispatchMouseWheelChanged(BMessage* message) {
+ float wheel_delta_y = 0;
+ if (message->FindFloat("be:wheel_delta_y", &wheel_delta_y) != B_OK) {
+ return;
+ }
+
+ InputEvent mouse_event;
+ mouse_event.ID = ++event_id;
+ mouse_event.type = InputEvent::MOUSE_BUTTON;
+ mouse_event.device = 0;
+
+ mouse_event.mouse_button.button_index = wheel_delta_y < 0 ? 4 : 5;
+ mouse_event.mouse_button.mod = GetKeyModifierState(last_key_modifier_state);
+ mouse_event.mouse_button.button_mask = last_button_mask;
+ mouse_event.mouse_button.x = last_mouse_position.x;
+ mouse_event.mouse_button.y = last_mouse_position.y;
+ mouse_event.mouse_button.global_x = last_mouse_position.x;
+ mouse_event.mouse_button.global_y = last_mouse_position.y;
+
+ mouse_event.mouse_button.pressed = true;
+ input->parse_input_event(mouse_event);
+
+ mouse_event.ID = ++event_id;
+ mouse_event.mouse_button.pressed = false;
+ input->parse_input_event(mouse_event);
+}
+
+inline InputModifierState HaikuDirectWindow::GetKeyModifierState(uint32 p_state) {
+ last_key_modifier_state = p_state;
+ InputModifierState state;
+
+ state.shift = (p_state & B_SHIFT_KEY) != 0;
+ state.control = (p_state & B_CONTROL_KEY) != 0;
+ state.alt = (p_state & B_OPTION_KEY) != 0;
+ state.meta = (p_state & B_COMMAND_KEY) != 0;
+
+ return state;
+}
+
+inline int HaikuDirectWindow::GetMouseButtonState(uint32 p_state) {
+ int state = 0;
+
+ if (p_state & B_PRIMARY_MOUSE_BUTTON) {
+ state |= 1 << 0;
+ }
+
+ if (p_state & B_SECONDARY_MOUSE_BUTTON) {
+ state |= 1 << 1;
+ }
+
+ if (p_state & B_TERTIARY_MOUSE_BUTTON) {
+ state |= 1 << 2;
+ }
+
+ last_button_mask = state;
+
+ return state;
+}
diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h
new file mode 100644
index 0000000000..5355ab4dd4
--- /dev/null
+++ b/platform/haiku/haiku_direct_window.h
@@ -0,0 +1,51 @@
+#ifndef HAIKU_DIRECT_WINDOW_H
+#define HAIKU_DIRECT_WINDOW_H
+
+#include <kernel/image.h> // needed for image_id
+#include <DirectWindow.h>
+
+#include "os/input.h"
+#include "haiku_gl_view.h"
+
+#define REDRAW_MSG 'rdrw'
+
+class HaikuDirectWindow : public BDirectWindow
+{
+private:
+ unsigned int event_id;
+ Point2i last_mouse_position;
+ bool last_mouse_pos_valid;
+ uint32 last_buttons_state;
+ uint32 last_key_modifier_state;
+ int last_button_mask;
+
+ MainLoop* main_loop;
+ InputDefault* input;
+ HaikuGLView* view;
+ BMessageRunner* update_runner;
+
+ void DispatchMouseButton(BMessage* message);
+ void DispatchMouseMoved(BMessage* message);
+ void DispatchMouseWheelChanged(BMessage* message);
+ inline InputModifierState GetKeyModifierState(uint32 p_state);
+ inline int GetMouseButtonState(uint32 p_state);
+
+public:
+ HaikuDirectWindow(BRect p_frame);
+ ~HaikuDirectWindow();
+
+ void SetHaikuGLView(HaikuGLView* p_view);
+ void StartMessageRunner();
+ void StopMessageRunner();
+ void SetInput(InputDefault* p_input);
+ void SetMainLoop(MainLoop* p_main_loop);
+ virtual bool QuitRequested();
+ virtual void DirectConnected(direct_buffer_info* info);
+ virtual void MessageReceived(BMessage* message);
+ virtual void DispatchMessage(BMessage* message, BHandler* handler);
+
+ inline Point2i GetLastMousePosition() { return last_mouse_position; };
+ inline int GetLastButtonMask() { return last_button_mask; };
+};
+
+#endif
diff --git a/platform/haiku/haiku_gl_view.cpp b/platform/haiku/haiku_gl_view.cpp
new file mode 100644
index 0000000000..8adab96a87
--- /dev/null
+++ b/platform/haiku/haiku_gl_view.cpp
@@ -0,0 +1,31 @@
+#include "main/main.h"
+#include "haiku_gl_view.h"
+
+HaikuGLView::HaikuGLView(BRect frame, uint32 type)
+ : BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type)
+{
+}
+
+void HaikuGLView::AttachedToWindow(void) {
+ LockGL();
+ BGLView::AttachedToWindow();
+ UnlockGL();
+ MakeFocus();
+}
+
+void HaikuGLView::Draw(BRect updateRect) {
+ Main::force_redraw();
+}
+
+void HaikuGLView::MessageReceived(BMessage* msg)
+{
+ // TODO: remove if not needed
+ switch (msg->what) {
+ default:
+ BGLView::MessageReceived(msg);
+ }
+}
+
+void HaikuGLView::MouseMoved (BPoint where, uint32 code, const BMessage *dragMessage) {
+ ERR_PRINT("MouseMoved()");
+}
diff --git a/platform/haiku/haiku_gl_view.h b/platform/haiku/haiku_gl_view.h
new file mode 100644
index 0000000000..78ebb513a8
--- /dev/null
+++ b/platform/haiku/haiku_gl_view.h
@@ -0,0 +1,17 @@
+#ifndef HAIKU_GL_VIEW_H
+#define HAIKU_GL_VIEW_H
+
+#include <kernel/image.h> // needed for image_id
+#include <GLView.h>
+
+class HaikuGLView : public BGLView
+{
+public:
+ HaikuGLView(BRect frame, uint32 type);
+ virtual void AttachedToWindow(void);
+ virtual void MessageReceived(BMessage* msg);
+ virtual void MouseMoved (BPoint where, uint32 code, const BMessage *dragMessage);
+ virtual void Draw(BRect updateRect);
+};
+
+#endif
diff --git a/platform/haiku/logo.png b/platform/haiku/logo.png
new file mode 100644
index 0000000000..c40214d6de
--- /dev/null
+++ b/platform/haiku/logo.png
Binary files differ
diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp
new file mode 100644
index 0000000000..b4b7877038
--- /dev/null
+++ b/platform/haiku/os_haiku.cpp
@@ -0,0 +1,305 @@
+#include <Screen.h>
+
+#include "servers/visual/visual_server_raster.h"
+#include "servers/visual/visual_server_wrap_mt.h"
+#include "drivers/gles2/rasterizer_gles2.h"
+#include "servers/physics/physics_server_sw.h"
+//#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
+#include "main/main.h"
+
+#include "os_haiku.h"
+
+
+OS_Haiku::OS_Haiku() {
+ AudioDriverManagerSW::add_driver(&driver_dummy);
+};
+
+void OS_Haiku::run() {
+ if (!main_loop) {
+ return;
+ }
+
+ main_loop->init();
+ window->StartMessageRunner();
+ app->Run();
+ window->StopMessageRunner();
+
+ delete app;
+ main_loop->finish();
+}
+
+String OS_Haiku::get_name() {
+ return "Haiku";
+}
+
+int OS_Haiku::get_video_driver_count() const {
+ return 1;
+}
+
+const char* OS_Haiku::get_video_driver_name(int p_driver) const {
+ return "GLES2";
+}
+
+OS::VideoMode OS_Haiku::get_default_video_mode() const {
+ return OS::VideoMode(800, 600, false);
+}
+
+void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_audio_driver) {
+ main_loop = NULL;
+ current_video_mode = p_desired;
+
+ app = new HaikuApplication();
+
+ BRect frame;
+ frame.Set(50, 50, 50 + current_video_mode.width - 1, 50 + current_video_mode.height - 1);
+
+ window = new HaikuDirectWindow(frame);
+
+ if (current_video_mode.fullscreen) {
+ window->SetFullScreen(true);
+ }
+
+ if (!current_video_mode.resizable) {
+ uint32 flags = window->Flags();
+ flags |= B_NOT_RESIZABLE;
+ window->SetFlags(flags);
+ }
+
+#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+ context_gl = memnew(ContextGL_Haiku(window));
+ context_gl->initialize();
+
+ rasterizer = memnew(RasterizerGLES2);
+#endif
+
+ visual_server = memnew(VisualServerRaster(rasterizer));
+
+ ERR_FAIL_COND(!visual_server);
+
+ // TODO: enable multithreaded VS
+ //if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
+ // visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
+ //}
+
+ visual_server->init();
+
+ physics_server = memnew(PhysicsServerSW);
+ physics_server->init();
+ physics_2d_server = memnew(Physics2DServerSW);
+ // TODO: enable multithreaded PS
+ //physics_2d_server = Physics2DServerWrapMT::init_server<Physics2DServerSW>();
+ physics_2d_server->init();
+
+ AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();
+
+ if (AudioDriverManagerSW::get_driver(p_audio_driver)->init() != OK) {
+ ERR_PRINT("Initializing audio failed.");
+ }
+
+ sample_manager = memnew(SampleManagerMallocSW);
+ audio_server = memnew(AudioServerSW(sample_manager));
+ audio_server->init();
+
+ spatial_sound_server = memnew(SpatialSoundServerSW);
+ spatial_sound_server->init();
+ spatial_sound_2d_server = memnew(SpatialSound2DServerSW);
+ spatial_sound_2d_server->init();
+
+ input = memnew(InputDefault);
+ window->SetInput(input);
+ window->Show();
+}
+
+void OS_Haiku::finalize() {
+ if (main_loop) {
+ memdelete(main_loop);
+ }
+
+ main_loop = NULL;
+
+ spatial_sound_server->finish();
+ memdelete(spatial_sound_server);
+
+ spatial_sound_2d_server->finish();
+ memdelete(spatial_sound_2d_server);
+
+ audio_server->finish();
+ memdelete(audio_server);
+ memdelete(sample_manager);
+
+ visual_server->finish();
+ memdelete(visual_server);
+ memdelete(rasterizer);
+
+ physics_server->finish();
+ memdelete(physics_server);
+
+ physics_2d_server->finish();
+ memdelete(physics_2d_server);
+
+ memdelete(input);
+
+#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+ memdelete(context_gl);
+#endif
+}
+
+void OS_Haiku::set_main_loop(MainLoop* p_main_loop) {
+ main_loop = p_main_loop;
+ input->set_main_loop(p_main_loop);
+ window->SetMainLoop(p_main_loop);
+}
+
+MainLoop* OS_Haiku::get_main_loop() const {
+ return main_loop;
+}
+
+void OS_Haiku::delete_main_loop() {
+ if (main_loop) {
+ memdelete(main_loop);
+ }
+
+ main_loop = NULL;
+ window->SetMainLoop(NULL);
+}
+
+void OS_Haiku::release_rendering_thread() {
+ context_gl->release_current();
+}
+
+void OS_Haiku::make_rendering_thread() {
+ context_gl->make_current();
+}
+
+bool OS_Haiku::can_draw() const {
+ // TODO: implement
+ return true;
+}
+
+void OS_Haiku::swap_buffers() {
+ context_gl->swap_buffers();
+}
+
+Point2 OS_Haiku::get_mouse_pos() const {
+ return window->GetLastMousePosition();
+}
+
+int OS_Haiku::get_mouse_button_state() const {
+ return window->GetLastButtonMask();
+}
+
+void OS_Haiku::set_cursor_shape(CursorShape p_shape) {
+ //ERR_PRINT("set_cursor_shape() NOT IMPLEMENTED");
+}
+
+int OS_Haiku::get_screen_count() const {
+ // TODO: implement get_screen_count()
+ return 1;
+}
+
+int OS_Haiku::get_current_screen() const {
+ // TODO: implement get_current_screen()
+ return 0;
+}
+
+void OS_Haiku::set_current_screen(int p_screen) {
+ // TODO: implement set_current_screen()
+}
+
+Point2 OS_Haiku::get_screen_position(int p_screen) const {
+ // TODO: make this work with the p_screen parameter
+ BScreen* screen = new BScreen(window);
+ BRect frame = screen->Frame();
+ delete screen;
+ return Point2i(frame.left, frame.top);
+}
+
+Size2 OS_Haiku::get_screen_size(int p_screen) const {
+ // TODO: make this work with the p_screen parameter
+ BScreen* screen = new BScreen(window);
+ BRect frame = screen->Frame();
+ delete screen;
+ return Size2i(frame.IntegerWidth() + 1, frame.IntegerHeight() + 1);
+}
+
+void OS_Haiku::set_window_title(const String& p_title) {
+ window->SetTitle(p_title.utf8().get_data());
+}
+
+Size2 OS_Haiku::get_window_size() const {
+ BSize size = window->Size();
+ return Size2i(size.IntegerWidth() + 1, size.IntegerHeight() + 1);
+}
+
+void OS_Haiku::set_window_size(const Size2 p_size) {
+ // TODO: why does it stop redrawing after this is called?
+ window->ResizeTo(p_size.x, p_size.y);
+}
+
+Point2 OS_Haiku::get_window_position() const {
+ BPoint point(0, 0);
+ window->ConvertToScreen(&point);
+ return Point2i(point.x, point.y);
+}
+
+void OS_Haiku::set_window_position(const Point2& p_position) {
+ window->MoveTo(p_position.x, p_position.y);
+}
+
+void OS_Haiku::set_window_fullscreen(bool p_enabled) {
+ window->SetFullScreen(p_enabled);
+ current_video_mode.fullscreen = p_enabled;
+ visual_server->init();
+}
+
+bool OS_Haiku::is_window_fullscreen() const {
+ return current_video_mode.fullscreen;
+}
+
+void OS_Haiku::set_window_resizable(bool p_enabled) {
+ uint32 flags = window->Flags();
+
+ if (p_enabled) {
+ flags &= ~(B_NOT_RESIZABLE);
+ } else {
+ flags |= B_NOT_RESIZABLE;
+ }
+
+ window->SetFlags(flags);
+}
+
+bool OS_Haiku::is_window_resizable() const {
+ return !(window->Flags() & B_NOT_RESIZABLE);
+}
+
+void OS_Haiku::set_window_minimized(bool p_enabled) {
+ window->Minimize(p_enabled);
+}
+
+bool OS_Haiku::is_window_minimized() const {
+ return window->IsMinimized();
+}
+
+void OS_Haiku::set_window_maximized(bool p_enabled) {
+ window->Minimize(!p_enabled);
+}
+
+bool OS_Haiku::is_window_maximized() const {
+ return !window->IsMinimized();
+}
+
+void OS_Haiku::set_video_mode(const VideoMode& p_video_mode, int p_screen) {
+ ERR_PRINT("set_video_mode() NOT IMPLEMENTED");
+}
+
+OS::VideoMode OS_Haiku::get_video_mode(int p_screen) const {
+ return current_video_mode;
+}
+
+void OS_Haiku::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
+ ERR_PRINT("get_fullscreen_mode_list() NOT IMPLEMENTED");
+}
+
+String OS_Haiku::get_executable_path() const {
+ return OS::get_executable_path();
+}
diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h
new file mode 100644
index 0000000000..a7a8bee522
--- /dev/null
+++ b/platform/haiku/os_haiku.h
@@ -0,0 +1,97 @@
+#ifndef OS_HAIKU_H
+#define OS_HAIKU_H
+
+#include "os/input.h"
+#include "drivers/unix/os_unix.h"
+#include "servers/visual_server.h"
+#include "servers/visual/rasterizer.h"
+#include "servers/physics_server.h"
+#include "servers/physics_2d/physics_2d_server_sw.h"
+#include "servers/audio/audio_server_sw.h"
+#include "servers/audio/sample_manager_sw.h"
+#include "servers/spatial_sound/spatial_sound_server_sw.h"
+#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
+#include "servers/audio/audio_driver_dummy.h"
+
+#include "context_gl_haiku.h"
+#include "haiku_application.h"
+#include "haiku_direct_window.h"
+
+
+class OS_Haiku : public OS_Unix {
+private:
+ HaikuApplication* app;
+ HaikuDirectWindow* window;
+ MainLoop* main_loop;
+ InputDefault* input;
+ Rasterizer* rasterizer;
+ VisualServer* visual_server;
+ VideoMode current_video_mode;
+ PhysicsServer* physics_server;
+ Physics2DServer* physics_2d_server;
+ AudioServerSW* audio_server;
+ SampleManagerMallocSW* sample_manager;
+ SpatialSoundServerSW* spatial_sound_server;
+ SpatialSound2DServerSW* spatial_sound_2d_server;
+
+ AudioDriverDummy driver_dummy; // TODO: use a real driver
+
+#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+ ContextGL_Haiku* context_gl;
+#endif
+
+ virtual void delete_main_loop();
+
+protected:
+ virtual int get_video_driver_count() const;
+ virtual const char* get_video_driver_name(int p_driver) const;
+ virtual VideoMode get_default_video_mode() const;
+
+ virtual void initialize(const VideoMode& p_desired, int p_video_driver, int p_audio_driver);
+ virtual void finalize();
+
+ virtual void set_main_loop(MainLoop* p_main_loop);
+
+public:
+ OS_Haiku();
+ void run();
+
+ virtual String get_name();
+
+ virtual MainLoop* get_main_loop() const;
+
+ virtual bool can_draw() const;
+ virtual void release_rendering_thread();
+ virtual void make_rendering_thread();
+ virtual void swap_buffers();
+
+ virtual Point2 get_mouse_pos() const;
+ virtual int get_mouse_button_state() const;
+ virtual void set_cursor_shape(CursorShape p_shape);
+
+ virtual int get_screen_count() const;
+ virtual int get_current_screen() const;
+ virtual void set_current_screen(int p_screen);
+ virtual Point2 get_screen_position(int p_screen=0) const;
+ virtual Size2 get_screen_size(int p_screen=0) const;
+ virtual void set_window_title(const String& p_title);
+ virtual Size2 get_window_size() const;
+ virtual void set_window_size(const Size2 p_size);
+ virtual Point2 get_window_position() const;
+ virtual void set_window_position(const Point2& p_position);
+ virtual void set_window_fullscreen(bool p_enabled);
+ virtual bool is_window_fullscreen() const;
+ virtual void set_window_resizable(bool p_enabled);
+ virtual bool is_window_resizable() const;
+ virtual void set_window_minimized(bool p_enabled);
+ virtual bool is_window_minimized() const;
+ virtual void set_window_maximized(bool p_enabled);
+ virtual bool is_window_maximized() const;
+
+ virtual void set_video_mode(const VideoMode& p_video_mode, int p_screen=0);
+ virtual VideoMode get_video_mode(int p_screen=0) const;
+ virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen=0) const;
+ virtual String get_executable_path() const;
+};
+
+#endif
diff --git a/platform/haiku/platform_config.h b/platform/haiku/platform_config.h
new file mode 100644
index 0000000000..691bdbdb9c
--- /dev/null
+++ b/platform/haiku/platform_config.h
@@ -0,0 +1,6 @@
+#include <alloca.h>
+
+// for ifaddrs.h needed in drivers/unix/ip_unix.cpp
+#define _BSD_SOURCE 1
+
+#define GLES2_INCLUDE_H <GL/glew.h>