Ejemplo n.º 1
0
    def __init__(self, width, height, order="C"):
        self._key_color = None
        self._ch = np.full((height, width), 0x20, dtype=np.intc)
        self._fg = np.zeros((height, width), dtype="(3,)u1")
        self._bg = np.zeros((height, width), dtype="(3,)u1")
        self._order = tcod._internal.verify_order(order)

        # libtcod uses the root console for defaults.
        bkgnd_flag = alignment = 0
        if lib.TCOD_ctx.root != ffi.NULL:
            bkgnd_flag = lib.TCOD_ctx.root.bkgnd_flag
            alignment = lib.TCOD_ctx.root.alignment

        self._console_data = self.console_c = ffi.new(
            "struct TCOD_Console*",
            {
                "w": width,
                "h": height,
                "ch_array": ffi.cast("int*", self._ch.ctypes.data),
                "fg_array": ffi.cast("TCOD_color_t*", self._fg.ctypes.data),
                "bg_array": ffi.cast("TCOD_color_t*", self._bg.ctypes.data),
                "bkgnd_flag": bkgnd_flag,
                "alignment": alignment,
                "fore": (255, 255, 255),
                "back": (0, 0, 0),
            },
        )
Ejemplo n.º 2
0
    def sample_mgrid(self, mgrid):
        """Sample a mesh-grid array and return the result.

        The :any:`sample_ogrid` method performs better as there is a lot of
        overhead when working with large mesh-grids.

        Args:
            mgrid (numpy.ndarray): A mesh-grid array of points to sample.
                A contiguous array of type `numpy.float32` is preferred.

        Returns:
            numpy.ndarray: An array of sampled points.

                This array has the shape: ``mgrid.shape[:-1]``.
                The ``dtype`` is `numpy.float32`.
        """
        mgrid = np.ascontiguousarray(mgrid, np.float32)
        if mgrid.shape[0] != self.dimensions:
            raise ValueError('mgrid.shape[0] must equal self.dimensions, '
                             '%r[0] != %r' % (mgrid.shape, self.dimensions))
        out = np.ndarray(mgrid.shape[1:], np.float32)
        if mgrid.shape[1:] != out.shape:
            raise ValueError('mgrid.shape[1:] must equal out.shape, '
                             '%r[1:] != %r' % (mgrid.shape, out.shape))
        lib.NoiseSampleMeshGrid(self._tdl_noise_c, out.size,
                                ffi.cast('float*', mgrid.ctypes.data),
                                ffi.cast('float*', out.ctypes.data))
        return out
Ejemplo n.º 3
0
    def sample_ogrid(self, ogrid):
        """Sample an open mesh-grid array and return the result.

        Args
            ogrid (Sequence[Sequence[float]]): An open mesh-grid.

        Returns:
            numpy.ndarray: An array of sampled points.

                The ``shape`` is based on the lengths of the open mesh-grid
                arrays.
                The ``dtype`` is `numpy.float32`.
        """
        if len(ogrid) != self.dimensions:
            raise ValueError('len(ogrid) must equal self.dimensions, '
                             '%r != %r' % (len(ogrid), self.dimensions))
        ogrids = [np.ascontiguousarray(array, np.float32) for array in ogrid]
        out = np.ndarray([array.size for array in ogrids], np.float32)
        lib.NoiseSampleOpenMeshGrid(
            self._tdl_noise_c,
            len(ogrids),
            out.shape,
            [ffi.cast('float*', array.ctypes.data) for array in ogrids],
            ffi.cast('float*', out.ctypes.data),
        )
        return out
Ejemplo n.º 4
0
    def __init__(self, width, height, order='C'):
        self._key_color = None
        self._ch = np.zeros((height, width), dtype=np.intc)
        self._fg = np.zeros((height, width), dtype='(3,)u1')
        self._bg = np.zeros((height, width), dtype='(3,)u1')
        self._order = tcod._internal.verify_order(order)

        # libtcod uses the root console for defaults.
        bkgnd_flag = alignment = 0
        if lib.TCOD_ctx.root != ffi.NULL:
            bkgnd_flag = lib.TCOD_ctx.root.bkgnd_flag
            alignment = lib.TCOD_ctx.root.alignment

        self._console_data = self.console_c = ffi.new(
            'struct TCOD_Console*',
            {
                'w': width,
                'h': height,
                'ch_array': ffi.cast('int*', self._ch.ctypes.data),
                'fg_array': ffi.cast('TCOD_color_t*', self._fg.ctypes.data),
                'bg_array': ffi.cast('TCOD_color_t*', self._bg.ctypes.data),
                'bkgnd_flag': bkgnd_flag,
                'alignment': alignment,
                'fore': (255, 255, 255),
                'back': (0, 0, 0),
            },
        )
