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      You can find the project page on Google Code 
   6      U{here<http://code.google.com/p/python-tdl/>}. 
   7       
   8      Report any bugs or issues to the Google Code issue tracker 
   9      U{here<https://code.google.com/p/python-tdl/issues/list>}. 
  10   
  11      Getting Started 
  12      =============== 
  13        Once the library is imported you can load the font you want to use with 
  14        L{tdl.setFont}. 
  15        This is optional and when skipped will use a decent default font. 
  16         
  17        After that you call L{tdl.init} to set the size of the window and get the 
  18        root console in return. 
  19        This console is the canvas to what will appear on the screen. 
  20   
  21      Indexing Consoles 
  22      ================= 
  23        For most methods taking a position you can use Python-style negative 
  24        indexes to refer to the opposite side of a console with (-1, -1) 
  25        starting at the bottom right. 
  26        You can also check if a point is part of a console using containment 
  27        logic i.e. ((x, y) in console). 
  28         
  29      Drawing 
  30      ======= 
  31        Once you have the root console from L{tdl.init} you can start drawing on 
  32        it using a method such as L{Console.drawChar}. 
  33        When using this method you can have the char parameter be an integer or a 
  34        single character string. 
  35        The fgcolor and bgcolor parameters expect a three item list 
  36        [red, green, blue] with integers in the 0-255 range with [0, 0, 0] being 
  37        black and [255, 255, 255] being white. 
  38        Or instead you can use None for any of the three parameters to tell the 
  39        library to not overwrite colors. 
  40        After the drawing functions are called a call to L{tdl.flush} will update 
  41        the screen. 
  42  """ 
  43   
  44  import sys 
  45  import os 
  46   
  47  import ctypes 
  48  import weakref 
  49  import array 
  50  import itertools 
  51  import textwrap 
  52  import struct 
  53  import re 
  54  import warnings 
  55   
  56  from . import event, map, noise 
  57  from .__tcod import _lib, _Color, _unpackfile 
  58   
  59  _IS_PYTHON3 = (sys.version_info[0] == 3) 
  60   
  61  if _IS_PYTHON3: # some type lists to use with isinstance 
  62      _INTTYPES = (int,) 
  63      _NUMTYPES = (int, float) 
  64      _STRTYPES = (str, bytes) 
  65  else: 
  66      _INTTYPES = (int, long) 
  67      _NUMTYPES = (int, long, float) 
  68      _STRTYPES = (str,) 
69 70 -def _encodeString(string): # still used for filepaths, and that's about it
71 "changes string into bytes if running in python 3, for sending to ctypes" 72 if _IS_PYTHON3 and isinstance(string, str): 73 return string.encode() 74 return string 75
76 #def _formatString(string): 77 # pass 78 79 -def _formatChar(char):
80 """Prepares a single character for passing to ctypes calls, needs to return 81 an integer but can also pass None which will keep the current character 82 instead of overwriting it. 83 84 This is called often and needs to be optimized whenever possible. 85 """ 86 if char is None: 87 return None 88 if isinstance(char, _INTTYPES): 89 return char 90 if isinstance(char, _STRTYPES) and len(char) == 1: 91 return ord(char) 92 raise TypeError('Expected char parameter to be a single character string, number, or None, got: %s' % repr(char))
93 94 _fontinitialized = False 95 _rootinitialized = False 96 _rootConsoleRef = None 97 # remove dots from common functions 98 _setchar = _lib.TCOD_console_set_char 99 _setfore = _lib.TCOD_console_set_char_foreground 100 _setback = _lib.TCOD_console_set_char_background 101 _setcharEX = _lib.TCOD_console_put_char_ex
102 -def _verify_colors(*colors):
103 """Used internally. 104 Raise an assertion error if the parameters can not be converted into colors. 105 """ 106 for color in colors: 107 assert _iscolor(color), 'a color must be a 3 item tuple, web format, or None, received %s' % repr(color) 108 return True
109
110 -def _iscolor(color):
111 """Used internally. 112 A debug function to see if an object can be used as a TCOD color struct. 113 None counts as a parameter to keep the current colors instead. 114 115 This function is often part of an inner-loop and can slow a program down. 116 It has been made to work with assert and can be skipped with the -O flag. 117 Still it's called often and must be optimized. 118 """ 119 if color is None: 120 return True 121 if isinstance(color, (tuple, list, _Color)): 122 return len(color) == 3 123 if isinstance(color, _INTTYPES): 124 return True 125 return False
126
127 ## not using this for now 128 #class Color(object): 129 # 130 # def __init__(self, r, g, b): 131 # self._color = (r, g, b) 132 # self._ctype = None 133 # 134 # def _getCType(self): 135 # if not self._ctype: 136 # self._ctype = _Color(*self._color) 137 # return self._ctype 138 # 139 # def __len__(self): 140 # return 3 141 142 -def _formatColor(color):
143 """Format the color to ctypes 144 """ 145 if color is None or color is False: 146 return color 147 if isinstance(color, _Color): 148 return color 149 #if isinstance(color, Color): 150 # return color._getCType() 151 if isinstance(color, _INTTYPES): 152 # format a web style color with the format 0xRRGGBB 153 return _Color(color >> 16 & 0xff, color >> 8 & 0xff, color & 0xff) 154 return _Color(*color)
155
156 -def _getImageSize(filename):
157 """Try to get the width and height of a bmp of png image file""" 158 file = open(filename, 'rb') 159 if file.read(8) == b'\x89PNG\r\n\x1a\n': # PNG 160 while 1: 161 length, = struct.unpack('>i', file.read(4)) 162 chunkID = file.read(4) 163 if chunkID == '': # EOF 164 return None 165 if chunkID == b'IHDR': 166 # return width, height 167 return struct.unpack('>ii', file.read(8)) 168 file.seek(4 + length, 1) 169 file.seek(0) 170 if file.read(8) == b'BM': # Bitmap 171 file.seek(18, 0) # skip to size data 172 # return width, height 173 return struct.unpack('<ii', file.read(8))
174 # return None on error, unknown file
175 176 -class TDLError(Exception):
177 """ 178 The catch all for most TDL specific errors. 179 """
180
181 -class _MetaConsole(object):
182 """ 183 Contains methods shared by both the L{Console} and L{Window} classes. 184 """ 185 __slots__ = ('width', 'height', 'console', '_cursor', '_fgcolor', 186 '_bgcolor', '_bgblend', '_colorLock', '__weakref__', '__dict__') 187
188 - def __init__(self):
189 self._cursor = (0, 0) 190 self._scrollMode = 'error' 191 self._fgcolor = _formatColor((255, 255, 255)) 192 self._bgcolor = _formatColor((0, 0, 0)) 193 self._bgblend = 1 # SET 194 self._colorLock = None # which object sets the ctype color options
195
196 - def _normalizePoint(self, x, y):
197 """Check if a point is in bounds and make minor adjustments. 198 199 Respects Pythons negative indexes. -1 starts at the bottom right. 200 Replaces the _drawable function 201 """ 202 assert isinstance(x, _INTTYPES), 'x must be an integer, got %s' % repr(x) 203 assert isinstance(y, _INTTYPES), 'y must be an integer, got %s' % repr(y) 204 205 assert (-self.width <= x < self.width) and (-self.height <= y < self.height), \ 206 ('(%i, %i) is an invalid postition on %s' % (x, y, self)) 207 208 # handle negative indexes 209 if x < 0: 210 x += self.width 211 if y < 0: 212 y += self.height 213 return (x, y)
214
215 - def _normalizeRect(self, x, y, width, height):
216 """Check if the rectangle is in bounds and make minor adjustments. 217 raise AssertionError's for any problems 218 """ 219 x, y = self._normalizePoint(x, y) # inherit _normalizePoint logic 220 221 assert width is None or isinstance(width, _INTTYPES), 'width must be an integer or None, got %s' % repr(width) 222 assert height is None or isinstance(height, _INTTYPES), 'height must be an integer or None, got %s' % repr(height) 223 224 # if width or height are None then extend them to the edge 225 if width is None: 226 width = self.width - x 227 elif width < 0: # handle negative numbers 228 width += self.width 229 width = max(0, width) # a 'too big' negative is clamped zero 230 if height is None: 231 height = self.height - y 232 height = max(0, height) 233 elif height < 0: 234 height += self.height 235 236 # reduce rect size to bounds 237 width = min(width, self.width - x) 238 height = min(height, self.height - y) 239 240 return x, y, width, height
241
242 - def _normalizeCursor(self, x, y):
243 """return the normalized the cursor position.""" 244 width, height = self.getSize() 245 while x >= width: 246 x -= width 247 y += 1 248 while y >= height: 249 if self._scrollMode == 'scroll': 250 y -= 1 251 self.scroll(0, -1) 252 elif self._scrollMode == 'error': 253 # reset the cursor on error 254 self._cursor = (0, 0) 255 raise TDLError('Cursor has reached the end of the console') 256 return (x, y)
257
258 - def _lockColors(self, forceUpdate=False):
259 """Make sure the color options on the root console match ths instance""" 260 if self.console._lockColors is not self or forceUpdate: 261 self.console._lockColors = self 262 _lib.TCOD_console_set_default_background(self.console, self.bgcolor) 263 _lib.TCOD_console_set_default_foreground(self.console, self.fgcolor)
264 # 265
266 - def setColors(self, fg=None, bg=None):
267 """Sets the colors to be used with the L{printStr} function. 268 269 Values of None will only leave the current values unchanged. 270 """ 271 if self.console._lockColors is self: 272 self.console._lockColors = None 273 if fg is not None: 274 self_fgcolor = _formatColor(fg) 275 if bg is not None: 276 self_fgcolor = _formatColor(fg)
277
278 - def printStr(self, string):
279 """Print a string at the virtual cursor. 280 281 Handles special characters such as '\\n' and '\\r'. 282 Printing past the bottom of the console will scroll everying upwards. 283 284 Colors can be set with L{setColors} and the virtual cursor can be moved 285 with L{move}. 286 287 @type string: string 288 @param string: 289 """ 290 x, y = self._cursor 291 for char in string: 292 if char == '\n': # line break 293 x = 0 294 y += 1 295 continue 296 if char == '\r': # return 297 x = 0 298 continue 299 x, y = self._normalizeCursor(x, y) 300 self.drawChar(x, y, char, self._fgcolor, self._bgcolor) 301 x += 1 302 self._cursor = (x, y)
303
304 - def write(self, string):
305 """This method mimics basic file-like behaviour. 306 307 Because of this method you can replace sys.stdout or sys.stderr with 308 a L{Typewriter} instance. 309 310 This is a convoluted process and behaviour seen now can be excepted to 311 change on later versions. 312 313 @type string: string 314 """ 315 # some 'basic' line buffer stuff. 316 # there must be an easier way to do this. The textwrap module didn't 317 # help much. 318 x, y = self._normalize(*self._cursor) 319 width, height = self.parent.getSize() 320 wrapper = textwrap.TextWrapper(initial_indent=(' '*x), width=width) 321 writeLines = [] 322 for line in string.split('\n'): 323 if line: 324 writeLines += wrapper.wrap(line) 325 wrapper.initial_indent = '' 326 else: 327 writeLines.append([]) 328 329 for line in writeLines: 330 x, y = self._normalize(x, y) 331 self.parent.drawStr(x, y, line[x:], self.fgcolor, self.bgcolor) 332 y += 1 333 x = 0 334 y -= 1 335 self._cursor = (x, y)
336
337 - def drawChar(self, x, y, char, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
338 """Draws a single character. 339 340 @type x: int 341 @param x: X coordinate to draw at. 342 @type y: int 343 @param y: Y coordinate to draw at. 344 345 @type char: int, string, or None 346 @param char: Should be an integer, single character string, or None. 347 348 You can set the char parameter as None if you only want to change 349 the colors of the tile. 350 351 @type fgcolor: (r, g, b) or None 352 @param fgcolor: For fgcolor and bgcolor you use a 3 item list with 353 integers ranging 0-255 or None. 354 355 None will keep the current color at this position unchanged. 356 @type bgcolor: (r, g, b) or None 357 @param bgcolor: Background color. See fgcolor 358 359 @raise AssertionError: Having x or y values that can't be placed inside 360 of the console will raise an AssertionError. 361 You can use always use ((x, y) in console) to 362 check if a tile is drawable. 363 """ 364 365 assert _verify_colors(fgcolor, bgcolor) 366 x, y = self._normalizePoint(x, y) 367 x, y = ctypes.c_int(x), ctypes.c_int(y) 368 self._setChar(x, y, _formatChar(char), 369 _formatColor(fgcolor), _formatColor(bgcolor))
370
371 - def drawStr(self, x, y, string, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
372 """Draws a string starting at x and y. Optinally colored. 373 374 A string that goes past the right side will wrap around. A string 375 wraping to below the console will raise a L{TDLError} but will still be 376 written out. This means you can safely ignore the errors with a 377 try... except block if you're fine with partily written strings. 378 379 \\r and \\n are drawn on the console as normal character tiles. No 380 special encoding is done and any string will translate to the character 381 table as is. 382 383 For a string drawing operation that respects special characters see the 384 L{Typewriter} class. 385 386 @type x: int 387 @param x: X coordinate to draw at. 388 @type y: int 389 @param y: Y coordinate to draw at. 390 391 @type string: string or iterable 392 @param string: Can be a string or an iterable of numbers. 393 394 Special characters are ignored and rendered as any other 395 character. 396 397 @type fgcolor: (r, g, b) or None 398 @param fgcolor: For fgcolor and bgcolor you use a 3 item list with 399 integers ranging 0-255 or None. 400 401 None will keep the current color at this position unchanged. 402 @type bgcolor: (r, g, b) or None 403 @param bgcolor: Background color. See fgcolor 404 405 @raise AssertionError: Having x or y values that can't be placed inside 406 of the console will raise an AssertionError. 407 408 You can use always use ((x, y) in console) to 409 check if a tile is drawable. 410 """ 411 412 x, y = self._normalizePoint(x, y) 413 assert _verify_colors(fgcolor, bgcolor) 414 fgcolor, bgcolor = _formatColor(fgcolor), _formatColor(bgcolor) 415 width, height = self.getSize() 416 batch = [] # prepare a batch operation 417 def _drawStrGen(x=x, y=y, string=string, width=width, height=height): 418 """Generator for drawStr 419 420 Iterates over ((x, y), ch) data for _setCharBatch, raising an 421 error if the end of the console is reached. 422 """ 423 for char in string: 424 if y == height: 425 raise TDLError('End of console reached.') 426 #batch.append(((x, y), _formatChar(char))) # ((x, y), ch) 427 yield((x, y), _formatChar(char)) 428 x += 1 # advance cursor 429 if x == width: # line break 430 x = 0 431 y += 1
432 self._setCharBatch(_drawStrGen(), fgcolor, bgcolor)
433
434 - def drawRect(self, x, y, width, height, string, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
435 """Draws a rectangle starting from x and y and extending to width and height. 436 437 If width or height are None then it will extend to the edge of the console. 438 439 @type x: int 440 @param x: x coordinate to draw at. 441 @type y: int 442 @param y: y coordinate to draw at. 443 444 @type width: int or None 445 @param width: Width of the rectangle. 446 447 Can be None to extend to the bottom right of the 448 console or can be a negative number to be sized reltive 449 to the total size of the console. 450 @type height: int or None 451 @param height: Height of the rectangle. See width. 452 453 @type string: int, string, or None 454 @param string: Should be an integer, single character string, or None. 455 456 You can set the char parameter as None if you only want 457 to change the colors of an area. 458 459 @type fgcolor: (r, g, b) or None 460 @param fgcolor: For fgcolor and bgcolor you use a 3 item list with 461 integers ranging 0-255 or None. 462 463 None will keep the current color at this position unchanged. 464 @type bgcolor: (r, g, b) or None 465 @param bgcolor: Background color. See fgcolor 466 467 @raise AssertionError: Having x or y values that can't be placed inside 468 of the console will raise an AssertionError. 469 470 You can use always use ((x, y) in console) to 471 check if a tile is drawable. 472 """ 473 x, y, width, height = self._normalizeRect(x, y, width, height) 474 assert _verify_colors(fgcolor, bgcolor) 475 fgcolor, bgcolor = _formatColor(fgcolor), _formatColor(bgcolor) 476 char = _formatChar(string) 477 # use itertools to make an x,y grid 478 # using ctypes here reduces type converstions later 479 grid = itertools.product((ctypes.c_int(x) for x in range(x, x + width)), 480 (ctypes.c_int(y) for y in range(y, y + height))) 481 # zip the single character in a batch variable 482 batch = zip(grid, itertools.repeat(char, width * height)) 483 self._setCharBatch(batch, fgcolor, bgcolor, nullChar=(char is None))
484
485 - def drawFrame(self, x, y, width, height, string, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
486 """Similar to L{drawRect} but only draws the outline of the rectangle. 487 488 @type x: int 489 @param x: x coordinate to draw at. 490 @type y: int 491 @param y: y coordinate to draw at. 492 493 @type width: int or None 494 @param width: Width of the rectangle. 495 496 Can be None to extend to the bottom right of the 497 console or can be a negative number to be sized reltive 498 to the total size of the console. 499 @type height: int or None 500 @param height: Height of the rectangle. See width. 501 502 @type string: int, string, or None 503 @param string: Should be an integer, single character string, or None. 504 505 You can set the char parameter as None if you only want 506 to change the colors of an area. 507 508 @type fgcolor: (r, g, b) or None 509 @param fgcolor: For fgcolor and bgcolor you use a 3 item list with 510 integers ranging 0-255 or None. 511 512 None will keep the current color at this position unchanged. 513 @type bgcolor: (r, g, b) or None 514 @param bgcolor: Background color. See fgcolor 515 516 @raise AssertionError: Having x or y values that can't be placed inside 517 of the console will raise an AssertionError. 518 519 You can use always use ((x, y) in console) to 520 check if a tile is drawable. 521 """ 522 x, y, width, height = self._normalizeRect(x, y, width, height) 523 assert _verify_colors(fgcolor, bgcolor) 524 fgcolor, bgcolor = _formatColor(fgcolor), _formatColor(bgcolor) 525 char = _formatChar(string) 526 if width == 1 or height == 1: # it's just a single width line here 527 return self.drawRect(x, y, width, height, char, fgcolor, bgcolor) 528 529 # draw sides of frame with drawRect 530 self.drawRect(x, y, 1, height, char, fgcolor, bgcolor) 531 self.drawRect(x, y, width, 1, char, fgcolor, bgcolor) 532 self.drawRect(x + width - 1, y, 1, height, char, fgcolor, bgcolor) 533 self.drawRect(x, y + height - 1, width, 1, char, fgcolor, bgcolor)
534
535 - def blit(self, source, x=0, y=0, width=None, height=None, srcX=0, srcY=0):
536 """Blit another console or Window onto the current console. 537 538 By default it blits the entire source to the topleft corner. 539 540 @type source: L{Console} or L{Window} 541 @param source: Source window can be a L{Console} or L{Window} instance. 542 It can even blit to itself without any problems. 543 544 @type x: int 545 @param x: X coordinate to blit to. 546 @type y: int 547 @param y: Y coordinate to blit to. 548 549 @type width: int or None 550 @param width: Width of the rectangle. 551 552 Can be None to extend as far as possible to the 553 bottom right corner of the blit area or can be a negative 554 number to be sized reltive to the total size of the 555 B{destination} console. 556 @type height: int or None 557 @param height: Height of the rectangle. See width. 558 559 @type srcX: int 560 @param srcX: The source consoles x coordinate to blit from. 561 @type srcY: int 562 @param srcY: The source consoles y coordinate to blit from. 563 """ 564 # hardcode alpha settings for now 565 fgalpha=1.0 566 bgalpha=1.0 567 568 assert isinstance(source, (Console, Window)), "source muse be a Window or Console instance" 569 570 # handle negative indexes and rects 571 # negative width and height will be set realtive to the destination 572 # and will also be clamped to the smallest Console 573 x, y, width, height = self._normalizeRect(x, y, width, height) 574 srcX, srcY, width, height = source._normalizeRect(srcX, srcY, width, height) 575 576 # translate source and self if any of them are Window instances 577 srcX, srcY = source._translate(srcX, srcY) 578 source = source.console 579 x, y = self._translate(x, y) 580 self = self.console 581 582 if self == source: 583 # if we are the same console then we need a third console to hold 584 # onto the data, otherwise it tries to copy into itself and 585 # starts destroying everything 586 tmp = Console(width, height) 587 _lib.TCOD_console_blit(source, srcX, srcY, width, height, tmp, 0, 0, fgalpha, bgalpha) 588 _lib.TCOD_console_blit(tmp, 0, 0, width, height, self, x, y, fgalpha, bgalpha) 589 else: 590 _lib.TCOD_console_blit(source, srcX, srcY, width, height, self, x, y, fgalpha, bgalpha)
591
592 - def getCursor(self):
593 """Return the virtual cursor position. 594 595 @rtype: (int, int) 596 @return: Returns (x, y) a 2-integer tuple containing where the next 597 L{addChar} or L{addStr} will start at. 598 599 This can be changed with the L{move} method.""" 600 x, y = self._cursor 601 width, height = self.parent.getSize() 602 while x >= width: 603 x -= width 604 y += 1 605 if y >= height and self.scrollMode == 'scroll': 606 y = height - 1 607 return x, y
608
609 - def getSize(self):
610 """Return the size of the console as (width, height) 611 612 @rtype: (int, int) 613 """ 614 return self.width, self.height
615
616 - def move(self, x, y):
617 """Move the virtual cursor. 618 619 @type x: int 620 @param x: X position to place the cursor. 621 @type y: int 622 @param y: Y position to place the cursor. 623 """ 624 self._cursor = self._normalizePoint(x, y)
625
626 - def scroll(self, x, y):
627 """Scroll the contents of the console in the direction of x,y. 628 629 Uncovered areas will be cleared. 630 Does not move the virutal cursor. 631 @type x: int 632 @param x: Distance to scroll along x-axis 633 @type y: int 634 @param y: Distance to scroll along y-axis 635 """ 636 assert isinstance(x, _INTTYPES), "x must be an integer, got %s" % repr(x) 637 assert isinstance(y, _INTTYPES), "y must be an integer, got %s" % repr(x) 638 def getSlide(x, length): 639 """get the parameters needed to scroll the console in the given 640 direction with x 641 returns (x, length, srcx) 642 """ 643 if x > 0: 644 srcx = 0 645 length -= x 646 elif x < 0: 647 srcx = abs(x) 648 x = 0 649 length -= srcx 650 else: 651 srcx = 0 652 return x, length, srcx
653 def getCover(x, length): 654 """return the (x, width) ranges of what is covered and uncovered""" 655 cover = (0, length) # everything covered 656 uncover = None # nothing uncovered 657 if x > 0: # left side uncovered 658 cover = (x, length - x) 659 uncover = (0, x) 660 elif x < 0: # right side uncovered 661 x = abs(x) 662 cover = (0, length - x) 663 uncover = (length - x, x) 664 return cover, uncover 665 666 width, height = self.getSize() 667 if abs(x) >= width or abs(y) >= height: 668 return self.clear() # just clear the console normally 669 670 # get the ranges of the areas that will be uncovered 671 coverX, uncoverX = getCover(x, width) 672 coverY, uncoverY = getCover(y, height) 673 # so at this point we know that coverX and coverY makes a rect that 674 # encases the area that we end up blitting to. uncoverX/Y makes a 675 # rect in the corner of the uncovered area. So we need to combine 676 # the uncoverX/Y with coverY/X to make what's left of the uncovered 677 # area. Explaining it makes it mush easier to do now. 678 679 # But first we need to blit. 680 x, width, srcx = getSlide(x, width) 681 y, height, srcy = getSlide(y, height) 682 self.blit(self, x, y, width, height, srcx, srcy) 683 684 if uncoverX: # clear sides (0x20 is space) 685 self.drawRect(uncoverX[0], coverY[0], uncoverX[1], coverY[1], 0x20, 0x000000, 0x000000) 686 if uncoverY: # clear top/bottom 687 self.drawRect(coverX[0], uncoverY[0], coverX[1], uncoverY[1], 0x20, 0x000000, 0x000000) 688 if uncoverX and uncoverY: # clear corner 689 self.drawRect(uncoverX[0], uncoverY[0], uncoverX[1], uncoverY[1], 0x20, 0x000000, 0x000000) 690
691 - def getChar(self, x, y):
692 """Return the character and colors of a tile as (ch, fg, bg) 693 694 This method runs very slowly as is not recommended to be called 695 frequently. 696 697 @rtype: (int, (r, g, b), (r, g, b)) 698 @returns: Returns a 3-item tuple. The first item is an integer of the 699 character at the position (x, y) the second and third are the 700 foreground and background colors respectfully. 701 """ 702 raise NotImplementedError('Method here only exists for the docstring')
703
704 - def __contains__(self, position):
705 """Use ((x, y) in console) to check if a position is drawable on this console. 706 """ 707 x, y = position 708 return (0 <= x < self.width) and (0 <= y < self.height)
709
710 -class Console(_MetaConsole):
711 """Contains character and color data and can be drawn to. 712 713 The console created by the L{tdl.init} function is the root console and is the 714 console that is rendered to the screen with L{flush}. 715 716 Any console created from the Console class is an off-screen console that 717 can be drawn on before being L{blit} to the root console. 718 """ 719 720 __slots__ = ('_as_parameter_', '_typewriter') 721
722 - def __init__(self, width, height):
723 """Create a new offscreen console. 724 725 @type width: int 726 @param width: Width of the console in tiles 727 @type height: int 728 @param height: Height of the console in tiles 729 """ 730 _MetaConsole.__init__(self) 731 if not _rootinitialized: 732 raise TDLError('Can not create Console\'s before tdl.init') 733 self._as_parameter_ = _lib.TCOD_console_new(width, height) 734 self.console = self 735 self.width = width 736 self.height = height 737 self._typewriter = None # "typewriter lock", makes sure the colors are set to the typewriter
738 # will be phased out with the Typewriter class 739 740 @classmethod
741 - def _newConsole(cls, console):
742 """Make a Console instance, from a console ctype""" 743 self = cls.__new__(cls) 744 _MetaConsole.__init__(self) 745 self._as_parameter_ = console 746 self.console = self 747 self.width = _lib.TCOD_console_get_width(self) 748 self.height = _lib.TCOD_console_get_height(self) 749 self._typewriter = None 750 return self
751
752 - def __del__(self):
753 """ 754 If the main console is garbage collected then the window will be closed as well 755 """ 756 # If this is the root console the window will close when collected 757 try: 758 if isinstance(self._as_parameter_, ctypes.c_void_p): 759 global _rootinitialized, _rootConsoleRef 760 _rootinitialized = False 761 _rootConsoleRef = None 762 _lib.TCOD_console_delete(self) 763 except StandardError: 764 pass # I forget why I put this here but I'm to afraid to delete it
765
766 - def __copy__(self):
767 # make a new class and blit 768 clone = self.__class__(self.width, self.height) 769 clone.blit(self) 770 return clone
771
772 - def __getstate__(self):
773 # save data from getChar 774 data = [self.getChar(x, y) for x,y in 775 itertools.product(range(self.width), range(self.height))] 776 return self.width, self.height, data
777
778 - def __setstate__(self, state):
779 # make console from __init__ and unpack a getChar array 780 width, height, data = state 781 self.__init__(width, height) 782 for (x, y), graphic in zip(itertools.product(range(width), 783 range(height)), data): 784 self.drawChar(x, y, *graphic)
785
786 - def _replace(self, console):
787 """Used internally 788 789 Mostly used just to replace this Console object with the root console 790 If another Console object is used then they are swapped 791 """ 792 if isinstance(console, Console): 793 self._as_parameter_, console._as_parameter_ = \ 794 console._as_parameter_, self._as_parameter_ # swap tcod consoles 795 else: 796 self._as_parameter_ = console 797 self.width = _lib.TCOD_console_get_width(self) 798 self.height = _lib.TCOD_console_get_height(self) 799 return self
800
801 - def _translate(self, x, y):
802 """Convertion x and y to their position on the root Console for this Window 803 804 Because this is a Console instead of a Window we return the paramaters 805 untouched""" 806 return x, y
807
808 - def clear(self, fgcolor=(0, 0, 0), bgcolor=(0, 0, 0)):
809 """Clears the entire Console. 810 811 @type fgcolor: (r, g, b) 812 @param fgcolor: Foreground color. 813 814 Must be a 3-item list with integers that range 0-255. 815 816 Unlike most other operations you cannot use None here. 817 @type bgcolor: (r, g, b) 818 @param bgcolor: Background color. See fgcolor. 819 """ 820 assert _verify_colors(fgcolor, bgcolor) 821 assert fgcolor and bgcolor, 'Can not use None with clear' 822 self._typewriter = None 823 _lib.TCOD_console_set_default_background(self, _formatColor(bgcolor)) 824 _lib.TCOD_console_set_default_foreground(self, _formatColor(fgcolor)) 825 _lib.TCOD_console_clear(self)
826
827 - def _setChar(self, x, y, char, fgcolor=None, bgcolor=None, bgblend=1):
828 """ 829 Sets a character. 830 This is called often and is designed to be as fast as possible. 831 832 Because of the need for speed this function will do NO TYPE CHECKING 833 AT ALL, it's up to the drawing functions to use the functions: 834 _formatChar and _formatColor before passing to this.""" 835 # buffer values as ctypes objects 836 console = self._as_parameter_ 837 838 if char is not None and fgcolor is not None and bgcolor is not None: 839 _setcharEX(console, x, y, char, fgcolor, bgcolor) 840 return 841 if char is not None: 842 _setchar(console, x, y, char) 843 if fgcolor is not None: 844 _setfore(console, x, y, fgcolor) 845 if bgcolor is not None: 846 _setback(console, x, y, bgcolor, bgblend)
847
848 - def _setCharBatch(self, batch, fgcolor, bgcolor, bgblend=1, nullChar=False):
849 """ 850 Try to perform a batch operation otherwise fall back to _setChar. 851 If fgcolor and bgcolor are defined then this is faster but not by very 852 much. 853 854 batch is a iterable of [(x, y), ch] items 855 """ 856 if fgcolor and not nullChar: 857 # buffer values as ctypes objects 858 self._typewriter = None # clear the typewriter as colors will be set 859 console = self._as_parameter_ 860 bgblend = ctypes.c_int(bgblend) 861 862 if not bgcolor: 863 bgblend = 0 864 else: 865 _lib.TCOD_console_set_default_background(console, bgcolor) 866 _lib.TCOD_console_set_default_foreground(console, fgcolor) 867 _putChar = _lib.TCOD_console_put_char # remove dots and make local 868 for (x, y), char in batch: 869 _putChar(console, x, y, char, bgblend) 870 else: 871 for (x, y), char in batch: 872 self._setChar(x, y, char, fgcolor, bgcolor, bgblend)
873
874 - def getChar(self, x, y):
875 # inherit docstring 876 x, y = self._normalizePoint(x, y) 877 char = _lib.TCOD_console_get_char(self, x, y) 878 bgcolor = _lib.TCOD_console_get_char_background_wrapper(self, x, y) 879 fgcolor = _lib.TCOD_console_get_char_foreground_wrapper(self, x, y) 880 return char, tuple(fgcolor), tuple(bgcolor)
881
882 - def __repr__(self):
883 return "<Console (Width=%i Height=%i)>" % (self.width, self.height)
884
885 886 -class Window(_MetaConsole):
887 """A Window contains a small isolated part of a Console. 888 889 Drawing on the Window draws on the Console. 890 891 Making a Window and setting its width or height to None will extend it to 892 the edge of the console. 893 """ 894 895 __slots__ = ('parent', 'x', 'y') 896
897 - def __init__(self, console, x, y, width, height):
898 """Isolate part of a L{Console} or L{Window} instance. 899 900 @type console: L{Console} or L{Window} 901 @param console: The parent object which can be a L{Console} or another 902 L{Window} instance. 903 904 @type x: int 905 @param x: X coordinate to place the Window. 906 907 This follows the normal rules for indexing so you can use a 908 negative integer to place the Window relative to the bottom 909 right of the parent Console instance. 910 @type y: int 911 @param y: Y coordinate to place the Window. 912 913 See x. 914 915 @type width: int or None 916 @param width: Width of the Window. 917 918 Can be None to extend as far as possible to the 919 bottom right corner of the parent Console or can be a 920 negative number to be sized reltive to the Consoles total 921 size. 922 @type height: int or None 923 @param height: Height of the Window. 924 925 See width. 926 """ 927 _MetaConsole.__init__(self) 928 assert isinstance(console, (Console, Window)), 'console parameter must be a Console or Window instance, got %s' % repr(console) 929 self.parent = console 930 self.x, self.y, self.width, self.height = console._normalizeRect(x, y, width, height) 931 if isinstance(console, Console): 932 self.console = console 933 else: 934 self.console = self.parent.console
935
936 - def _translate(self, x, y):
937 """Convertion x and y to their position on the root Console""" 938 # we add our position relative to our parent and then call then next parent up 939 return self.parent._translate((x + self.x), (y + self.y))
940
941 - def clear(self, fgcolor=(0, 0, 0), bgcolor=(0, 0, 0)):
942 """Clears the entire Window. 943 944 @type fgcolor: (r, g, b) 945 @param fgcolor: Foreground color. 946 947 Must be a 3-item list with integers that range 0-255. 948 949 Unlike most other operations you can not use None here. 950 @type bgcolor: (r, g, b) 951 @param bgcolor: Background color. See fgcolor. 952 """ 953 assert _verify_colors(fgcolor, bgcolor) 954 assert fgcolor and bgcolor, 'Can not use None with clear' 955 self.drawRect(0, 0, None, None, 0x20, fgcolor, bgcolor)
956
957 - def _setChar(self, x, y, char=None, fgcolor=None, bgcolor=None, bgblend=1):
958 self.parent._setChar((x + self.x), (y + self.y), char, fgcolor, bgcolor, bgblend)
959
960 - def _setCharBatch(self, batch, fgcolor, bgcolor, bgblend=1):
961 myX = self.x # remove dots for speed up 962 myY = self.y 963 self.parent._setCharBatch((((x + myX, y + myY), ch) for ((x, y), ch) in batch), 964 fgcolor, bgcolor, bgblend)
965 966
967 - def drawChar(self, x, y, char, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
968 # inherit docstring 969 x, y = self._normalizePoint(x, y) 970 self.parent.drawChar(x + self.x, y + self.y, char, fgcolor, bgcolor)
971
972 - def drawRect(self, x, y, width, height, string, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
973 # inherit docstring 974 x, y, width, height = self._normalizeRect(x, y, width, height) 975 self.parent.drawRect(x + self.x, y + self.y, width, height, string, fgcolor, bgcolor)
976
977 - def drawFrame(self, x, y, width, height, string, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
978 # inherit docstring 979 x, y, width, height = self._normalizeRect(x, y, width, height) 980 self.parent.drawFrame(x + self.x, y + self.y, width, height, string, fgcolor, bgcolor)
981
982 - def getChar(self, x, y):
983 # inherit docstring 984 x, y = self._normalizePoint(x, y) 985 return self.console.getChar(self._translate(x, y))
986
987 - def __repr__(self):
988 return "<Window(X=%i Y=%i Width=%i Height=%i)>" % (self.x, self.y, 989 self.width, 990 self.height)
991
992 993 -class Typewriter(object):
994 """Converts a console into a scrolling text log that respects special 995 characters. 996 997 This class works best on a L{Window} or off-screen L{Console} instance. 998 In a L{Window} for example the scrolling text is limited to the L{Window}'s 999 isolated area. 1000 """ 1001
1002 - def __init__(self, console):
1003 """Add a virtual cursor to a L{Console} or L{Window} instance. 1004 1005 @type console: L{Console} or L{Window} 1006 """ 1007 warnings.warn("Typewriter is no longer needed, use Console or Window objects", DeprecationWarning) 1008 assert isinstance(console, (Console, Window)), 'console parameter must be a Console or Window instance, got %s' % repr(console) 1009 self.parent = console 1010 if isinstance(self.parent, Console): 1011 self.console = self.parent 1012 else: 1013 self.console = self.parent.console 1014 self._cursor = (0, 0) # cursor position 1015 self.scrollMode = 'scroll' #can be 'scroll', 'error' 1016 self.fgcolor = _formatColor((255, 255, 255)) 1017 self.bgcolor = _formatColor((0, 0, 0)) 1018 self._bgblend = 1 # SET
1019
1020 - def _normalize(self, x, y):
1021 """return the normalized the cursor position.""" 1022 width, height = self.parent.getSize() 1023 while x >= width: 1024 x -= width 1025 y += 1 1026 while y >= height: 1027 if self.scrollMode == 'scroll': 1028 y -= 1 1029 self.parent.scroll(0, -1) 1030 elif self.scrollMode == 'error': 1031 # reset the cursor on error 1032 self._cursor = (0, 0) 1033 raise TDLError('Typewriter cursor has reached the end of the console') 1034 return (x, y)
1035
1036 - def getCursor(self):
1037 """Return the virtual cursor position. 1038 1039 @rtype: (int, int) 1040 @return: Returns (x, y) a 2-integer tuple containing where the next 1041 L{addChar} or L{addStr} will start at. 1042 1043 This can be changed with the L{move} method.""" 1044 x, y = self._cursor 1045 width, height = self.parent.getSize() 1046 while x >= width: 1047 x -= width 1048 y += 1 1049 if y >= height and self.scrollMode == 'scroll': 1050 y = height - 1 1051 return x, y
1052
1053 - def move(self, x, y):
1054 """Move the virtual cursor. 1055 1056 @type x: int 1057 @param x: X position to place the cursor. 1058 @type y: int 1059 @param y: Y position to place the cursor. 1060 """ 1061 self._cursor = self.parent._normalizePoint(x, y)
1062
1063 - def setFG(self, color):
1064 """Change the foreground color""" 1065 assert _iscolor(color) 1066 assert color is not None 1067 self.fgcolor = _formatColor(color) 1068 if self.console._colorLock is self: 1069 _lib.TCOD_console_set_default_foreground(self.console, self.fgcolor)
1070
1071 - def setBG(self, color):
1072 """Change the background color""" 1073 assert _iscolor(color) 1074 assert color is not None 1075 self.bgcolor = _formatColor(color) 1076 if self.console._colorLock is self: 1077 _lib.TCOD_console_set_default_background(self.console, self.bgcolor)
1078
1079 - def _updateConsole(self):
1080 """Make sure the colors on a console match the Typewriter instance""" 1081 if self.console._colorLock is not self: 1082 self.console._colorLock = self 1083 1084 _lib.TCOD_console_set_default_background(self.console, self.bgcolor) 1085 _lib.TCOD_console_set_default_foreground(self.console, self.fgcolor)
1086 1087
1088 - def addChar(self, char):
1089 """Draw a single character at the cursor.""" 1090 if char == '\n': # line break 1091 x = 0 1092 y += 1 1093 return 1094 if char == '\r': # return 1095 x = 0 1096 return 1097 x, y = self._normalize(*self.cursor) 1098 self._cursor = [x + 1, y] # advance cursor on next draw 1099 self._updateConsole() 1100 x, y = self.parent._translate(x, y) 1101 _lib.TCOD_console_put_char(self.console._as_parameter_, x, y, _formatChar(char), self._bgblend)
1102 1103
1104 - def addStr(self, string):
1105 """Write a string at the cursor. Handles special characters such as newlines. 1106 1107 @type string: string 1108 @param string: 1109 """ 1110 x, y = self._cursor 1111 for char in string: 1112 if char == '\n': # line break 1113 x = 0 1114 y += 1 1115 continue 1116 if char == '\r': # return 1117 x = 0 1118 continue 1119 x, y = self._normalize(x, y) 1120 self.parent.drawChar(x, y, char, self.fgcolor, self.bgcolor) 1121 x += 1 1122 self._cursor = (x, y)
1123
1124 - def write(self, string):
1125 """This method mimics basic file-like behaviour. 1126 1127 Because of this method you can replace sys.stdout or sys.stderr with 1128 a L{Typewriter} instance. 1129 1130 @type string: string 1131 """ 1132 # some 'basic' line buffer stuff. 1133 # there must be an easier way to do this. The textwrap module didn't 1134 # help much. 1135 x, y = self._normalize(*self._cursor) 1136 width, height = self.parent.getSize() 1137 wrapper = textwrap.TextWrapper(initial_indent=(' '*x), width=width) 1138 writeLines = [] 1139 for line in string.split('\n'): 1140 if line: 1141 writeLines += wrapper.wrap(line) 1142 wrapper.initial_indent = '' 1143 else: 1144 writeLines.append([]) 1145 1146 for line in writeLines: 1147 x, y = self._normalize(x, y) 1148 self.parent.drawStr(x, y, line[x:], self.fgcolor, self.bgcolor) 1149 y += 1 1150 x = 0 1151 y -= 1 1152 self._cursor = (x, y)
1153
1154 1155 -def init(width, height, title=None, fullscreen=False, renderer='OPENGL'):
1156 """Start the main console with the given width and height and return the 1157 root console. 1158 1159 Call the consoles drawing functions. Then remember to use L{tdl.flush} to 1160 make what's drawn visible on the console. 1161 1162 @type width: int 1163 @param width: width of the root console (in tiles) 1164 1165 @type height: int 1166 @param height: height of the root console (in tiles) 1167 1168 @type title: string 1169 @param title: Text to display as the window title. 1170 1171 If left None it defaults to the running scripts filename. 1172 1173 @type fullscreen: boolean 1174 @param fullscreen: Can be set to True to start in fullscreen mode. 1175 1176 @type renderer: string 1177 @param renderer: Can be one of 'GLSL', 'OPENGL', or 'SDL'. 1178 1179 Due to way Python works you're unlikely to see much of an 1180 improvement by using 'GLSL' or 'OPENGL' as most of the 1181 time Python is slow interacting with the console and the 1182 rendering itself is pretty fast even on 'SDL'. 1183 1184 @rtype: L{Console} 1185 @return: The root console. Only what is drawn on the root console is 1186 what's visible after a call to L{tdl.flush}. 1187 After the root console is garbage collected, the window made by 1188 this function will close. 1189 """ 1190 RENDERERS = {'GLSL': 0, 'OPENGL': 1, 'SDL': 2} 1191 global _rootinitialized, _rootConsoleRef 1192 if not _fontinitialized: # set the default font to the one that comes with tdl 1193 setFont(_unpackfile('terminal8x8.png'), None, None, True, True) 1194 1195 if renderer.upper() not in RENDERERS: 1196 raise TDLError('No such render type "%s", expected one of "%s"' % (renderer, '", "'.join(RENDERERS))) 1197 renderer = RENDERERS[renderer.upper()] 1198 1199 # If a console already exists then make a clone to replace it 1200 if _rootConsoleRef and _rootConsoleRef(): 1201 oldroot = _rootConsoleRef() 1202 rootreplacement = Console(oldroot.width, oldroot.height) 1203 rootreplacement.blit(oldroot) 1204 oldroot._replace(rootreplacement) 1205 del rootreplacement 1206 1207 if title is None: # use a default title 1208 if sys.argv: 1209 # Use the script filename as the title. 1210 title = os.path.basename(sys.argv[0]) 1211 else: 1212 title = 'python-tdl' 1213 1214 _lib.TCOD_console_init_root(width, height, _encodeString(title), fullscreen, renderer) 1215 1216 #event.get() # flush the libtcod event queue to fix some issues 1217 # issues may be fixed already 1218 1219 event._eventsflushed = False 1220 _rootinitialized = True 1221 rootconsole = Console._newConsole(ctypes.c_void_p()) 1222 _rootConsoleRef = weakref.ref(rootconsole) 1223 1224 return rootconsole
1225
1226 -def flush():
1227 """Make all changes visible and update the screen. 1228 1229 Remember to call this function after drawing operations. 1230 Calls to flush will enfore the frame rate limit set by L{tdl.setFPS}. 1231 1232 This function can only be called after L{tdl.init} 1233 """ 1234 if not _rootinitialized: 1235 raise TDLError('Cannot flush without first initializing with tdl.init') 1236 1237 _lib.TCOD_console_flush()
1238
1239 -def setFont(path, columns=None, rows=None, columnFirst=False, 1240 greyscale=False, altLayout=False):
1241 """Changes the font to be used for this session. 1242 This should be called before L{tdl.init} 1243 1244 If the font specifies its size in its filename (i.e. font_NxN.png) then this 1245 function can auto-detect the tileset formatting and the parameters columns 1246 and rows can be left None. 1247 1248 While it's possible you can change the font mid program it can sometimes 1249 break in rare circumstances. So use caution when doing this. 1250 1251 @type path: string 1252 @param path: Must be a string filepath where a bmp or png file is found. 1253 1254 @type columns: int 1255 @param columns: Number of columns in the tileset. 1256 1257 Can be left None for auto-detection. 1258 1259 @type rows: int 1260 @param rows: Number of rows in the tileset. 1261 1262 Can be left None for auto-detection. 1263 1264 @type columnFirst: boolean 1265 @param columnFirst: Defines if the characer order goes along the rows or 1266 colomns. 1267 It should be True if the charater codes 0-15 are in the 1268 first column. 1269 And should be False if the characters 0-15 1270 are in the first row. 1271 1272 @type greyscale: boolean 1273 @param greyscale: Creates an anti-aliased font from a greyscale bitmap. 1274 Otherwise it uses the alpha channel for anti-aliasing. 1275 1276 Unless you actually need anti-aliasing from a font you 1277 know uses a smooth greyscale channel you should leave 1278 this on False. 1279 1280 @type altLayout: boolean 1281 @param altLayout: An alternative layout with space in the upper left 1282 corner. 1283 The colomn parameter is ignored if this is True, 1284 find examples of this layout in the font/libtcod/ 1285 directory included with the python-tdl source. 1286 1287 @raise TDLError: Will be raised if no file is found at path or if auto- 1288 detection fails. 1289 1290 @note: A png file that's been optimized can fail to load correctly on 1291 MAC OS X creating a garbled mess when rendering. 1292 Don't use a program like optipng or just use bmp files instead if 1293 you want your program to work on macs. 1294 """ 1295 # put up some constants that are only used here 1296 FONT_LAYOUT_ASCII_INCOL = 1 1297 FONT_LAYOUT_ASCII_INROW = 2 1298 FONT_TYPE_GREYSCALE = 4 1299 FONT_LAYOUT_TCOD = 8 1300 global _fontinitialized 1301 _fontinitialized = True 1302 flags = 0 1303 if altLayout: 1304 flags |= FONT_LAYOUT_TCOD 1305 elif columnFirst: 1306 flags |= FONT_LAYOUT_ASCII_INCOL 1307 else: 1308 flags |= FONT_LAYOUT_ASCII_INROW 1309 if greyscale: 1310 flags |= FONT_TYPE_GREYSCALE 1311 if not os.path.exists(path): 1312 raise TDLError('no file exists at: "%s"' % path) 1313 path = os.path.abspath(path) 1314 1315 # and the rest is the auto-detect script 1316 imgSize = _getImageSize(path) # try to find image size 1317 if imgSize: 1318 imgWidth, imgHeight = imgSize 1319 # try to get font size from filename 1320 match = re.match('.*?([0-9]+)[xX]([0-9]+)', os.path.basename(path)) 1321 if match: 1322 fontWidth, fontHeight = match.groups() 1323 fontWidth, fontHeight = int(fontWidth), int(fontHeight) 1324 1325 # estimate correct tileset size 1326 estColumns, remC = divmod(imgWidth, fontWidth) 1327 estRows, remR = divmod(imgHeight, fontHeight) 1328 if remC or remR: 1329 warnings.warn("Font may be incorrectly formatted.") 1330 1331 if not columns: 1332 columns = estColumns 1333 if not rows: 1334 rows = estRows 1335 else: 1336 # the font name excluded the fonts size 1337 if not (columns and rows): 1338 # no matched font size and no tileset is given 1339 raise TDLError('%s has no font size in filename' % os.path.basename(path)) 1340 1341 if columns and rows: 1342 # confirm user set options 1343 if (fontWidth * columns != imgWidth or 1344 fontHeight * rows != imgHeight): 1345 warnings.warn("setFont parameters are set as if the image size is (%d, %d) when the detected size is actually (%i, %i)" 1346 % (fontWidth * columns, fontHeight * rows, 1347 imgWidth, imgHeight)) 1348 else: 1349 warnings.warn("%s is probably not an image." % os.path.basename(path)) 1350 1351 if not (columns and rows): 1352 # didn't auto-detect 1353 raise TDLError('Can not auto-detect the tileset of %s' % os.path.basename(path)) 1354 1355 _lib.TCOD_console_set_custom_font(_encodeString(path), flags, columns, rows)
1356
1357 -def getFullscreen():
1358 """Returns True if program is fullscreen. 1359 1360 @rtype: boolean 1361 @return: Returns True if the window is in fullscreen mode. 1362 Otherwise returns False. 1363 """ 1364 if not _rootinitialized: 1365 raise TDLError('Initialize first with tdl.init') 1366 return _lib.TCOD_console_is_fullscreen()
1367
1368 -def setFullscreen(fullscreen):
1369 """Changes the fullscreen state. 1370 1371 @type fullscreen: boolean 1372 """ 1373 if not _rootinitialized: 1374 raise TDLError('Initialize first with tdl.init') 1375 _lib.TCOD_console_set_fullscreen(fullscreen)
1376
1377 -def setTitle(title):
1378 """Change the window title. 1379 1380 @type title: string 1381 """ 1382 if not _rootinitialized: 1383 raise TDLError('Not initilized. Set title with tdl.init') 1384 _lib.TCOD_console_set_window_title(_encodeString(title))
1385
1386 -def screenshot(path=None):
1387 """Capture the screen and save it as a png file 1388 1389 @type path: string 1390 @param path: The filepath to save the screenshot. 1391 1392 If path is None then the image will be placed in the current 1393 folder with the names: 1394 screenshot001.png, screenshot002.png, ... 1395 """ 1396 if not _rootinitialized: 1397 raise TDLError('Initialize first with tdl.init') 1398 if isinstance(path, str): 1399 _lib.TCOD_sys_save_screenshot(_encodeString(path)) 1400 elif path is None: # save to screenshot001.png, screenshot002.png, ... 1401 filelist = os.listdir('.') 1402 n = 1 1403 filename = 'screenshot%.3i.png' % n 1404 while filename in filelist: 1405 n += 1 1406 filename = 'screenshot%.3i.png' % n 1407 _lib.TCOD_sys_save_screenshot(_encodeString(filename)) 1408 else: # assume file like obj 1409 #save to temp file and copy to file-like obj 1410 tmpname = os.tempnam() 1411 _lib.TCOD_sys_save_screenshot(_encodeString(tmpname)) 1412 with tmpname as tmpfile: 1413 path.write(tmpfile.read()) 1414 os.remove(tmpname)
1415 #else:
1416 # raise TypeError('path is an invalid type: %s' % type(path)) 1417 1418 -def setFPS(frameRate):
1419 """Set the maximum frame rate. 1420 1421 @type frameRate: int 1422 @param frameRate: Further calls to L{tdl.flush} will limit the speed of 1423 the program to run at <frameRate> frames per second. Can 1424 also be set to 0 to run without a limit. 1425 1426 Defaults to None. 1427 """ 1428 if frameRate is None: 1429 frameRate = 0 1430 assert isinstance(frameRate, _INTTYPES), 'frameRate must be an integer or None, got: %s' % repr(frameRate) 1431 _lib.TCOD_sys_set_fps(frameRate)
1432
1433 -def getFPS():
1434 """Return the current frames per second of the running program set by 1435 L{setFPS} 1436 1437 @rtype: int 1438 @return: Returns the frameRate set by setFPS. 1439 If set to no limit, this will return 0. 1440 """ 1441 return _lib.TCOD_sys_get_fps()
1442
1443 -def forceResolution(width, height):
1444 """Change the fullscreen resoulution 1445 1446 @type width: int 1447 @type height: int 1448 """ 1449 _lib.TCOD_sys_force_fullscreen_resolution(width, height)
1450 1451 __all__ = [_var for _var in locals().keys() if _var[0] != '_' and _var not in 1452 ['sys', 'os', 'ctypes', 'array', 'weakref', 'itertools', 'textwrap', 1453 'struct', 're', 'warnings']] # remove modules from __all__ 1454 __all__ += ['_MetaConsole'] # keep this object public to show the documentation in epydoc 1455 __all__.remove('Typewriter') # Hide the deprecated Typewriter class 1456 1457 __license__ = "New BSD License" 1458 __email__ = "4b796c65+pythonTDL@gmail.com" 1459