Package untdl
[frames] | no frames]

Source Code for Package untdl

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