Ejemplo n.º 5
0
 def __setstate__(self, state):
     self._key_color = None
     self.__dict__.update(state)
     self._console_data.update(
         {
         'ch_array': ffi.cast('int*', self._ch.ctypes.data),
         'fg_array': ffi.cast('TCOD_color_t*', self._fg.ctypes.data),
         'bg_array': ffi.cast('TCOD_color_t*', self._bg.ctypes.data),
         }
     )
     self._console_data = self.console_c = ffi.new(
         'struct TCOD_Console*', self._console_data)
Ejemplo n.º 6
0
 def __setstate__(self, state):
     self._key_color = None
     self.__dict__.update(state)
     self._console_data.update(
         {
             "ch_array": ffi.cast("int*", self._ch.ctypes.data),
             "fg_array": ffi.cast("TCOD_color_t*", self._fg.ctypes.data),
             "bg_array": ffi.cast("TCOD_color_t*", self._bg.ctypes.data),
         }
     )
     self._console_data = self.console_c = ffi.new(
         "struct TCOD_Console*", self._console_data
     )
Ejemplo n.º 7
0
 def __as_cdata(self):
     return ffi.new('map_t *', (
         self.width,
         self.height,
         self.width * self.height,
         ffi.cast('cell_t*', self.__buffer.ctypes.data),
     ))
Ejemplo n.º 8
0
 def __init__(
     self,
     dimensions: int,
     algorithm: int = 2,
     implementation: int = SIMPLE,
     hurst: float = 0.5,
     lacunarity: float = 2.0,
     octaves: float = 4,
     seed: Optional[tcod.random.Random] = None,
 ):
     if not 0 < dimensions <= 4:
         raise ValueError("dimensions must be in range 0 < n <= 4, got %r" %
                          (dimensions, ))
     self._random = seed
     _random_c = seed.random_c if seed else ffi.NULL
     self._algorithm = algorithm
     self.noise_c = ffi.gc(
         ffi.cast(
             "struct TCOD_Noise*",
             lib.TCOD_noise_new(dimensions, hurst, lacunarity, _random_c),
         ),
         lib.TCOD_noise_delete,
     )
     self._tdl_noise_c = ffi.new("TDLNoise*",
                                 (self.noise_c, dimensions, 0, octaves))
     self.implementation = implementation  # sanity check
Ejemplo n.º 9
0
 def __as_cdata(self):
     return ffi.new('struct TCOD_Map*', (
         self.width,
         self.height,
         self.width * self.height,
         ffi.cast('struct TCOD_MapCell*', self.__buffer.ctypes.data),
     ))
Ejemplo n.º 10
0
    def _init_setup_console_data(self, order="C"):
        """Setup numpy arrays over libtcod data buffers."""
        global _root_console
        self._key_color = None
        if self.console_c == ffi.NULL:
            _root_console = self
            self._console_data = lib.TCOD_ctx.root
        else:
            self._console_data = ffi.cast(
                "struct TCOD_Console*", self.console_c
            )

        def unpack_color(color_data):
            """return a (height, width, 3) shaped array from an image struct"""
            color_buffer = ffi.buffer(color_data[0 : self.width * self.height])
            array = np.frombuffer(color_buffer, np.uint8)
            return array.reshape((self.height, self.width, 3))

        self._fg = unpack_color(self._console_data.fg_array)
        self._bg = unpack_color(self._console_data.bg_array)

        buf = self._console_data.ch_array
        buf = ffi.buffer(buf[0 : self.width * self.height])
        self._ch = np.frombuffer(buf, np.intc).reshape(
            (self.height, self.width)
        )

        self._order = tcod._internal.verify_order(order)
Ejemplo n.º 11
0
    def _init_setup_console_data(self, order='C'):
        """Setup numpy arrays over libtcod data buffers."""
        self._key_color = None
        if self.console_c == ffi.NULL:
            self._console_data = lib.TCOD_ctx.root
        else:
            self._console_data = ffi.cast('TCOD_console_data_t *',
                                          self.console_c)

        def unpack_color(color_data):
            """return a (height, width, 3) shaped array from an image struct"""
            color_buffer = ffi.buffer(color_data[0:self.width * self.height])
            array = np.frombuffer(color_buffer, np.uint8)
            return array.reshape((self.height, self.width, 3))

        self._fg = unpack_color(self._console_data.fg_array)
        self._bg = unpack_color(self._console_data.bg_array)

        buf = self._console_data.ch_array
        buf = ffi.buffer(buf[0:self.width * self.height])
        self._ch = np.frombuffer(buf, np.intc).reshape(
            (self.height, self.width))

        order = tcod._internal.verify_order(order)
        if order == 'F':
            self._fg = self._fg.transpose(1, 0, 2)
            self._bg = self._bg.transpose(1, 0, 2)
            self._ch = self._ch.transpose()
