diff pytouhou/lib/glfw.pyx @ 636:4fa0a8e7d941

Add a GLFW implementation of gui.Window.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sun, 14 May 2017 20:14:03 +0100
parents
children f953ae5b3732
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/pytouhou/lib/glfw.pyx
@@ -0,0 +1,128 @@
+# -*- encoding: utf-8 -*-
+##
+## Copyright (C) 2016 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published
+## by the Free Software Foundation; version 3 only.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+
+from .gui cimport SHOOT, BOMB, FOCUS, UP, DOWN, LEFT, RIGHT, SKIP
+
+CLIENT_API = GLFW_CLIENT_API
+OPENGL_PROFILE = GLFW_OPENGL_PROFILE
+CONTEXT_VERSION_MAJOR = GLFW_CONTEXT_VERSION_MAJOR
+CONTEXT_VERSION_MINOR = GLFW_CONTEXT_VERSION_MINOR
+DEPTH_BITS = GLFW_DEPTH_BITS
+ALPHA_BITS = GLFW_ALPHA_BITS
+RESIZABLE = GLFW_RESIZABLE
+DOUBLEBUFFER = GLFW_DOUBLEBUFFER
+
+OPENGL_API = GLFW_OPENGL_API
+OPENGL_ES_API = GLFW_OPENGL_ES_API
+OPENGL_CORE_PROFILE = GLFW_OPENGL_CORE_PROFILE
+
+cdef void error_callback(int a, const char* b):
+    print('GLFW error 0x%x: %s' % (a, b.decode('utf-8')))
+
+cdef list _global_events = []
+
+cdef void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods):
+    if action != GLFW_PRESS:
+        return
+    if key == GLFW_KEY_ESCAPE:
+        _global_events.append((gui.PAUSE, None))
+    elif key in (GLFW_KEY_P, GLFW_KEY_HOME):
+        _global_events.append((gui.SCREENSHOT, None))
+    elif key == GLFW_KEY_DOWN:
+        _global_events.append((gui.DOWN, None))
+    elif key == GLFW_KEY_F11:
+        _global_events.append((gui.FULLSCREEN, None))
+    elif key == GLFW_KEY_ENTER:
+        if mods & GLFW_MOD_ALT:
+            _global_events.append((gui.FULLSCREEN, None))
+
+cdef void size_callback(GLFWwindow* window, int width, int height):
+    _global_events.append((gui.RESIZE, (width, height)))
+
+cdef void close_callback(GLFWwindow* window):
+    _global_events.append((gui.EXIT, None))
+
+cdef void init() except *:
+    glfwSetErrorCallback(<GLFWerrorfun>error_callback)
+    ret = glfwInit()
+    if not ret:
+        raise Exception('TODO')
+
+cdef void terminate() nogil:
+    glfwTerminate()
+
+cdef void window_hint(int hint, int value) nogil:
+    glfwWindowHint(hint, value)
+
+cdef class Window:
+    def __init__(self, int width, int height, str title, Monitor monitor=None, Window share=None):
+        cdef GLFWmonitor* c_monitor = NULL
+        cdef GLFWwindow* c_share = NULL
+        if monitor is not None:
+            c_monitor = monitor.monitor
+        if share is not None:
+            c_share = share.window
+        self.window = glfwCreateWindow(width, height, title.encode('utf-8'), c_monitor, c_share)
+        if self.window == NULL:
+            raise Exception('TODO')
+        glfwSetFramebufferSizeCallback(self.window, <GLFWframebuffersizefun>size_callback)
+        glfwSetWindowCloseCallback(self.window, <GLFWwindowclosefun>close_callback)
+        glfwSetKeyCallback(self.window, <GLFWkeyfun>key_callback)
+
+    def __del__(self):
+        glfwDestroyWindow(self.window)
+
+    cdef void create_gl_context(self) except *:
+        glfwMakeContextCurrent(self.window)
+
+    cdef void present(self) nogil:
+        glfwSwapBuffers(self.window)
+
+    cdef void set_window_size(self, int width, int height) nogil:
+        pass
+
+    cdef list get_events(self):
+        glfwPollEvents()
+        events = _global_events[:]
+        _global_events.clear()
+        return events
+
+    cdef void toggle_fullscreen(self) nogil:
+        monitor = glfwGetWindowMonitor(self.window)
+        if monitor == NULL:
+            monitor = glfwGetPrimaryMonitor()
+        else:
+            monitor = NULL
+        # TODO: save the previous size.
+        glfwSetWindowMonitor(self.window, monitor, 0, 0, 640, 480, 60)
+
+    cdef int get_keystate(self) nogil:
+        cdef int keystate = 0
+        if glfwGetKey(self.window, GLFW_KEY_Z):
+            keystate |= SHOOT
+        if glfwGetKey(self.window, GLFW_KEY_X):
+            keystate |= BOMB
+        if glfwGetKey(self.window, GLFW_KEY_LEFT_SHIFT):
+            keystate |= FOCUS
+        if glfwGetKey(self.window, GLFW_KEY_UP):
+            keystate |= UP
+        if glfwGetKey(self.window, GLFW_KEY_DOWN):
+            keystate |= DOWN
+        if glfwGetKey(self.window, GLFW_KEY_LEFT):
+            keystate |= LEFT
+        if glfwGetKey(self.window, GLFW_KEY_RIGHT):
+            keystate |= RIGHT
+        if glfwGetKey(self.window, GLFW_KEY_LEFT_CONTROL):
+            keystate |= SKIP
+        return keystate