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