Package tdl
[frames] | no frames]

Source Code for Package tdl

  1  """ 
  2      The documentation for python-tdl.  A Pythonic port of 
  3      U{libtcod<http://doryen.eptalys.net/libtcod/>}. 
  4       
  5      Getting Started 
  6      =============== 
  7        Once the library is imported you can load the font you want to use with 
  8        L{tdl.setFont}.  This is optional and can be skipped to get a decent 
  9        default font.  After that you call L{tdl.init} to set the size of the 
 10        window and get the root console in return.  This console is the canvas 
 11        to what will appear on the screen. 
 12       
 13      Drawing 
 14      ======= 
 15        Once you have the root console from L{tdl.init} you can start drawing on 
 16        it using a method such as L{Console.drawChar}.  When using this method 
 17        you can have the char parameter be an intiger or a single character 
 18        string.  The fgcolor and bgcolor parameters expect a three item list 
 19        [red, green, blue] with integers in the 0-255 range with [0, 0, 0] being 
 20        black and [255, 255, 255] being white.  Or instead you can use None for 
 21        any of the three parameters to tell the library to keep what is at that 
 22        spot instead of overwriting it.  After the drawing functions are called 
 23        a call to L{tdl.flush} will update the screen. 
 24  """ 
 25   
 26  import sys 
 27  import os 
 28  import ctypes 
 29  import weakref 
 30  import array 
 31  import itertools 
 32   
 33  from . import event 
 34  from .__tcod import _lib, _Color, _unpackfile 
 35   
 36  _IS_PYTHON3 = (sys.version_info[0] == 3) 
 37  _USE_FILL = False 
 38  'Set to True to use the libtcod fill optimization.  This is actually slower than the normal mode.' 
