Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

More functions wrapped, more refactoring, etc.

  • Loading branch information...
commit 9e1819fd3a1623ea3870195e1c8d568c9e2a50f3 1 parent 5ca83ae
Vincent Kuyatt authored
View
4 binding.gyp
@@ -11,7 +11,9 @@
'src/texture.cc',
'src/window.cc',
'src/surface.cc',
- 'src/container.cc'
+ 'src/container.cc',
+ 'src/sdl_gl.cc',
+ 'src/event.cc'
],
'libraries': [
'/Library/Frameworks/SDL2.framework/SDL2',
View
2  package.json
@@ -9,7 +9,7 @@
},
"main": "sdl.js",
"engines": {
- "node": ">=0.4.4"
+ "node": ">=0.10.0"
},
"dependencies": {},
"devDependencies": {}
View
1  sdl.js
@@ -23,6 +23,7 @@ SDL.Color.Blue = new SDL.Color(0, 0, 255);
console.log("About to init SDL. (no args, default to EVERYTHING)");
SDL.init("FOO");
+console.log(SDL.Renderer.SOFTWARE);
console.log("COLOR: " + new SDL.Color(100, 100, 100, 255).toString());
console.log(SDL.Color.White.toString());
View
70 src/event.cc
@@ -0,0 +1,70 @@
+#include "event.h"
+
+using namespace v8;
+using namespace node;
+
+
+Local<Object> SDLEventToJavascriptObject(const SDL_Event& event) {
+ Local<Object> evt = Object::New();
+
+ switch (event.type) {
+ case SDL_KEYDOWN:
+ case SDL_KEYUP:
+ evt->Set(String::New("type"), String::New(event.type == SDL_KEYDOWN ? "KEYDOWN" : "KEYUP"));
+ evt->Set(String::New("scancode"), Number::New(event.key.keysym.scancode));
+ evt->Set(String::New("sym"), Number::New(event.key.keysym.sym));
+ evt->Set(String::New("mod"), Number::New(event.key.keysym.mod));
+ break;
+ case SDL_MOUSEMOTION:
+ evt->Set(String::New("type"), String::New("MOUSEMOTION"));
+ evt->Set(String::New("state"), Number::New(event.motion.state));
+ evt->Set(String::New("which"), Number::New(event.motion.which));
+ evt->Set(String::New("x"), Number::New(event.motion.x));
+ evt->Set(String::New("y"), Number::New(event.motion.y));
+ evt->Set(String::New("xrel"), Number::New(event.motion.xrel));
+ evt->Set(String::New("yrel"), Number::New(event.motion.yrel));
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ case SDL_MOUSEBUTTONUP:
+ evt->Set(String::New("type"), String::New(event.type == SDL_MOUSEBUTTONDOWN ? "MOUSEBUTTONDOWN" : "MOUSEBUTTONUP"));
+ evt->Set(String::New("button"), Number::New(event.button.button));
+ evt->Set(String::New("which"), Number::New(event.button.which));
+ evt->Set(String::New("x"), Number::New(event.button.x));
+ evt->Set(String::New("y"), Number::New(event.button.y));
+ break;
+ case SDL_JOYAXISMOTION:
+ evt->Set(String::New("type"), String::New("JOYAXISMOTION"));
+ evt->Set(String::New("which"), Number::New(event.jaxis.which));
+ evt->Set(String::New("axis"), Number::New(event.jaxis.axis));
+ evt->Set(String::New("value"), Number::New(event.jaxis.value));
+ break;
+ case SDL_JOYBALLMOTION:
+ evt->Set(String::New("type"), String::New("JOYBALLMOTION"));
+ evt->Set(String::New("which"), Number::New(event.jball.which));
+ evt->Set(String::New("ball"), Number::New(event.jball.ball));
+ evt->Set(String::New("xrel"), Number::New(event.jball.xrel));
+ evt->Set(String::New("yrel"), Number::New(event.jball.yrel));
+ break;
+ case SDL_JOYHATMOTION:
+ evt->Set(String::New("type"), String::New("JOYHATMOTION"));
+ evt->Set(String::New("which"), Number::New(event.jhat.which));
+ evt->Set(String::New("hat"), Number::New(event.jhat.hat));
+ evt->Set(String::New("value"), Number::New(event.jhat.value));
+ break;
+ case SDL_JOYBUTTONDOWN:
+ case SDL_JOYBUTTONUP:
+ evt->Set(String::New("type"), String::New(event.type == SDL_JOYBUTTONDOWN ? "JOYBUTTONDOWN" : "JOYBUTTONUP"));
+ evt->Set(String::New("which"), Number::New(event.jbutton.which));
+ evt->Set(String::New("button"), Number::New(event.jbutton.button));
+ break;
+ case SDL_QUIT:
+ evt->Set(String::New("type"), String::New("QUIT"));
+ break;
+ default:
+ evt->Set(String::New("type"), String::New("UNKNOWN"));
+ evt->Set(String::New("typeCode"), Number::New(event.type));
+ break;
+ }
+
+ return evt;
+}
View
13 src/event.h
@@ -0,0 +1,13 @@
+#ifndef NODEJS_EVENT_H
+#define NODEJS_EVENT_H
+
+#include <v8.h>
+#include <node.h>
+#include "SDL.h"
+
+
+namespace sdl {
+ v8::Local<v8::Object> SDLEventToJavascriptObject(const SDL_Event& event);
+}
+
+#endif
View
1  src/helpers.h
@@ -17,7 +17,6 @@ namespace sdl {
char* BufferData(v8::Local<v8::Object> buf_obj);
size_t BufferLength(v8::Local<v8::Object> buf_obj);
- v8::Local<v8::Object> SDLEventToJavascriptObject(const SDL_Event& event);
v8::Local<v8::Object> SDLDisplayModeToJavascriptObject(const SDL_DisplayMode& mode);
} // sdl
View
270 src/node_sdl.cc
@@ -4,12 +4,15 @@
#endif
#include "SDL.h"
+#include "SDL_revision.h"
#include "node_sdl.h"
#include "struct_wrappers.h"
#include "window.h"
#include "texture.h"
#include "surface.h"
#include "container.h"
+#include "sdl_gl.h"
+#include "event.h"
#include <v8.h>
#include <string>
#include <iostream>
@@ -82,6 +85,7 @@ init(Handle<Object> target)
sdl::TextureWrapper::Init(target);
sdl::SurfaceWrapper::Init(target);
sdl::ColorWrapper::Init(target);
+ sdl::gl::Init(target);
// Initialization and Shutdown.
NODE_SET_METHOD(target, "init", sdl::Init);
@@ -116,6 +120,21 @@ init(Handle<Object> target)
NODE_SET_METHOD(target, "getRGB", sdl::GetRGB);
NODE_SET_METHOD(target, "getRGBA", sdl::GetRGBA);
+ NODE_SET_METHOD(target, "AddHintCallback", sdl::AddHintCallback);
+ NODE_SET_METHOD(target, "getHint", sdl::GetHint);
+ NODE_SET_METHOD(target, "setHint", sdl::SetHint);
+ NODE_SET_METHOD(target, "setHintWithPriority", sdl::SetHintWithPriority);
+
+ NODE_SET_METHOD(target, "compiledVersion", sdl::CompiledVersion);
+ NODE_SET_METHOD(target, "compiledRevision", sdl::CompiledRevision);
+ NODE_SET_METHOD(target, "getRevision", sdl::GetRevision);
+ NODE_SET_METHOD(target, "getRevisionNumber", sdl::GetRevisionNumber);
+ NODE_SET_METHOD(target, "getVersion", sdl::GetVersion);
+
+ NODE_SET_METHOD(target, "getClipboardText", sdl::GetClipboardText);
+ NODE_SET_METHOD(target, "hasClipboardText", sdl::HasClipboardText);
+ NODE_SET_METHOD(target, "setClipboardText", sdl::SetClipboardText);
+
Local<Object> INIT = Object::New();
target->Set(String::New("INIT"), INIT);
INIT->Set(String::New("TIMER"), Number::New(SDL_INIT_TIMER));
@@ -153,23 +172,6 @@ init(Handle<Object> target)
EVENT->Set(String::New("USEREVENT"), Number::New(SDL_USEREVENT));
EVENT->Set(String::New("WINDOWEVENT"), Number::New(SDL_WINDOWEVENT));
- Local<Object> SURFACE = Object::New();
- target->Set(String::New("SURFACE"), SURFACE);
- // SURFACE->Set(String::New("ANYFORMAT"), Number::New(SDL_ANYFORMAT));
- // SURFACE->Set(String::New("ASYNCBLIT"), Number::New(SDL_ASYNCBLIT));
- // SURFACE->Set(String::New("DOUBLEBUF"), Number::New(SDL_DOUBLEBUF));
- // SURFACE->Set(String::New("HWACCEL"), Number::New(SDL_HWACCEL));
- // SURFACE->Set(String::New("HWPALETTE"), Number::New(SDL_HWPALETTE));
- // SURFACE->Set(String::New("HWSURFACE"), Number::New(SDL_HWSURFACE));
- // SURFACE->Set(String::New("FULLSCREEN"), Number::New(SDL_FULLSCREEN));
- // SURFACE->Set(String::New("OPENGL"), Number::New(SDL_OPENGL));
- // SURFACE->Set(String::New("RESIZABLE"), Number::New(SDL_RESIZABLE));
- SURFACE->Set(String::New("RLEACCEL"), Number::New(SDL_RLEACCEL));
- // SURFACE->Set(String::New("SRCALPHA"), Number::New(SDL_SRCALPHA));
- // SURFACE->Set(String::New("SRCCOLORKEY"), Number::New(SDL_SRCCOLORKEY));
- SURFACE->Set(String::New("SWSURFACE"), Number::New(SDL_SWSURFACE));
- SURFACE->Set(String::New("PREALLOC"), Number::New(SDL_PREALLOC));
-
// SDL Enumerations start:
Local<Object> AUDIOFORMAT = Object::New();
@@ -198,29 +200,8 @@ init(Handle<Object> target)
Local<Object> WM = Object::New();
target->Set(String::New("WM"), WM);
- Local<Object> GL = Object::New();
- target->Set(String::New("GL"), GL);
-
-
- NODE_SET_METHOD(GL, "setAttribute", sdl::GL::SetAttribute);
- NODE_SET_METHOD(GL, "getAttribute", sdl::GL::GetAttribute);
-
- GL->Set(String::New("RED_SIZE"), Number::New(SDL_GL_RED_SIZE));
- GL->Set(String::New("GREEN_SIZE"), Number::New(SDL_GL_GREEN_SIZE));
- GL->Set(String::New("BLUE_SIZE"), Number::New(SDL_GL_BLUE_SIZE));
- GL->Set(String::New("ALPHA_SIZE"), Number::New(SDL_GL_ALPHA_SIZE));
- GL->Set(String::New("DOUBLEBUFFER"), Number::New(SDL_GL_DOUBLEBUFFER));
- GL->Set(String::New("BUFFER_SIZE"), Number::New(SDL_GL_BUFFER_SIZE));
- GL->Set(String::New("DEPTH_SIZE"), Number::New(SDL_GL_DEPTH_SIZE));
- GL->Set(String::New("STENCIL_SIZE"), Number::New(SDL_GL_STENCIL_SIZE));
- GL->Set(String::New("ACCUM_RED_SIZE"), Number::New(SDL_GL_ACCUM_RED_SIZE));
- GL->Set(String::New("ACCUM_GREEN_SIZE"), Number::New(SDL_GL_ACCUM_GREEN_SIZE));
- GL->Set(String::New("ACCUM_BLUE_SIZE"), Number::New(SDL_GL_ACCUM_BLUE_SIZE));
- GL->Set(String::New("ACCUM_ALPHA_SIZE"), Number::New(SDL_GL_ACCUM_ALPHA_SIZE));
-
Local<Object> HINT = Object::New();
target->Set(String::New("HINT"), HINT);
-
HINT->Set(String::New("FRAMEBUFFER_ACCELERATION"), String::New(SDL_HINT_FRAMEBUFFER_ACCELERATION));
HINT->Set(String::New("IDLE_TIMER_DISABLED"), String::New(SDL_HINT_IDLE_TIMER_DISABLED));
HINT->Set(String::New("ORIENTATIONS"), String::New(SDL_HINT_ORIENTATIONS));
@@ -228,10 +209,12 @@ init(Handle<Object> target)
HINT->Set(String::New("RENDER_OPENGL_SHADERS"), String::New(SDL_HINT_RENDER_OPENGL_SHADERS));
HINT->Set(String::New("SCALE_QUALITY"), String::New(SDL_HINT_RENDER_SCALE_QUALITY));
HINT->Set(String::New("RENDER_VSYNC"), String::New(SDL_HINT_RENDER_VSYNC));
+ HINT->Set(String::New("DEFAULT"), Number::New(SDL_HINT_DEFAULT));
+ HINT->Set(String::New("NORMAL"), Number::New(SDL_HINT_NORMAL));
+ HINT->Set(String::New("OVERRIDE"), Number::New(SDL_HINT_OVERRIDE));
Local<Object> RENDERER = Object::New();
target->Set(String::New("RENDERER"), RENDERER);
-
RENDERER->Set(String::New("SOFTWARE"), Number::New(SDL_RENDERER_SOFTWARE));
RENDERER->Set(String::New("ACCELERATED"), Number::New(SDL_RENDERER_ACCELERATED));
RENDERER->Set(String::New("PRESENTVSYNC"), Number::New(SDL_RENDERER_PRESENTVSYNC));
@@ -239,7 +222,6 @@ init(Handle<Object> target)
Local<Object> BLENDMODE = Object::New();
target->Set(String::New("BLENDMODE"), BLENDMODE);
-
BLENDMODE->Set(String::New("NONE"), Number::New(SDL_BLENDMODE_NONE));
BLENDMODE->Set(String::New("BLEND"), Number::New(SDL_BLENDMODE_BLEND));
BLENDMODE->Set(String::New("ADD"), Number::New(SDL_BLENDMODE_ADD));
@@ -247,7 +229,6 @@ init(Handle<Object> target)
Local<Object> FLIP = Object::New();
target->Set(String::New("FLIP"), FLIP);
-
FLIP->Set(String::New("NONE"), Number::New(SDL_FLIP_NONE));
FLIP->Set(String::New("HORIZONTAL"), Number::New(SDL_FLIP_HORIZONTAL));
FLIP->Set(String::New("VERTICAL"), Number::New(SDL_FLIP_VERTICAL));
@@ -822,6 +803,184 @@ Handle<Value> sdl::GetRGBA(const Arguments& args) {
return scope.Close(rgba);
}
+////////////////////////////////////////////////////////////////////////////////
+// SDL Hint Handling.
+static void HintCallbackHandler(void *userData, const char *name, const char *oldValue, const char *newValue) {
+ HandleScope scope;
+
+ Persistent<Function> callback = *static_cast<Persistent<Function>*>(userData);
+
+ Local<Value> nodeName = String::New(name);
+ Local<Value> nodeOldValue = String::New(oldValue);
+ Local<Value> nodeNewValue = String::New(newValue);
+
+ Local<Value> argv[3] = {nodeName, nodeOldValue, nodeNewValue};
+ Local<Value> retValue = callback->Call(Context::GetCurrent()->Global(), 3, argv);
+ Local<Boolean> ret = retValue->ToBoolean();
+ if(ret->BooleanValue()) {
+ SDL_DelHintCallback(name, HintCallbackHandler, userData);
+ callback.Dispose();
+ }
+}
+
+Handle<Value> sdl::AddHintCallback(const Arguments& args) {
+ HandleScope scope;
+
+ if(args.Length() < 2) {
+ return ThrowException(Exception::TypeError(
+ String::New("Invalid arguments: Expected AddHintCallback(String, Function)")));
+ }
+
+ String::Utf8Value name(args[0]);
+ Handle<Function> callback = Handle<Function>::Cast(args[1]);
+ Persistent<Function> userData = Persistent<Function>::New(callback);
+ SDL_AddHintCallback(*name, HintCallbackHandler, static_cast<void*>(&userData));
+
+ return Undefined();
+}
+// TODO: Implement a way to call SDL_ClearHints safely. Currently, because we store a Persistent
+// in the userData slot, this would leak memory due to those functions never being cleaned
+// up. Need some global list of Persistents to dispose of when this is called.
+// TODO: Also implement a wrapper around SDL_DelHintCallback. (need to return a token or something
+// when adding a callback, because it's likely most callbacks will be anonymous so we won't
+// have the exact same Persistent address)
+// Handle<Value> ClearHints(const Arguments& args) {
+// HandleScope scope;
+// return Undefined();
+// }
+Handle<Value> sdl::GetHint(const Arguments& args) {
+ HandleScope scope;
+
+ if(args.Length() < 1) {
+ return ThrowException(Exception::TypeError(
+ String::New("Invalid arguments: Expected GetHint(String)")));
+ }
+
+ String::Utf8Value name(args[0]);
+ const char *value = SDL_GetHint(*name);
+ if(NULL == value) {
+ return Undefined();
+ }
+
+ return scope.Close(String::New(value));
+}
+Handle<Value> sdl::SetHint(const Arguments& args) {
+ HandleScope scope;
+
+ if(args.Length() < 2) {
+ return ThrowException(Exception::TypeError(
+ String::New("Invalid arguments: Expected SetHint(String, String)")));
+ }
+
+ String::Utf8Value name(args[0]);
+ String::Utf8Value value(args[1]);
+ int err = SDL_SetHint(*name, *value);
+ if(err < 0) {
+ return ThrowSDLException(__func__);
+ }
+
+ return Undefined();
+}
+Handle<Value> sdl::SetHintWithPriority(const Arguments& args) {
+ HandleScope scope;
+
+ if(args.Length() < 3) {
+ return ThrowException(Exception::TypeError(
+ String::New("Invalid arguments: Excpected SetHintWithPriority(String, String, Number)")));
+ }
+
+ String::Utf8Value name(args[0]);
+ String::Utf8Value value(args[1]);
+ SDL_HintPriority priority = static_cast<SDL_HintPriority>(args[2]->Int32Value());
+ SDL_bool ret = SDL_SetHintWithPriority(*name, *value, priority);
+
+ return scope.Close(Boolean::New(ret ? true : false));
+}
+
+Handle<Value> sdl::CompiledVersion(const Arguments& args) {
+ HandleScope scope;
+
+ SDL_version version;
+ SDL_VERSION(&version);
+
+ Handle<Object> ret = Object::New();
+ ret->Set(String::New("major"), Number::New(version.major));
+ ret->Set(String::New("minor"), Number::New(version.minor));
+ ret->Set(String::New("patch"), Number::New(version.patch));
+
+ return scope.Close(ret);
+}
+Handle<Value> sdl::CompiledRevision(const Arguments& args) {
+ HandleScope scope;
+
+ Handle<String> ret = String::New(SDL_REVISION);
+
+ return scope.Close(ret);
+}
+Handle<Value> sdl::GetRevision(const Arguments& args) {
+ HandleScope scope;
+
+ const char *revision = SDL_GetRevision();
+ Handle<String> ret = String::New(revision);
+
+ return scope.Close(ret);
+}
+Handle<Value> sdl::GetRevisionNumber(const Arguments& args) {
+ HandleScope scope;
+
+ int revision = SDL_GetRevisionNumber();
+ Handle<Value> ret = Number::New(revision);
+
+ return scope.Close(ret);
+}
+Handle<Value> sdl::GetVersion(const Arguments& args) {
+ HandleScope scope;
+
+ SDL_version version;
+ SDL_GetVersion(&version);
+
+ Handle<Object> ret = Object::New();
+ ret->Set(String::New("major"), Number::New(version.major));
+ ret->Set(String::New("minor"), Number::New(version.minor));
+ ret->Set(String::New("patch"), Number::New(version.patch));
+
+ return scope.Close(ret);
+}
+
+Handle<Value> sdl::GetClipboardText(const Arguments& args) {
+ HandleScope scope;
+
+ char *text = SDL_GetClipboardText();
+ if(NULL == text) {
+ return ThrowSDLException(__func__);
+ }
+
+ return scope.Close(String::New(text));
+}
+Handle<Value> sdl::HasClipboardText(const Arguments& args) {
+ HandleScope scope;
+
+ SDL_bool has = SDL_HasClipboardText();
+
+ return scope.Close(Boolean::New(has ? true : false));
+}
+Handle<Value> sdl::SetClipboardText(const Arguments& args) {
+ HandleScope scope;
+
+ if(args.Length() < 1) {
+ return ThrowException(Exception::TypeError(
+ String::New("Invalid arguments: Expected SetClipboardText(String)")));
+ }
+
+ String::Utf8Value text(args[0]);
+ int err = SDL_SetClipboardText(*text);
+ if(err < 0) {
+ return ThrowSDLException(__func__);
+ }
+
+ return Undefined();
+}
+
Handle<Value> sdl::TTF::Init(const Arguments& args) {
HandleScope scope;
@@ -916,33 +1075,4 @@ Handle<Value> sdl::IMG::Load(const Arguments& args) {
return scope.Close(ret);
}
-Handle<Value> sdl::GL::SetAttribute(const Arguments& args) {
- HandleScope scope;
-
- if (!(args.Length() == 2 && args[0]->IsNumber() && args[1]->IsNumber())) {
- return ThrowException(Exception::TypeError(String::New("Invalid arguments: Expected SetAttribute(Number, Number)")));
- }
-
- int attr = args[0]->Int32Value();
- int value = args[1]->Int32Value();
-
- if (SDL_GL_SetAttribute((SDL_GLattr)attr, value)) return ThrowSDLException(__func__);
- return Undefined();
-}
-
-Handle<Value> sdl::GL::GetAttribute(const Arguments& args) {
- HandleScope scope;
-
- if (!(args.Length() == 1 && args[0]->IsNumber())) {
- return ThrowException(Exception::TypeError(String::New("Invalid arguments: Expected GetAttribute(Number)")));
- }
-
- int attr = args[0]->Int32Value();
- int value;
-
- if (SDL_GL_GetAttribute((SDL_GLattr)attr, &value)) return ThrowSDLException(__func__);
-
- return Number::New(value);
-}
-
NODE_MODULE(node_sdl, init)
View
22 src/node_sdl.h
@@ -73,6 +73,22 @@ namespace sdl {
v8::Handle<v8::Value> GetRGB(const v8::Arguments& args);
v8::Handle<v8::Value> GetRGBA(const v8::Arguments& args);
+ v8::Handle<v8::Value> AddHintCallback(const v8::Arguments& args);
+ // v8::Handle<v8::Value> ClearHints(const v8::Arguments& args);
+ v8::Handle<v8::Value> GetHint(const v8::Arguments& args);
+ v8::Handle<v8::Value> SetHint(const v8::Arguments& args);
+ v8::Handle<v8::Value> SetHintWithPriority(const v8::Arguments& args);
+
+ v8::Handle<v8::Value> CompiledVersion(const v8::Arguments& args);
+ v8::Handle<v8::Value> CompiledRevision(const v8::Arguments& args);
+ v8::Handle<v8::Value> GetRevision(const v8::Arguments& args);
+ v8::Handle<v8::Value> GetRevisionNumber(const v8::Arguments& args);
+ v8::Handle<v8::Value> GetVersion(const v8::Arguments& args);
+
+ v8::Handle<v8::Value> GetClipboardText(const v8::Arguments& args);
+ v8::Handle<v8::Value> HasClipboardText(const v8::Arguments& args);
+ v8::Handle<v8::Value> SetClipboardText(const v8::Arguments& args);
+
namespace TTF {
v8::Handle<v8::Value> Init(const v8::Arguments& args);
v8::Handle<v8::Value> OpenFont(const v8::Arguments& args);
@@ -85,12 +101,6 @@ namespace sdl {
namespace WM {
}
-
- namespace GL {
- v8::Handle<v8::Value> SetAttribute (const v8::Arguments& args);
- v8::Handle<v8::Value> GetAttribute (const v8::Arguments& args);
- }
-
}
#endif
View
308 src/sdl_gl.cc
@@ -0,0 +1,308 @@
+#include "sdl_gl.h"
+#include "window.h"
+#include "helpers.h"
+#include "texture.h"
+
+using namespace v8;
+using namespace node;
+
+
+void sdl::gl::Init(Handle<Object> exports) {
+ Local<Object> GL = Object::New();
+ exports->Set(String::New("GL"), GL);
+ ContextWrapper::Init(GL);
+
+ NODE_SET_METHOD(GL, "bindTexture", BindTexture);
+ NODE_SET_METHOD(GL, "unbindTexture", UnbindTexture);
+
+ NODE_SET_METHOD(GL, "extensionSupported", ExtensionSupported);
+
+ NODE_SET_METHOD(GL, "loadLibrary", LoadLibrary);
+ NODE_SET_METHOD(GL, "unloadLibrary", UnloadLibrary);
+
+ NODE_SET_METHOD(GL, "setAttribute", SetAttribute);
+ NODE_SET_METHOD(GL, "makeCurrent", MakeCurrent);
+ NODE_SET_METHOD(GL, "setSwapInterval", SetSwapInterval);
+
+ NODE_SET_METHOD(GL, "getAttribute", GetAttribute);
+ NODE_SET_METHOD(GL, "getCurrentContext", GetCurrentContext);
+ NODE_SET_METHOD(GL, "getCurrentWindow", GetCurrentWindow);
+ NODE_SET_METHOD(GL, "getDrawableSize", GetDrawableSize);
+ NODE_SET_METHOD(GL, "getSwapInterval", GetSwapInterval);
+
+ // SDL_GLattr enum.
+ GL->Set(String::New("RED_SIZE"), Number::New(SDL_GL_RED_SIZE));
+ GL->Set(String::New("GREEN_SIZE"), Number::New(SDL_GL_GREEN_SIZE));
+ GL->Set(String::New("BLUE_SIZE"), Number::New(SDL_GL_BLUE_SIZE));
+ GL->Set(String::New("ALPHA_SIZE"), Number::New(SDL_GL_ALPHA_SIZE));
+ GL->Set(String::New("BUFFER_SIZE"), Number::New(SDL_GL_BUFFER_SIZE));
+ GL->Set(String::New("DOUBLEBUFFER"), Number::New(SDL_GL_DOUBLEBUFFER));
+ GL->Set(String::New("DEPTH_SIZE"), Number::New(SDL_GL_DEPTH_SIZE));
+ GL->Set(String::New("STENCIL_SIZE"), Number::New(SDL_GL_STENCIL_SIZE));
+ GL->Set(String::New("ACCUM_RED_SIZE"), Number::New(SDL_GL_ACCUM_RED_SIZE));
+ GL->Set(String::New("ACCUM_GREEN_SIZE"), Number::New(SDL_GL_ACCUM_GREEN_SIZE));
+ GL->Set(String::New("ACCUM_BLUE_SIZE"), Number::New(SDL_GL_ACCUM_BLUE_SIZE));
+ GL->Set(String::New("ACCUM_ALPHA_SIZE"), Number::New(SDL_GL_ACCUM_ALPHA_SIZE));
+ GL->Set(String::New("STEREO"), Number::New(SDL_GL_STEREO));
+ GL->Set(String::New("MULTISAMPLEBUFFERS"), Number::New(SDL_GL_MULTISAMPLEBUFFERS));
+ GL->Set(String::New("MULTISAMPLESAMPLES"), Number::New(SDL_GL_MULTISAMPLESAMPLES));
+ GL->Set(String::New("ACCELERATED_VISUAL"), Number::New(SDL_GL_ACCELERATED_VISUAL));
+ GL->Set(String::New("RETAINED_BACKING"), Number::New(SDL_GL_RETAINED_BACKING));
+ GL->Set(String::New("CONTEXT_MAJOR_VERSION"), Number::New(SDL_GL_CONTEXT_MAJOR_VERSION));
+ GL->Set(String::New("CONTEXT_MINOR_VERSION"), Number::New(SDL_GL_CONTEXT_MINOR_VERSION));
+ GL->Set(String::New("CONTEXT_EGL"), Number::New(SDL_GL_CONTEXT_EGL));
+ GL->Set(String::New("CONTEXT_FLAGS"), Number::New(SDL_GL_CONTEXT_FLAGS));
+ GL->Set(String::New("CONTEXT_PROFILE_MASK"), Number::New(SDL_GL_CONTEXT_PROFILE_MASK));
+ GL->Set(String::New("SHARE_WITH_CURRENT_CONTEXT"), Number::New(SDL_GL_SHARE_WITH_CURRENT_CONTEXT));
+ GL->Set(String::New("FRAMEBUFFER_SRGB_CAPABLE"), Number::New(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE));
+ // SDL_GLprofile enum.
+ GL->Set(String::New("CONTEXT_PROFILE_CORE"), Number::New(SDL_GL_CONTEXT_PROFILE_CORE));
+ GL->Set(String::New("CONTEXT_PROFILE_COMPATIBILITY"), Number::New(SDL_GL_CONTEXT_PROFILE_COMPATIBILITY));
+ GL->Set(String::New("PROFILE_ES"), Number::New(SDL_GL_CONTEXT_PROFILE_ES));
+ // SDL_GLcontextFlag enum.
+ GL->Set(String::New("CONTEXT_DEBUG_FLAG"), Number::New(SDL_GL_CONTEXT_DEBUG_FLAG));
+ GL->Set(String::New("CONTEXT_FORWARD_COMPATIBLE_FLAG"), Number::New(SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG));
+ GL->Set(String::New("CONTEXT_ROBUST_ACCESS_FLAG"), Number::New(SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG));
+ GL->Set(String::New("CONTEXT_RESET_ISOLATION_FLAG"), Number::New(SDL_GL_CONTEXT_RESET_ISOLATION_FLAG));
+}
+
+Persistent<FunctionTemplate> sdl::gl::ContextWrapper::wrap_template_;
+
+sdl::gl::ContextWrapper::ContextWrapper() {
+}
+sdl::gl::ContextWrapper::ContextWrapper(Handle<Object> obj) {
+ Wrap(obj);
+}
+sdl::gl::ContextWrapper::~ContextWrapper() {
+ if(NULL != context_) {
+ SDL_GL_DeleteContext(context_);
+ }
+}
+
+void sdl::gl::ContextWrapper::Init(Handle<Object> exports) {
+ Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
+ wrap_template_ = Persistent<FunctionTemplate>::New(tpl);
+
+ wrap_template_->InstanceTemplate()->SetInternalFieldCount(1);
+ wrap_template_->SetClassName(String::NewSymbol("ContextWrapper"));
+}
+
+Handle<Value> sdl::gl::ContextWrapper::New(const Arguments& args) {
+ HandleScope scope;
+
+ if(args.Length() < 1) {
+ return ThrowException(Exception::TypeError(
+ String::New("Invalid arguments: Expected new sdl.ContextWrapper(Window)")));
+ }
+
+ WindowWrapper* window = ObjectWrap::Unwrap<WindowWrapper>(Handle<Object>::Cast(args[0]));
+ SDL_GLContext context = SDL_GL_CreateContext(window->window_);
+ if(NULL == context) {
+ return ThrowSDLException(__func__);
+ }
+
+ ContextWrapper* obj = new ContextWrapper();
+ obj->context_ = context;
+ obj->Wrap(args.This());
+ return args.This();
+}
+
+Handle<Value> sdl::gl::BindTexture(const Arguments& args) {
+ if(!args.IsConstructCall()) {
+ return ThrowException(Exception::TypeError(
+ String::New("Must create a Context with the new operator.")));
+ }
+
+ HandleScope scope;
+
+ if(args.Length() < 1) {
+ return ThrowException(Exception::TypeError(
+ String::New("Invalid arguments: Expected BindTexture(Texture)")));
+ }
+
+ TextureWrapper* obj = ObjectWrap::Unwrap<TextureWrapper>(Handle<Object>::Cast(args[0]));
+ float texw, texh;
+ int err = SDL_GL_BindTexture(obj->texture_, &texw, &texh);
+ if(err < 0) {
+ return ThrowSDLException(__func__);
+ }
+
+ Handle<Array> ret = Array::New(2);
+ ret->Set(0, Number::New(texw));
+ ret->Set(1, Number::New(texh));
+ return scope.Close(ret);
+}
+Handle<Value> sdl::gl::UnbindTexture(const Arguments& args) {
+ HandleScope scope;
+
+ if(args.Length() < 1) {
+ return ThrowException(Exception::TypeError(
+ String::New("Invalid arguments: Expected BindTexture(Texture)")));
+ }
+
+ TextureWrapper* obj = ObjectWrap::Unwrap<TextureWrapper>(Handle<Object>::Cast(args[0]));
+ int err = SDL_GL_UnbindTexture(obj->texture_);
+ if(err < 0) {
+ return ThrowSDLException(__func__);
+ }
+
+ return Undefined();
+}
+
+Handle<Value> sdl::gl::ExtensionSupported(const Arguments& args) {
+ HandleScope scope;
+
+ if(args.Length() < 1) {
+ return ThrowException(Exception::TypeError(
+ String::New("Invalid arguments: Expected ExtensionSupported(String)")));
+ }
+
+ String::Utf8Value name(args[0]);
+ SDL_bool ret = SDL_GL_ExtensionSupported(*name);
+ return scope.Close(Boolean::New(ret ? true : false));
+}
+
+Handle<Value> sdl::gl::LoadLibrary(const Arguments& args) {
+ HandleScope scope;
+
+ int err;
+ if(args[0]->IsUndefined()) {
+ err = SDL_GL_LoadLibrary(NULL);
+ }
+ else {
+ String::Utf8Value name(args[0]);
+ err = SDL_GL_LoadLibrary(*name);
+ }
+ if(err < 0) {
+ return ThrowSDLException(__func__);
+ }
+
+ return Undefined();
+}
+Handle<Value> sdl::gl::UnloadLibrary(const Arguments& args) {
+ HandleScope scope;
+
+ SDL_GL_UnloadLibrary();
+
+ return Undefined();
+}
+
+Handle<Value> sdl::gl::SetAttribute(const Arguments& args) {
+ HandleScope scope;
+
+ if (!(args.Length() == 2 && args[0]->IsNumber() && args[1]->IsNumber())) {
+ return ThrowException(Exception::TypeError(String::New("Invalid arguments: Expected SetAttribute(Number, Number)")));
+ }
+
+ int attr = args[0]->Int32Value();
+ int value = args[1]->Int32Value();
+
+ if (SDL_GL_SetAttribute((SDL_GLattr)attr, value)) return ThrowSDLException(__func__);
+ return Undefined();
+}
+Handle<Value> sdl::gl::MakeCurrent(const Arguments& args) {
+ HandleScope scope;
+
+ if(args.Length() < 2) {
+ return ThrowException(Exception::TypeError(
+ String::New("Invalid arguments: Expected MakeCurrent(Window, GLContext)")));
+ }
+
+ WindowWrapper* window = ObjectWrap::Unwrap<WindowWrapper>(Handle<Object>::Cast(args[0]));
+ ContextWrapper* context = ObjectWrap::Unwrap<ContextWrapper>(Handle<Object>::Cast(args[1]));
+ int err = SDL_GL_MakeCurrent(window->window_, context->context_);
+ if(err < 0) {
+ return ThrowSDLException(__func__);
+ }
+
+ return Undefined();
+}
+Handle<Value> sdl::gl::SetSwapInterval(const Arguments& args) {
+ HandleScope scope;
+
+ if(args.Length() < 1) {
+ return ThrowException(Exception::TypeError(
+ String::New("Invalid arguments: Exception SetSwapInterval(Number)")));
+ }
+
+ int interval = args[0]->Int32Value();
+ int err = SDL_GL_SetSwapInterval(interval);
+ if(err < 0) {
+ return ThrowSDLException(__func__);
+ }
+
+ return Undefined();
+}
+
+Handle<Value> sdl::gl::GetAttribute(const Arguments& args) {
+ HandleScope scope;
+
+ if (!(args.Length() == 1 && args[0]->IsNumber())) {
+ return ThrowException(Exception::TypeError(String::New("Invalid arguments: Expected GetAttribute(Number)")));
+ }
+
+ int attr = args[0]->Int32Value();
+ int value;
+
+ if (SDL_GL_GetAttribute((SDL_GLattr)attr, &value)) return ThrowSDLException(__func__);
+
+ return Number::New(value);
+}
+Handle<Value> sdl::gl::GetCurrentContext(const Arguments& args) {
+ HandleScope scope;
+
+ SDL_GLContext context = SDL_GL_GetCurrentContext();
+ if(NULL == context) {
+ return ThrowSDLException(__func__);
+ }
+
+ Handle<Object> newObj = Object::New();
+ ContextWrapper* wrap = new ContextWrapper(newObj);
+ wrap->context_ = context;
+ return scope.Close(newObj);
+}
+Handle<Value> sdl::gl::GetCurrentWindow(const Arguments& args) {
+ HandleScope scope;
+
+ SDL_Window* window = SDL_GL_GetCurrentWindow();
+ if(NULL == window) {
+ return ThrowSDLException(__func__);
+ }
+
+ Handle<Object> newObj = Object::New();
+ WindowWrapper* wrap = new WindowWrapper(newObj);
+ wrap->window_ = window;
+ return scope.Close(newObj);
+}
+// TODO: Migrate to WindowWrapper object.
+Handle<Value> sdl::gl::GetDrawableSize(const Arguments& args) {
+ HandleScope scope;
+
+ if(args.Length() < 1) {
+ return ThrowException(Exception::TypeError(
+ String::New("Invalid arguments: Expected GetDrawableSize(Window)")));
+ }
+
+ WindowWrapper* wrap = ObjectWrap::Unwrap<WindowWrapper>(Handle<Object>::Cast(args[0]));
+ int w, h;
+ SDL_GL_GetDrawableSize(wrap->window_, &w, &h);
+
+ Handle<Array> ret = Array::New(2);
+ ret->Set(0, Number::New(w));
+ ret->Set(0, Number::New(h));
+ return scope.Close(ret);
+}
+// TODO: Handle this somehow?
+// Theoretically handleable with Handle<External>, but I don't see any use in wrapping a function
+// pointer for Javascript. Better off loading addresses invisibly when SDL/OpenGl gets initialized
+// and providing an API to access the functions.
+// Handle<Value> sdl::gl::GetProcAddress(const Arguments& args) {
+// }
+Handle<Value> sdl::gl::GetSwapInterval(const Arguments& args) {
+ HandleScope scope;
+
+ int interval = SDL_GL_GetSwapInterval();
+ return scope.Close(Number::New(interval));
+}
+
+
View
48 src/sdl_gl.h
@@ -0,0 +1,48 @@
+#ifndef NODESDL_SDLGL_H
+#define NODESDL_SDLGL_H
+
+#include <v8.h>
+#include <node.h>
+
+#include "SDL.h"
+
+
+namespace sdl {
+ namespace gl {
+ void Init(v8::Handle<v8::Object> exports);
+
+ class ContextWrapper : node::ObjectWrap {
+ public:
+ ContextWrapper();
+ ContextWrapper(v8::Handle<v8::Object> obj);
+ ~ContextWrapper();
+
+ static v8::Persistent<v8::FunctionTemplate> wrap_template_;
+
+ static void Init(v8::Handle<v8::Object> exports);
+ static v8::Handle<v8::Value> New(const v8::Arguments& args);
+
+ SDL_GLContext context_;
+ };
+
+ v8::Handle<v8::Value> BindTexture(const v8::Arguments& args);
+ v8::Handle<v8::Value> UnbindTexture(const v8::Arguments& args);
+
+ v8::Handle<v8::Value> ExtensionSupported(const v8::Arguments& args);
+
+ v8::Handle<v8::Value> LoadLibrary(const v8::Arguments& args);
+ v8::Handle<v8::Value> UnloadLibrary(const v8::Arguments& args);
+
+ v8::Handle<v8::Value> SetAttribute(const v8::Arguments& args);
+ v8::Handle<v8::Value> MakeCurrent(const v8::Arguments& args);
+ v8::Handle<v8::Value> SetSwapInterval(const v8::Arguments& args);
+
+ v8::Handle<v8::Value> GetAttribute(const v8::Arguments& args);
+ v8::Handle<v8::Value> GetCurrentContext(const v8::Arguments& args);
+ v8::Handle<v8::Value> GetCurrentWindow(const v8::Arguments& args);
+ v8::Handle<v8::Value> GetDrawableSize(const v8::Arguments& args);
+ v8::Handle<v8::Value> GetSwapInterval(const v8::Arguments& args);
+ }
+}
+
+#endif
View
12 src/window.cc
@@ -14,6 +14,10 @@ Persistent<FunctionTemplate> sdl::WindowWrapper::window_wrap_template_;
sdl::WindowWrapper::WindowWrapper() {
}
+sdl::WindowWrapper::WindowWrapper(Handle<Object> obj) {
+ Wrap(obj);
+}
+
sdl::WindowWrapper::~WindowWrapper() {
if(NULL != window_) {
SDL_DestroyWindow(window_);
@@ -522,3 +526,11 @@ Handle<Value> sdl::WindowWrapper::UpdateWindowSurfaceRects(const Arguments& args
}
return Undefined();
}
+
+Handle<Value> sdl::WindowWrapper::Swap(const Arguments& args) {
+ HandleScope scope;
+
+ WindowWrapper* obj = ObjectWrap::Unwrap<WindowWrapper>(args.This());
+ SDL_GL_SwapWindow(obj->window_);
+ return Undefined();
+}
View
3  src/window.h
@@ -10,6 +10,7 @@ namespace sdl {
class WindowWrapper : public node::ObjectWrap {
public:
WindowWrapper();
+ WindowWrapper(v8::Handle<v8::Object> obj);
~WindowWrapper();
static v8::Persistent<v8::FunctionTemplate> window_wrap_template_;
@@ -62,6 +63,8 @@ namespace sdl {
static v8::Handle<v8::Value> UpdateWindowSurface(const v8::Arguments& args);
static v8::Handle<v8::Value> UpdateWindowSurfaceRects(const v8::Arguments& args);
+ static v8::Handle<v8::Value> Swap(const v8::Arguments& args);
+
SDL_Window* window_;
};
}
Please sign in to comment.
Something went wrong with that request. Please try again.