Ejemplo n.º 12
0
 def __init__(self, algorithm, seed=None):
     """Create a new instance using this algorithm and seed."""
     if seed is None:
         seed = random.getrandbits(32)
     self.random_c = ffi.gc(
         ffi.cast('mersenne_data_t*',
                  lib.TCOD_random_new_from_seed(algorithm,
                                                hash(seed) % (1 << 32))),
         lib.TCOD_random_delete)
Ejemplo n.º 13
0
    def __init__(
        self,
        width: int,
        height: int,
        order: str = "C",
        buffer: Optional[np.array] = None,
    ):
        self._key_color = None  # type: Optional[Tuple[int, int, int]]
        self._order = tcod._internal.verify_order(order)
        if buffer is not None:
            if self._order == "F":
                buffer = buffer.transpose()
            self._ch = np.ascontiguousarray(buffer["ch"], np.intc)
            self._fg = np.ascontiguousarray(buffer["fg"], "u1")
            self._bg = np.ascontiguousarray(buffer["bg"], "u1")
        else:
            self._ch = np.ndarray((height, width), dtype=np.intc)
            self._fg = np.ndarray((height, width), dtype=self._DTYPE_RGB)
            self._bg = np.ndarray((height, width), dtype=self._DTYPE_RGB)

        # libtcod uses the root console for defaults.
        default_bg_blend = 0
        default_alignment = 0
        if lib.TCOD_ctx.root != ffi.NULL:
            default_bg_blend = lib.TCOD_ctx.root.bkgnd_flag
            default_alignment = lib.TCOD_ctx.root.alignment

        self._console_data = self.console_c = ffi.new(
            "struct TCOD_Console*",
            {
                "w": width,
                "h": height,
                "ch_array": ffi.cast("int*", self._ch.ctypes.data),
                "fg_array": ffi.cast("TCOD_color_t*", self._fg.ctypes.data),
                "bg_array": ffi.cast("TCOD_color_t*", self._bg.ctypes.data),
                "bkgnd_flag": default_bg_blend,
                "alignment": default_alignment,
                "fore": (255, 255, 255),
                "back": (0, 0, 0),
            },
        )

        if buffer is None:
            self.clear()
Ejemplo n.º 14
0
 def __as_cdata(self) -> Any:
     return ffi.new(
         "struct TCOD_Map*",
         (
             self.width,
             self.height,
             self.width * self.height,
             ffi.cast("struct TCOD_MapCell*", self.__buffer.ctypes.data),
         ),
     )
Ejemplo n.º 15
0
    def get_tcod_path_ffi(self) -> Tuple[Any, Any, Tuple[int, int]]:
        if len(self.shape) != 2:
            raise ValueError("Array must have a 2d shape, shape is %r" %
                             (self.shape, ))
        if self.dtype.type not in self._C_ARRAY_CALLBACKS:
            raise ValueError("dtype must be one of %r, dtype is %r" %
                             (self._C_ARRAY_CALLBACKS.keys(), self.dtype.type))

        array_type, callback = self._C_ARRAY_CALLBACKS[self.dtype.type]
        userdata = ffi.new(
            "struct PathCostArray*",
            (ffi.cast("char*", self.ctypes.data), self.strides),
        )
        return callback, userdata, self.shape
Ejemplo n.º 16
0
    def get_tcod_path_ffi(self):
        if len(self.shape) != 2:
            raise ValueError('Array must have a 2d shape, shape is %r' %
                             (self.shape, ))
        if self.dtype.type not in self._C_ARRAY_CALLBACKS:
            raise ValueError('dtype must be one of %r, dtype is %r' %
                             (self._C_ARRAY_CALLBACKS.keys(), self.dtype.type))

        array_type, callback = \
            self._C_ARRAY_CALLBACKS[self.dtype.type]
        userdata = ffi.new(
            'PathCostArray*',
            (self.width, ffi.cast(array_type, self.ctypes.data)),
        )
        return callback, userdata, self.width, self.height
Ejemplo n.º 17
0
    def get_tile(self, codepoint: int) -> np.array:
        """Return a copy of a tile for the given codepoint.

        If the tile does not exist yet then a blank array will be returned.

        The tile will have a shape of (height, width, rgba) and a dtype of
        uint8.  Note that most grey-scale tiles will only use the alpha
        channel and will usually have a solid white color channel.
        """
        tile = np.zeros(self.tile_shape + (4, ), dtype=np.uint8)
        lib.TCOD_tileset_get_tile_(
            self._tileset_p,
            codepoint,
            ffi.cast("struct TCOD_ColorRGBA*", tile.ctypes.data),
        )
        return tile
