Example #1
0
 def _init_thread(self):
     """ Complete SDL2 interface initialisation. """
     # initialise SDL
     sdl2.SDL_Init(sdl2.SDL_INIT_EVERYTHING)
     # set clipboard handler to SDL2
     backend.clipboard_handler = SDL2Clipboard()
     # display palettes for blink states 0, 1
     self.show_palette = [
         sdl2.SDL_AllocPalette(256),
         sdl2.SDL_AllocPalette(256)
     ]
     # get physical screen dimensions (needs to be called before set_mode)
     display_mode = sdl2.SDL_DisplayMode()
     sdl2.SDL_GetCurrentDisplayMode(0, ctypes.byref(display_mode))
     self.physical_size = display_mode.w, display_mode.h
     # create the window initially, size will be corrected later
     self.display = None
     # create window in same thread that manipulates it
     # "NOTE: You should not expect to be able to create a window, render, or receive events on any thread other than the main one"
     # https://wiki.libsdl.org/CategoryThread
     # http://stackoverflow.com/questions/27751533/sdl2-threading-seg-fault
     self._do_create_window(640, 400)
     # load an all-black 16-colour game palette to get started
     self.set_palette([(0, 0, 0)] * 16, None)
     self.move_cursor(1, 1)
     self.set_page(0, 0)
     self.set_mode(self.kwargs['initial_mode'])
     # support for CGA composite
     self.composite_palette = sdl2.SDL_AllocPalette(256)
     composite_colors = video_graphical.composite_640.get(
         self.composite_card, video_graphical.composite_640['cga'])
     colors = (sdl2.SDL_Color * 256)(
         *[sdl2.SDL_Color(r, g, b, 255) for (r, g, b) in composite_colors])
     sdl2.SDL_SetPaletteColors(self.composite_palette, colors, 0, 256)
     # check if we can honour scaling=smooth
     if self.smooth:
         # pointer to the zoomed surface
         self.zoomed = None
         pixelformat = self.display_surface.contents.format
         if pixelformat.contents.BitsPerPixel != 32:
             logging.warning(
                 'Smooth scaling not available on this display of %d-bit colour depth: needs 32-bit',
                 self.display_surface.format.contents.BitsPerPixel)
             self.smooth = False
         if not hasattr(sdl2, 'sdlgfx'):
             logging.warning(
                 'Smooth scaling not available: SDL_GFX extension not found.'
             )
             self.smooth = False
     # available joysticks
     num_joysticks = sdl2.SDL_NumJoysticks()
     for j in range(num_joysticks):
         sdl2.SDL_JoystickOpen(j)
         # if a joystick is present, its axes report 128 for mid, not 0
         for axis in (0, 1):
             backend.input_queue.put(
                 backend.Event(backend.STICK_MOVED, (j, axis, 128)))
Example #2
0
 def __init__(self, input_queue, video_queue, **kwargs):
     """Initialise SDL2 interface."""
     if not sdl2:
         logging.debug('PySDL2 module not found.')
         raise base.InitFailed()
     if not numpy:
         logging.debug('NumPy module not found.')
         raise base.InitFailed()
     video_graphical.VideoGraphical.__init__(self, input_queue, video_queue, **kwargs)
     # display & border
     # border attribute
     self.border_attr = 0
     # palette and colours
     # composite colour artifacts
     self.composite_artifacts = False
     # update cycle
     # refresh cycle parameters
     self._cycle = 0
     self.last_cycle = 0
     self._cycle_time = 120
     self.blink_cycles = 5
     # cursor
     # current cursor location
     self.last_row = 1
     self.last_col = 1
     # cursor is visible
     self.cursor_visible = True
     # load the icon
     self.icon = kwargs['icon']
     # mouse setups
     buttons = {'left': sdl2.SDL_BUTTON_LEFT, 'middle': sdl2.SDL_BUTTON_MIDDLE,
                'right': sdl2.SDL_BUTTON_RIGHT, 'none': None}
     copy_paste = kwargs.get('copy-paste', ('left', 'middle'))
     self.mousebutton_copy = buttons[copy_paste[0]]
     self.mousebutton_paste = buttons[copy_paste[1]]
     self.mousebutton_pen = buttons[kwargs.get('pen', 'right')]
     # keyboard setup
     self.f11_active = False
     self.altgr = kwargs['altgr']
     if not self.altgr:
         scan_to_scan[sdl2.SDL_SCANCODE_RALT] = scancode.ALT
         mod_to_scan[sdl2.KMOD_RALT] = scancode.ALT
     # keep params for enter
     self.kwargs = kwargs
     # we need a set_mode call to be really up and running
     self._has_window = False
     # ensure the correct SDL2 video driver is chosen for Windows
     # since this gets messed up if we also import pygame
     if platform.system() == 'Windows':
         os.environ['SDL_VIDEODRIVER'] = 'windows'
     # initialise SDL
     if sdl2.SDL_Init(sdl2.SDL_INIT_EVERYTHING):
         # SDL not initialised correctly
         logging.error('Could not initialise SDL2: %s', sdl2.SDL_GetError())
         raise base.InitFailed()
     display_mode = sdl2.SDL_DisplayMode()
     sdl2.SDL_GetCurrentDisplayMode(0, ctypes.byref(display_mode))
     self.physical_size = display_mode.w, display_mode.h
     # create the window initially as 640*400 black
     # "NOTE: You should not expect to be able to create a window, render, or receive events on any thread other than the main one"
     # https://wiki.libsdl.org/CategoryThread
     # http://stackoverflow.com/questions/27751533/sdl2-threading-seg-fault
     self.display = None
     self.work_surface = None
     self._do_create_window(*self._find_display_size(640, 400, self.border_width))
     # pop up as black rather than background, looks nicer
     sdl2.SDL_UpdateWindowSurface(self.display)
