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