Ejemplo n.º 18
0
 def __init__(
     self,
     algorithm: int = MERSENNE_TWISTER,
     seed: Optional[Hashable] = None,
 ):
     """Create a new instance using this algorithm and seed."""
     if seed is None:
         seed = random.getrandbits(32)
     self.random_c = ffi.gc(
         ffi.cast(
             "mersenne_data_t*",
             lib.TCOD_random_new_from_seed(algorithm,
                                           hash(seed) % (1 << 32)),
         ),
         lib.TCOD_random_delete,
     )
Ejemplo n.º 19
0
    def _init_setup_console_data(self, order: str = "C") -> None:
        """Setup numpy arrays over libtcod data buffers."""
        global _root_console
        self._key_color = None
        if self.console_c == ffi.NULL:
            _root_console = self
            self._console_data = lib.TCOD_ctx.root
        else:
            self._console_data = ffi.cast("struct TCOD_Console*",
                                          self.console_c)

        self._tiles = np.frombuffer(
            ffi.buffer(self._console_data.tiles[0:self.width * self.height]),
            dtype=self.DTYPE,
        ).reshape((self.height, self.width))

        self._order = tcod._internal.verify_order(order)
Ejemplo n.º 20
0
    def __setstate__(self, state: Any) -> None:
        self._key_color = None
        if "_tiles" not in state:
            tiles = np.ndarray((self.height, self.width), dtype=self.DTYPE)
            tiles["ch"] = state["_ch"]
            tiles["fg"][..., :3] = state["_fg"]
            tiles["fg"][..., 3] = 255
            tiles["bg"][..., :3] = state["_bg"]
            tiles["bg"][..., 3] = 255
            state["_tiles"] = tiles
            del state["_ch"]
            del state["_fg"]
            del state["_bg"]

        self.__dict__.update(state)
        self._console_data["tiles"] = ffi.cast("struct TCOD_ConsoleTile*",
                                               self._tiles.ctypes.data)
        self._console_data = self.console_c = ffi.new("struct TCOD_Console*",
                                                      self._console_data)
Ejemplo n.º 21
0
 def __init__(self, dimensions, algorithm=2, implementation=SIMPLE,
              hurst=0.5, lacunarity=2.0, octaves=4, seed=None):
     if not 0 < dimensions <= 4:
         raise ValueError('dimensions must be in range 0 < n <= 4, got %r' %
                          (dimensions,))
     self._random = seed
     _random_c = seed.random_c if seed else ffi.NULL
     self._algorithm = algorithm
     self.noise_c = ffi.gc(
         ffi.cast(
             'perlin_data_t*',
             lib.TCOD_noise_new(dimensions, hurst, lacunarity,
                                _random_c),
             ),
         lib.TCOD_noise_delete)
     self._tdl_noise_c = ffi.new('TDLNoise*', (self.noise_c,
                                               dimensions,
                                               0,
                                               octaves))
     self.implementation = implementation # sanity check
Ejemplo n.º 22
0
    def set_tile(self, codepoint: int, tile: np.array) -> None:
        """Upload a tile into this array.

        The tile can be in 32-bit color (height, width, rgba), or grey-scale
        (height, width).  The tile should have a dtype of ``np.uint8``.

        This data may need to be sent to graphics card memory, this is a slow
        operation.
        """
        tile = np.ascontiguousarray(tile, dtype=np.uint8)
        if tile.shape == self.tile_shape:
            full_tile = np.empty(self.tile_shape + (4, ), dtype=np.uint8)
            full_tile[:, :, :3] = 255
            full_tile[:, :, 3] = tile
            return self.set_tile(codepoint, full_tile)
        required = self.tile_shape + (4, )
        if tile.shape != required:
            raise ValueError("Tile shape must be %r or %r, got %r." %
                             (required, self.tile_shape, tile.shape))
        lib.TCOD_tileset_set_tile_(
            self._tileset_p,
            codepoint,
            ffi.cast("struct TCOD_ColorRGBA*", tile.ctypes.data),
        )
Ejemplo n.º 23
0
def _get_pathcost_func(
        name: str) -> Callable[[int, int, int, int, Any], float]:
    """Return a properly cast PathCostArray callback."""
    return ffi.cast(  # type: ignore
        "TCOD_path_func_t", ffi.addressof(lib, name))
Ejemplo n.º 24
0
def _get_pathcost_func(name):
    """Return a properly cast PathCostArray callback."""
    return ffi.cast('TCOD_path_func_t', ffi.addressof(lib, name))
Ejemplo n.º 25
0
def _get_pathcost_func(name):
    # type: (str) -> Callable[[int, int, int, int, cffi.CData], float]
    """Return a properly cast PathCostArray callback."""
    return ffi.cast("TCOD_path_func_t", ffi.addressof(lib, name))