Example #3
0
def display_init(diagonal_in):
    """Initializes the display and rendering backend, calculating and assigning the values
		of runtime KLParams variables related to the screen (e.g. P.screen_c, P.refresh_rate,
		P.pixels_per_degree). Called by 'klibs run' on launch, for internal use only.
		
		Args:
			diagonal_in (float): The size of the monitor in diagonal inches (e.g. 13 for a
				13-inch MacBook Pro).

		"""
    if os.name == 'nt':
        # set video driver explicitly on Windows to avoid misdetection problems
        os.environ['SDL_VIDEODRIVER'] = 'windows'

    sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
    sdl2.mouse.SDL_ShowCursor(sdl2.SDL_DISABLE)
    sdl2.SDL_PumpEvents()

    display_mode = sdl2.video.SDL_DisplayMode()
    sdl2.SDL_GetCurrentDisplayMode(0, display_mode)

    P.screen_x = display_mode.w
    P.screen_y = display_mode.h
    P.screen_c = (P.screen_x // 2, P.screen_y // 2)
    P.screen_x_y = (P.screen_x, P.screen_y)

    P.refresh_rate = float(display_mode.refresh_rate)
    if P.refresh_rate == 0:
        P.refresh_rate = 60.0
        print(
            "\tWarning: Unable to detect your monitor's refresh rate, defaulting to 60Hz."
        )
    elif P.refresh_rate == 59:
        P.refresh_rate = 59.94  # fix for some Windows monitors
    P.refresh_time = 1000.0 / P.refresh_rate

    #TODO: figure out what's actually needed for multi-monitor support
    for d in P.additional_displays:
        if d[2]:
            P.screen_x_y = list(d[1])
            P.screen_x = d[1][0]
            P.screen_y = d[1][1]

    if P.screen_origin is None:
        P.screen_origin = (0, 0)

    # Get conversion factor for pixels to degrees of visual angle based on viewing distance,
    # screen resolution, and given diagonal screen size
    P.screen_diagonal_in = diagonal_in
    P.screen_diagonal_px = sqrt(P.screen_x**2.0 + P.screen_y**2.0)
    P.ppi = P.screen_diagonal_px / diagonal_in
    P.monitor_height = P.screen_y / P.ppi
    P.monitor_width = P.screen_x / P.ppi
    P.screen_degrees_x = degrees(2 * atan(
        (2.54 * P.monitor_width / 2.0) / P.view_distance))
    P.screen_degrees_y = degrees(2 * atan(
        (2.54 * P.monitor_height / 2.0) / P.view_distance))
    P.pixels_per_degree = P.screen_x / P.screen_degrees_x
    P.ppd = P.pixels_per_degree  # alias for convenience

    # Create the SDL window object and configure it properly for OpenGL (code from Mike)
    SCREEN_FLAGS = (sdl2.SDL_WINDOW_SHOWN | sdl2.SDL_WINDOW_FULLSCREEN_DESKTOP
                    | sdl2.SDL_WINDOW_OPENGL | sdl2.SDL_WINDOW_ALLOW_HIGHDPI)
    window = sdl2.ext.Window(P.project_name, P.screen_x_y, P.screen_origin,
                             SCREEN_FLAGS)
    sdl2.SDL_GL_CreateContext(window.window)
    sdl2.SDL_GL_SetSwapInterval(1)  # enforce vsync
    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.glLoadIdentity()
    gl.glOrtho(0, P.screen_x, P.screen_y, 0, 0, 1)
    gl.glMatrixMode(gl.GL_MODELVIEW)
    gl.glDisable(gl.GL_DEPTH_TEST)

    # Clear the SDL event queue and open the window, returning the window object
    sdl2.SDL_PumpEvents()
    sdl2.mouse.SDL_ShowCursor(sdl2.SDL_DISABLE)
    window.show()
    P.display_initialized = True
    return window