39 40 -def _format_string(string): # still used for filepaths, and that's about it
41 "changes string into bytes if running in python 3, for sending to ctypes" 42 if _IS_PYTHON3 and isinstance(string, str): 43 return string.encode() 44 return string 45
46 #def _encodeString(string): 47 # pass 48 49 -def _formatChar(char):
50 """Prepares a single character for passing to ctypes calls, needs to return 51 an integer but can also pass None which will keep the current character 52 instead of overrwriting it. 53 54 This is called often and needs to be optimized whenever possible. 55 """ 56 if char is None: 57 return None 58 if isinstance(char, int) or not _IS_PYTHON3 and isinstance(char, long): 59 return char 60 if isinstance(char, (str, bytes)) and len(char) == 1: 61 return ord(char) 62 raise TypeError('Expected char parameter to be a single character string, number, or None, got: %s' % repr(char))
63 64 _fontinitialized = False 65 _rootinitialized = False 66 _rootconsole = None 67 # remove dots from common functions 68 _setchar = _lib.TCOD_console_set_char 69 _setfore = _lib.TCOD_console_set_char_foreground 70 _setback = _lib.TCOD_console_set_char_background 71 _setcharEX = _lib.TCOD_console_put_char_ex
72 -def _verify_colors(*colors):
73 """Used internally. 74 Raise an assertion error if the parameters can not be converted into colors. 75 """ 76 for color in colors: 77 assert _iscolor(color), 'a color must be a 3 item tuple, web format, or None, received %s' % repr(color) 78 return True
79
80 -def _iscolor(color):
81 """Used internally. 82 A debug function to see if an object can be used as a TCOD color struct. 83 None counts as a parameter to keep the current colors instead. 84 85 This function is often part of an inner-loop and can slow a program down. 86 It has been made to work with assert and can be skipped with the -O flag. 87 Still it's called often and must be optimized. 88 """ 89 if color is None: 90 return True 91 if isinstance(color, (tuple, list, _Color)): 92 return len(color) == 3 93 if isinstance(color, int) or not _IS_PYTHON3 and isinstance(color, long): 94 return True 95 return False
96
97 -def _formatColor(color):
98 """Format the color to ctypes 99 """ 100 if color is None: 101 return None 102 # avoid isinstance, checking __class__ gives a small speed increase 103 if color.__class__ is _Color: 104 return color 105 if isinstance(color, int) or not _IS_PYTHON3 and isinstance(color, long): 106 # format a web style color with the format 0xRRGGBB 107 return _Color(color >> 16 & 0xff, color >> 8 & 0xff, color & 0xff) 108 return _Color(*color)
109
110 -class TDLError(Exception):
111 """ 112 The catch all for most TDL specific errors. 113 """
114
115 -class _MetaConsole(object):
116 """ 117 Contains methods shared by both the L{Console} and L{Window} classes. 118 """ 119 __slots__ = ('width', 'height', '__weakref__', '__dict__') 120
121 - def drawChar(self, x, y, char, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
122 """Draws a single character. 123 124 @type x: int 125 @type y: int 126 @type char: int, string, or None 127 @type fgcolor: 3-item list or None 128 @type bgcolor: 3-item list or None 129 @param char: Should be an integer, single character string, or None. 130 131 You can set the char parameter as None if you only want to change 132 the colors of the tile. 133 134 @param fgcolor: For fgcolor and bgcolor you use a 3 item list with integers ranging 0 - 255 or None. 135 None will keep the current color at this position unchanged. 136 137 138 @raise AssertionError: Having the x or y values outside of the console will raise an 139 AssertionError. You can use ((x, y) in console) 140 to check if a cell is drawable. 141 """ 142 143 assert _verify_colors(fgcolor, bgcolor) 144 assert self._drawable(x, y) 145 146 self._setChar(x, y, _formatChar(char), 147 _formatColor(fgcolor), _formatColor(bgcolor))
148
149 - def drawStr(self, x, y, string, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
150 """Draws a string starting at x and y. Optinally colored. 151 152 A string that goes past the right side will wrap around. A string 153 wraping to below the console will raise a L{TDLError} but will still be 154 written out. This means you can safely ignore the errors with a 155 try... except block if you're fine with partily written strings. 156 157 \\r and \\n are drawn on the console as normal character tiles. No 158 special encoding is done and any string will translate to the character 159 table as is. 160 161 fgcolor and bgcolor can be set to None to keep the colors unchanged. 162 163 @type x: int 164 @type y: int 165 @type string: string or iterable 166 @type fgcolor: 3-item list or None 167 @type bgcolor: 3-item list or None 168 169 """ 170 171 assert self._drawable(x, y) 172 assert _verify_colors(fgcolor, bgcolor) 173 fgcolor, bgcolor = _formatColor(fgcolor), _formatColor(bgcolor) 174 width, height = self.getSize() 175 for char in string: 176 if y == height: 177 raise TDLError('End of console reached.') 178 self._setChar(x, y, _formatChar(char), fgcolor, bgcolor) 179 x += 1 # advance cursor 180 if x == width: # line break 181 x = 0 182 y += 1
183
184 - def drawRect(self, x, y, width, height, string, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
185 """Draws a rectangle starting from x and y and extending to width and 186 height. If width or height are None then it will extend to the edge 187 of the console. The rest are the same as drawChar. 188 189 @type x: int 190 @type y: int 191 @type width: int or None 192 @type height: int or None 193 @type string: int, string, or None 194 @type fgcolor: 3-item list or None 195 @type bgcolor: 3-item list or None 196 """ 197 x, y, width, height = self._normalizeRect(x, y, width, height) 198 assert _verify_colors(fgcolor, bgcolor) 199 fgcolor, bgcolor = _formatColor(fgcolor), _formatColor(bgcolor) 200 char = _formatChar(string) 201 for cellY in range(y, y + height): 202 for cellX in range(x, x + width): 203 self._setChar(cellX, cellY, char, fgcolor, bgcolor)
204
205 - def drawFrame(self, x, y, width, height, string, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
206 """Similar to drawRect but only draws the outline of the rectangle. 207 208 @type x: int 209 @type y: int 210 @type width: int or None 211 @type height: int or None 212 @type string: int, string, or None 213 @type fgcolor: 3-item list or None 214 @type bgcolor: 3-item list or None 215 """ 216 x, y, width, height = self._normalizeRect(x, y, width, height) 217 assert _verify_colors(fgcolor, bgcolor) 218 fgcolor, bgcolor = _formatColor(fgcolor), _formatColor(bgcolor) 219 char = _formatChar(string) 220 if width == 1 or height == 1: # it's just a single width line here 221 return self.drawRect(x, y, width, height, char, fgcolor, bgcolor) 222 223 # draw sides of frame with drawRect 224 self.drawRect(x, y, 1, height, char, fgcolor, bgcolor) 225 self.drawRect(x, y, width, 1, char, fgcolor, bgcolor) 226 self.drawRect(x + width - 1, y, 1, height, char, fgcolor, bgcolor) 227 self.drawRect(x, y + height - 1, width, 1, char, fgcolor, bgcolor)
228 229
230 - def _normalizeRect(self, x, y, width, height):
231 """Check if the rectangle is in bounds and make minor adjustments. 232 raise AssertionError's for any problems 233 """ 234 old = x, y, width, height 235 assert isinstance(x, int), 'x must be an integer, got %s' % repr(x) 236 assert isinstance(y, int), 'y must be an integer, got %s' % repr(y) 237 if width == None: # if width or height are None then extend them to the edge 238 width = self.width - x 239 if height == None: 240 height = self.height - y 241 assert isinstance(width, int), 'width must be an integer or None, got %s' % repr(width) 242 assert isinstance(height, int), 'height must be an integer or None, got %s' % repr(height) 243 244 assert width >= 0 and height >= 0, 'width and height cannot be negative' 245 # later idea, negative numbers work like Python list indexing 246 247 assert x >= 0 and y >= 0 and x + width <= self.width and y + height <= self.height, \ 248 'Rect is out of bounds at (x=%i y=%i width=%i height=%i), Console bounds are (width=%i, height=%i)' % (old + self.getSize()) 249 return x, y, width, height
250
251 - def _rectInBounds(self, x, y, width, height):
252 "check the rect so see if it's within the bounds of this console" 253 if width is None: 254 width = 0 255 if height is None: 256 height = 0 257 if (x < 0 or y < 0 or 258 x + width > self.width or y + height > self.height): 259 return False 260 261 return True
262
263 - def _clampRect(self, x=0, y=0, width=None, height=None):
264 """Alter a rectange to fit inside of this console 265 266 width and hight of None will extend to the edge and 267 an area out of bounds will end with a width and height of 0 268 """ 269 # extend any width and height of None to the end of the console 270 if width is None: 271 width = self.width - x 272 if height is None: 273 height = self.height - y 274 # move x and y within bounds, shrinking the width and height to match 275 if x < 0: 276 width += x 277 x = 0 278 if y < 0: 279 height += y 280 y = 0 281 # move width and height within bounds 282 width = min(width, self.width - x) 283 height = min(height, self.height - y) 284 # a rect that was out of bounds will have a 0 or negative width or height at this point 285 if width <= 0 or height <= 0: 286 width = height = 0 287 return x, y, width, height
288
289 - def blit(self, source, x=0, y=0, width=None, height=None, srcX=0, srcY=0):
290 """Blit another console or Window onto the current console. 291 292 By default it blits the entire source to the topleft corner. 293 294 @type source: Console or Window 295 @type x: int 296 @type y: int 297 @type width: int or None 298 @type height: int or None 299 @type srcX: int 300 @type srcY: int 301 """ 302 # hardcode alpha settings for now 303 fgalpha=1.0 304 bgalpha=1.0 305 306 assert isinstance(source, (Console, Window)), "source muse be a Window or Console instance" 307 308 assert width is None or isinstance(width, (int)), "width must be a number or None, got %s" % repr(width) 309 assert height is None or isinstance(height, (int)), "height must be a number or None, got %s" % repr(height) 310 311 # fill in width, height 312 if width == None: 313 width = min(self.width - x, source.width - srcX) 314 if height == None: 315 height = min(self.height - y, source.height - srcY) 316 317 x, y, width, height = self._normalizeRect(x, y, width, height) 318 srcX, srcY, width, height = source._normalizeRect(srcX, srcY, width, height) 319 320 # translate source and self if any of them are Window instances 321 if isinstance(source, Window): 322 srcX, srcY = source._translate(srcX, srcY) 323 source = source.console 324 325 if isinstance(self, Window): 326 x, y = self._translate(x, y) 327 self = self.console 328 329 if self == source: 330 # if we are the same console then we need a third console to hold 331 # onto the data, otherwise it tries to copy into itself and 332 # starts destroying everything 333 tmp = Console(width, height) 334 _lib.TCOD_console_blit(source, srcX, srcY, width, height, tmp, 0, 0, fgalpha, bgalpha) 335 _lib.TCOD_console_blit(tmp, 0, 0, width, height, self, x, y, fgalpha, bgalpha) 336 else: 337 _lib.TCOD_console_blit(source, srcX, srcY, width, height, self, x, y, fgalpha, bgalpha)
338
339 - def getSize(self):
340 """Return the size of the console as (width, height) 341 342 @rtype: (int, int) 343 """ 344 return self.width, self.height
345
346 - def scroll(self, x, y):
347 """Scroll the contents of the console in the direction of x,y. 348 349 Uncovered areas will be cleared. 350 @type x: int 351 @type y: int 352 """ 353 assert isinstance(x, int), "x must be an integer, got %s" % repr(x) 354 assert isinstance(y, int), "y must be an integer, got %s" % repr(x) 355 def getSlide(x, length): 356 """get the parameters needed to scroll the console in the given 357 direction with x 358 returns (x, length, srcx) 359 """ 360 if x > 0: 361 srcx = 0 362 length -= x 363 elif x < 0: 364 srcx = abs(x) 365 x = 0 366 length -= srcx 367 else: 368 srcx = 0 369 return x, length, srcx
370 def getCover(x, length): 371 """return the (x, width) ranges of what is covered and uncovered""" 372 cover = (0, length) # everything covered 373 uncover = None # nothing uncovered 374 if x > 0: # left side uncovered 375 cover = (x, length - x) 376 uncover = (0, x) 377 elif x < 0: # right side uncovered 378 x = abs(x) 379 cover = (0, length - x) 380 uncover = (length - x, x) 381 return cover, uncover
382 383 width, height = self.getSize() 384 if abs(x) >= width or abs(y) >= height: 385 return self.clear() # just clear the console normally 386 387 # get the ranges of the areas that will be uncovered 388 coverX, uncoverX = getCover(x, width) 389 coverY, uncoverY = getCover(y, height) 390 # so at this point we know that coverX and coverY makes a rect that 391 # encases the area that we end up blitting to. uncoverX/Y makes a 392 # rect in the corner of the uncovered area. So we need to combine 393 # the uncoverX/Y with coverY/X to make what's left of the uncovered 394 # area. Explaining it makes it mush easier to do now. 395 396 # But first we need to blit. 397 x, width, srcx = getSlide(x, width) 398 y, height, srcy = getSlide(y, height) 399 self.blit(self, x, y, width, height, srcx, srcy) 400 401 if uncoverX: # clear sides (0x20 is space) 402 self.drawRect(uncoverX[0], coverY[0], uncoverX[1], coverY[1], 0x20) 403 if uncoverY: # clear top/bottom 404 self.drawRect(coverX[0], uncoverY[0], coverX[1], uncoverY[1], 0x20) 405 if uncoverX and uncoverY: # clear corner 406 self.drawRect(uncoverX[0], uncoverY[0], uncoverX[1], uncoverY[1], 0x20) 407
408 - def __contains__(self, position):
409 """Use ((x, y) in console) to check if a position is drawable on this console. 410 """ 411 x, y = position 412 return (0 <= x < self.width) and (0 <= y < self.height)
413
414 - def _drawable(self, x, y):
415 """Used internally 416 Checks if a cell is part of the console. 417 Raises an AssertionError if it can not be used. 418 """ 419 assert isinstance(x, int), 'x must be an integer, got %s' % repr(x) 420 assert isinstance(y, int), 'y must be an integer, got %s' % repr(y) 421 422 assert (0 <= x < self.width) and (0 <= y < self.height), \ 423 ('(%i, %i) is an invalid postition. %s size is (%i, %i)' % 424 (x, y, self.__class__.__name__, self.width, self.height)) 425 return True
426
427 -class Console(_MetaConsole):
428 """The Console is the main class of the tdl library. 429 430 The console created by the L{tdl.init} function is the root console and is the 431 consle that is rendered to the screen with flush. 432 433 Any console made from Console is an off-screen console that can be drawn 434 on and then L{blit} to the root console. 435 """ 436 437 __slots__ = ('_as_parameter_',) 438
439 - def __init__(self, width, height):
440 """Create a new offscreen console 441 """ 442 self._as_parameter_ = _lib.TCOD_console_new(width, height) 443 self.width = width 444 self.height = height 445 self._initArrays()
446 #self.clear() 447 448 @classmethod
449 - def _newConsole(cls, console):
450 """Make a Console instance, from a console ctype""" 451 self = cls.__new__(cls) 452 self._as_parameter_ = console 453 self.width = _lib.TCOD_console_get_width(self) 454 self.height = _lib.TCOD_console_get_height(self) 455 self._initArrays() 456 #self.clear() 457 return self
458
459 - def _initArrays(self):
460 if not _USE_FILL: 461 return 462 # used for the libtcod fill optimization 463 IntArray = ctypes.c_int * (self.width * self.height) 464 self.chArray = IntArray() 465 self.fgArrays = (IntArray(), 466 IntArray(), 467 IntArray()) 468 self.bgArrays = (IntArray(), 469 IntArray(), 470 IntArray())
471
472 - def __del__(self):
473 """ 474 If the main console is garbage collected then the window will be closed as well 475 """ 476 # If this is the root console the window will close when collected 477 try: 478 if isinstance(self._as_parameter_, ctypes.c_void_p): 479 global _rootinitialized, _rootconsole 480 _rootinitialized = False 481 _rootconsole = None 482 _lib.TCOD_console_delete(self) 483 except StandardError: 484 pass # I forget why I put this here but I'm to afraid to delete it
485
486 - def _replace(self, console):
487 """Used internally 488 489 Mostly used just to replace this Console object with the root console 490 If another Console object is used then they are swapped 491 """ 492 if isinstance(console, Console): 493 self._as_parameter_, console._as_parameter_ = \ 494 console._as_parameter_, self._as_parameter_ # swap tcod consoles 495 else: 496 self._as_parameter_ = console 497 self.width = _lib.TCOD_console_get_width(self) 498 self.height = _lib.TCOD_console_get_height(self) 499 return self
500
501 - def _translate(self, x, y):
502 """Convertion x and y to their position on the root Console for this Window 503 504 Because this is a Console instead of a Window we return the paramaters 505 untouched""" 506 return x, y
507
508 - def clear(self, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
509 """Clears the entire console. 510 511 @type fgcolor: 3-item list 512 @type bgcolor: 3-item list 513 """ 514 assert _verify_colors(fgcolor, bgcolor) 515 assert fgcolor and bgcolor, 'Can not use None with clear' 516 _lib.TCOD_console_set_default_background(self, _formatColor(bgcolor)) 517 _lib.TCOD_console_set_default_foreground(self, _formatColor(fgcolor)) 518 _lib.TCOD_console_clear(self)
519
520 - def _setCharFill(self, x, y, char, fgcolor=None, bgcolor=None):
521 """An optimized version using the fill wrappers that didn't work out to be any faster""" 522 index = x + y * self.width 523 self.chArray[index] = char 524 for channel, color in zip(itertools.chain(self.fgArrays, self.bgArrays), 525 itertools.chain(fgcolor, bgcolor)): 526 channel[index] = color
527
528 - def _setCharCall(self, x, y, char, fgcolor=None, bgcolor=None, bgblend=1):
529 """ 530 Sets a character. 531 This is called often and is designed to be as fast as possible. 532 533 Because of the need for speed this function will do NO TYPE CHECKING 534 AT ALL, it's up to the drawing functions to use the functions: 535 _formatChar and _formatColor before passing to this.""" 536 if char is not None and fgcolor is not None and bgcolor is not None: 537 return _setcharEX(self, x, y, char, fgcolor, bgcolor) 538 if char is not None: 539 _setchar(self, x, y, char) 540 if fgcolor is not None: 541 _setfore(self, x, y, fgcolor) 542 if bgcolor is not None: 543 _setback(self, x, y, bgcolor, bgblend)
544 545 if _USE_FILL: 546 _setChar = _setCharFill 547 else: 548 _setChar = _setCharCall 549
550 - def getChar(self, x, y):
551 """Return the character and colors of a cell as 552 (char, fgcolor, bgcolor) 553 554 The charecter is returned as a number. 555 Each color is returned as a tuple. 556 557 @rtype: (int, 3-item tuple, 3-item tuple) 558 """ 559 self._drawable(x, y) 560 char = _lib.TCOD_console_get_char(self, x, y) 561 bgcolor = _lib.TCOD_console_get_char_background_wrapper(self, x, y) 562 fgcolor = _lib.TCOD_console_get_char_foreground_wrapper(self, x, y) 563 return char, tuple(fgcolor), tuple(bgcolor)
564
565 - def __repr__(self):
566 return "<Console (Width=%i Height=%i)>" % (self.width, self.height)
567
568 569 -class Window(_MetaConsole):
570 """A Window contains a small isolated part of a Console. 571 572 Drawing on the Window draws on the Console. 573 574 Making a Window and setting its width or height to None will extend it to 575 the edge of the console. 576 """ 577 578 __slots__ = ('console', 'parent', 'x', 'y') 579
580 - def __init__(self, console, x, y, width, height):
581 assert isinstance(console, (Console, Window)), 'console parameter must be a Console or Window instance, got %s' % repr(console) 582 self.parent = console 583 self.x, self.y, self.width, self.height = console._normalizeRect(x, y, width, height) 584 if isinstance(console, Console): 585 self.console = console 586 else: 587 self.console = self.parent.console
588
589 - def _translate(self, x, y):
590 """Convertion x and y to their position on the root Console""" 591 # we add our position relative to our parent and then call then next parent up 592 return self.parent._translate((x + self.x), (y + self.y))
593
594 - def clear(self, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
595 """Clears the entire Window. 596 597 @type fgcolor: 3-item list 598 @type bgcolor: 3-item list 599 """ 600 assert _verify_colors(fgcolor, bgcolor) 601 assert fgcolor and bgcolor, 'Can not use None with clear' 602 self.draw_rect(0, 0, None, None, 0x20, fgcolor, bgcolor)
603
604 - def _setChar(self, x, y, char=None, fgcolor=None, bgcolor=None, bgblend=1):
605 self.parent._setChar((x + self.x), (y + self.y), char, fgcolor, bgcolor, bgblend)
606
607 - def getChar(self, x, y):
608 """Return the character and colors of a cell as (ch, fg, bg) 609 610 @rtype: (int, 3-item tuple, 3-item tuple) 611 """ 612 self._drawable(x, y) 613 return self.console.getChar(self._translate(x, y))
614
615 - def __repr__(self):
616 return "<Window(X=%i Y=%i Width=%i Height=%i)>" % (self.x, self.y, 617 self.width, 618 self.height)
619
620 621 -def init(width, height, title='python-tdl', fullscreen=False, renderer='OPENGL'):
622 """Start the main console with the given width and height and return the 623 root console. 624 625 Call the consoles drawing functions. Then remember to use L{tdl.flush} to 626 make what's drawn visible on the console. 627 628 @type width: int 629 @type height: int 630 631 @type title: string 632 633 @type fullscreen: boolean 634 @param fullscreen: Can be set to True to start in fullscreen mode. 635 636 @type renderer: string 637 @param renderer: Can be one of 'GLSL', 'OPENGL', or 'SDL'. 638 639 Due to way Python works you're unlikely to see much of an 640 improvement by using 'GLSL' or 'OPENGL' as most of the 641 time Python is slow interacting with the console and the 642 rendering itself is pretty fast even on 'SDL'. 643 644 This should be left at default or switched to 'SDL' for 645 better reliability and an instantaneous start up time. 646 647 @rtype: L{Console} 648 @return: The root console. Only what is drawn on the root console is 649 what's visible after a call to L{tdl.flush}. 650 After the root console is garbage collected, the window made by 651 this function will close. 652 """ 653 RENDERERS = {'GLSL': 0, 'OPENGL': 1, 'SDL': 2} 654 global _rootinitialized, _rootconsole 655 if not _fontinitialized: # set the default font to the one that comes with tdl 656 setFont(_unpackfile('terminal.png'), 16, 16, colomn=True) 657 658 if renderer.upper() not in RENDERERS: 659 raise TDLError('No such render type "%s", expected one of "%s"' % (renderer, '", "'.join(RENDERERS))) 660 renderer = RENDERERS[renderer.upper()] 661 662 # If a console already exists then make a clone to replace it 663 if _rootconsole is not None: 664 oldroot = _rootconsole() 665 rootreplacement = Console(oldroot.width, oldroot.height) 666 rootreplacement.blit(oldroot) 667 oldroot._replace(rootreplacement) 668 del rootreplacement 669 670 _lib.TCOD_console_init_root(width, height, _format_string(title), fullscreen, renderer) 671 672 #event.get() # flush the libtcod event queue to fix some issues 673 # issues may be fixed already 674 675 event._eventsflushed = False 676 _rootinitialized = True 677 rootconsole = Console._newConsole(ctypes.c_void_p()) 678 _rootconsole = weakref.ref(rootconsole) 679 680 return rootconsole
681
682 -def flush():
683 """Make all changes visible and update the screen. 684 685 Remember to call this function after drawing operations. 686 Calls to flush will enfore the frame rate limit set by L{tdl.setFPS}. 687 688 This function can only be called after L{tdl.init} 689 """ 690 if not _rootinitialized: 691 raise TDLError('Cannot flush without first initializing with tdl.init') 692 693 if _USE_FILL: 694 console = _rootconsole() 695 _lib.TCOD_console_fill_background(console, *console.bgArrays) 696 _lib.TCOD_console_fill_foreground(console, *console.fgArrays) 697 _lib.TCOD_console_fill_char(console, console.chArray) 698 699 _lib.TCOD_console_flush()
700
701 -def setFont(path, tileWidth, tileHeight, colomn=False, 702 greyscale=False, altLayout=False):
703 """Changes the font to be used for this session. 704 This should be called before L{tdl.init} 705 706 While it's possible you can change the font mid program it can sometimes 707 break in rare circumstances. So use caution when doing this. 708 709 @type path: string 710 @param path: Must be a string filepath where a bmp or png file is found. 711 712 @type tileWidth: int 713 @param tileWidth: The width of an individual tile. 714 715 @type tileHeight: int 716 @param tileHeight: The height of an individual tile. 717 718 @type colomn: boolean 719 @param colomn: Defines if the characer order goes along the rows or 720 colomns. 721 It should be True if the charater codes 0-15 are in the 722 first column. And should be False if the characters 0-15 723 are in the first row. 724 725 @type greyscale: boolean 726 @param greyscale: Creates an anti-aliased font from a greyscale bitmap. 727 Otherwise it uses the alpha channel for anti-aliasing. 728 729 @type altLayout: boolean 730 @param altLayout: An alternative layout with space in the upper left 731 corner. The colomn parameter is ignored if this is 732 True, find examples of this layout in the font/ 733 directory included with the python-tdl source. 734 735 @raise TDLError: Will be raised if no file is found at path. 736 737 @note: A png file that's been optimized can fail to load correctly on 738 MAC OS X creating a garbled mess when rendering. 739 Don't use a program like optipng or just use bmp files instead if 740 you want your program to work on macs. 741 """ 742 # put up some constants that are only used here 743 FONT_LAYOUT_ASCII_INCOL = 1 744 FONT_LAYOUT_ASCII_INROW = 2 745 FONT_TYPE_GREYSCALE = 4 746 FONT_LAYOUT_TCOD = 8 747 global _fontinitialized 748 _fontinitialized = True 749 flags = 0 750 if altLayout: 751 flags |= FONT_LAYOUT_TCOD 752 elif colomn: 753 flags |= FONT_LAYOUT_ASCII_INCOL 754 else: 755 flags |= FONT_LAYOUT_ASCII_INROW 756 if greyscale: 757 flags |= FONT_TYPE_GREYSCALE 758 if not os.path.exists(path): 759 raise TDLError('no file exists at: "%s"' % path) 760 _lib.TCOD_console_set_custom_font(_format_string(path), flags, tileWidth, tileHeight)
761
762 -def getFullscreen():
763 """Returns True if program is fullscreen. 764 765 @rtype: boolean 766 @return: Returns True if the window is in fullscreen mode. 767 Otherwise returns False. 768 """ 769 if not _rootinitialized: 770 raise TDLError('Initialize first with tdl.init') 771 return _lib.TCOD_console_is_fullscreen()
772
773 -def setFullscreen(fullscreen):
774 """Changes the fullscreen state. 775 776 @type fullscreen: boolean 777 """ 778 if not _rootinitialized: 779 raise TDLError('Initialize first with tdl.init') 780 _lib.TCOD_console_set_fullscreen(fullscreen)
781
782 -def setTitle(title):
783 """Change the window title. 784 785 @type title: string 786 """ 787 if not _rootinitialized: 788 raise TDLError('Not initilized. Set title with tdl.init') 789 _lib.TCOD_console_set_window_title(_format_string(title))
790
791 -def screenshot(path=None):
792 """Capture the screen and save it as a png file 793 794 @type path: string 795 @param path: The filepath to save the screenshot. 796 797 If path is None then the image will be placed in the current 798 folder with the names: 799 screenshot001.png, screenshot002.png, ... 800 """ 801 if not _rootinitialized: 802 raise TDLError('Initialize first with tdl.init') 803 if isinstance(fileobj, str): 804 _lib.TCOD_sys_save_screenshot(_format_string(fileobj)) 805 elif isinstance(fileobj, file): # save to temp file and copy to file-like obj 806 tmpname = os.tempnam() 807 _lib.TCOD_sys_save_screenshot(_format_string(tmpname)) 808 with tmpname as tmpfile: 809 fileobj.write(tmpfile.read()) 810 os.remove(tmpname) 811 elif fileobj is None: # save to screenshot001.png, screenshot002.png, ... 812 filelist = os.listdir('.') 813 n = 1 814 filename = 'screenshot%.3i.png' % n 815 while filename in filelist: 816 n += 1 817 filename = 'screenshot%.4i.png' % n 818 _lib.TCOD_sys_save_screenshot(_format_string(filename)) 819 else: 820 raise TypeError('fileobj is an invalid type: %s' % type(fileobj))
821
822 -def setFPS(frameRate):
823 """Set the maximum frame rate. 824 825 @type frameRate: int 826 @param frameRate: Further calls to L{tdl.flush} will limit the speed of 827 the program to run at <frameRate> frames per second. Can 828 also be set to 0 to run without a limit. 829 830 Defaults to None. 831 """ 832 if frameRate is None: 833 frameRate = 0 834 assert isinstance(frameRate, int), 'frameRate must be an integer or None, got: %s' % repr(frameRate) 835 _lib.TCOD_sys_set_fps(frameRate)
836
837 -def getFPS():
838 """Return the current frames per second of the running program set by 839 L{setFPS} 840 841 @rtype: int 842 @return: Returns the frameRate set by setFPS. 843 If set to no limit, this will return 0. 844 """ 845 return _lib.TCOD_sys_get_fps()
846
847 -def forceResolution(width, height):
848 """Change the fullscreen resoulution 849 850 @type width: int 851 @type height: int 852 """ 853 _lib.TCOD_sys_force_fullscreen_resolution(width, height)
854 855 __all__ = [_var for _var in locals().keys() if _var[0] != '_' and _var not in ['sys', 'os', 'ctypes', 'array', 'weakref', 'itertools']] 856 __all__ += ['_MetaConsole'] # keep this object public to show the documentation in epydoc 857