55# To the extent possible under law, the libtcod maintainers have waived all
66# copyright and related or neighboring rights to these samples.
77# https://creativecommons.org/publicdomain/zero/1.0/
8+ from __future__ import annotations
9+
810import copy
911import math
1012import os
@@ -37,10 +39,16 @@ def get_data(path: str) -> str:
3739SAMPLE_SCREEN_Y = 10
3840FONT = get_data ("fonts/dejavu10x10_gs_tc.png" )
3941
40- root_console = None
42+ # Mutable global names.
43+ context : tcod .context .Context
44+ tileset : tcod .tileset .Tileset
45+ root_console = tcod .Console (80 , 50 , order = "F" )
4146sample_console = tcod .console .Console (
4247 SAMPLE_SCREEN_WIDTH , SAMPLE_SCREEN_HEIGHT , order = "F"
4348)
49+ cur_sample = 0 # Current selected sample.
50+ frame_times = [time .perf_counter ()]
51+ frame_length = [0.0 ]
4452
4553
4654class Sample (tcod .event .EventDispatch ):
@@ -54,7 +62,7 @@ def on_draw(self):
5462 pass
5563
5664 def ev_keydown (self , event : tcod .event .KeyDown ):
57- global cur_sample
65+ global cur_sample , context
5866 if event .sym == tcod .event .K_DOWN :
5967 cur_sample = (cur_sample + 1 ) % len (SAMPLES )
6068 SAMPLES [cur_sample ].on_enter ()
@@ -71,16 +79,17 @@ def ev_keydown(self, event: tcod.event.KeyDown):
7179 elif event .sym == tcod .event .K_PRINTSCREEN or event .sym == ord ("p" ):
7280 print ("screenshot" )
7381 if event .mod & tcod .event .KMOD_LALT :
74- tcod .console_save_apf (None , "samples.apf" )
82+ tcod .console_save_apf (root_console , "samples.apf" )
7583 print ("apf" )
7684 else :
7785 tcod .sys_save_screenshot ()
7886 print ("png" )
7987 elif event .sym == tcod .event .K_ESCAPE :
8088 raise SystemExit ()
8189 elif event .sym in RENDERER_KEYS :
82- tcod .sys_set_renderer (RENDERER_KEYS [event .sym ])
83- draw_renderer_menu ()
90+ # Swap the active context for one with a different renderer.
91+ context .close ()
92+ context = init_context (RENDERER_KEYS [event .sym ])
8493
8594 def ev_quit (self , event : tcod .event .Quit ):
8695 raise SystemExit ()
@@ -101,9 +110,6 @@ def __init__(self):
101110 # corner indexes
102111 self .corners = np .array ([0 , 1 , 2 , 3 ])
103112
104- def on_enter (self ):
105- tcod .sys_set_fps (0 )
106-
107113 def on_draw (self ):
108114 self .slide_corner_colors ()
109115 self .interpolate_corner_colors ()
@@ -200,7 +206,6 @@ def __init__(self):
200206
201207 def on_enter (self ):
202208 self .counter = time .perf_counter ()
203- tcod .sys_set_fps (0 )
204209 # get a "screenshot" of the current sample screen
205210 sample_console .blit (dest = self .screenshot )
206211
@@ -273,9 +278,6 @@ def ev_keydown(self, event: tcod.event.KeyDown):
273278 else :
274279 super ().ev_keydown (event )
275280
276- def on_enter (self ):
277- tcod .sys_set_fps (0 )
278-
279281 def on_draw (self ):
280282 alpha = 0.0
281283 if (self .bk_flag & 0xFF ) == tcod .BKGND_ALPH :
@@ -378,9 +380,6 @@ def get_noise(self):
378380 seed = None ,
379381 )
380382
381- def on_enter (self ):
382- tcod .sys_set_fps (0 )
383-
384383 def on_draw (self ):
385384 self .dx = time .perf_counter () * 0.25
386385 self .dy = time .perf_counter () * 0.25
@@ -487,7 +486,7 @@ def ev_keydown(self, event: tcod.event.KeyDown):
487486DARK_GROUND = (50 , 50 , 150 )
488487LIGHT_GROUND = (200 , 180 , 50 )
489488
490- SAMPLE_MAP = [
489+ SAMPLE_MAP_ = [
491490 "##############################################" ,
492491 "####################### #################" ,
493492 "##################### # ###############" ,
@@ -510,7 +509,7 @@ def ev_keydown(self, event: tcod.event.KeyDown):
510509 "##############################################" ,
511510]
512511
513- SAMPLE_MAP = np .array ([list (line ) for line in SAMPLE_MAP ]).transpose ()
512+ SAMPLE_MAP = np .array ([list (line ) for line in SAMPLE_MAP_ ]).transpose ()
514513
515514FOV_ALGO_NAMES = [
516515 "BASIC " ,
@@ -576,9 +575,6 @@ def draw_ui(self):
576575 bg = None ,
577576 )
578577
579- def on_enter (self ):
580- tcod .sys_set_fps (60 )
581-
582578 def on_draw (self ):
583579 sample_console .clear ()
584580 # Draw the help text & player @.
@@ -696,7 +692,6 @@ def __init__(self):
696692 self .dijk = tcod .dijkstra_new (self .map )
697693
698694 def on_enter (self ):
699- tcod .sys_set_fps (60 )
700695 # we draw the foreground only the first time.
701696 # during the player movement, only the @ is redrawn.
702697 # the rest impacts only the background color
@@ -785,7 +780,7 @@ def on_draw(self):
785780 )
786781
787782 # move the creature
788- self .busy -= tcod . sys_get_last_frame_length ()
783+ self .busy -= frame_length [ - 1 ]
789784 if self .busy <= 0.0 :
790785 self .busy = 0.2
791786 if self .using_astar :
@@ -1110,9 +1105,6 @@ def __init__(self):
11101105 self .img .set_key_color (tcod .black )
11111106 self .circle = tcod .image_load (get_data ("img/circle.png" ))
11121107
1113- def on_enter (self ):
1114- tcod .sys_set_fps (0 )
1115-
11161108 def on_draw (self ):
11171109 sample_console .clear ()
11181110 x = sample_console .width / 2 + math .cos (time .time ()) * 10.0
@@ -1162,7 +1154,6 @@ def __init__(self):
11621154 def on_enter (self ):
11631155 tcod .mouse_move (320 , 200 )
11641156 tcod .mouse_show_cursor (True )
1165- tcod .sys_set_fps (60 )
11661157
11671158 def ev_mousemotion (self , event : tcod .event .MouseMotion ):
11681159 self .motion = event
@@ -1188,9 +1179,9 @@ def on_draw(self):
11881179 sample_console .print (
11891180 1 ,
11901181 1 ,
1191- "Mouse position : %4dx%4d\n "
1192- "Mouse cell : %4dx%4d\n "
1193- "Mouse movement : %4dx%4d\n "
1182+ "Pixel position : %4dx%4d\n "
1183+ "Tile position : %4dx%4d\n "
1184+ "Tile movement : %4dx%4d\n "
11941185 "Left button : %s\n "
11951186 "Right button : %s\n "
11961187 "Middle button : %s\n "
@@ -1235,9 +1226,6 @@ def __init__(self):
12351226 self .names = []
12361227 self .sets = None
12371228
1238- def on_enter (self ):
1239- tcod .sys_set_fps (60 )
1240-
12411229 def on_draw (self ):
12421230 if self .nbsets == 0 :
12431231 # parse all *.cfg files in data/namegen
@@ -1268,7 +1256,7 @@ def on_draw(self):
12681256 bg = None ,
12691257 alignment = tcod .RIGHT ,
12701258 )
1271- self .delay += tcod . sys_get_last_frame_length ()
1259+ self .delay += frame_length [ - 1 ]
12721260 if self .delay > 0.5 :
12731261 self .delay -= 0.5
12741262 self .names .append (tcod .namegen_generate (self .sets [self .curset ]))
@@ -1341,7 +1329,6 @@ def __init__(self):
13411329
13421330 def on_enter (self ):
13431331 global frac_t , abs_t , lights , tex_r , tex_g , tex_b
1344- tcod .sys_set_fps (0 )
13451332 sample_console .clear () # render status message
13461333 sample_console .print (
13471334 1 , SCREEN_H - 3 , "Renderer: NumPy" , fg = tcod .white , bg = None
@@ -1358,7 +1345,7 @@ def on_draw(self):
13581345 global use_numpy , frac_t , abs_t , lights , tex_r , tex_g , tex_b , xc , yc
13591346 global texture , texture2 , brightness2 , R2 , G2 , B2
13601347
1361- time_delta = tcod . sys_get_last_frame_length () * SPEED # advance time
1348+ time_delta = frame_length [ - 1 ] * SPEED # advance time
13621349 frac_t += time_delta # increase fractional (always < 1.0) time
13631350 abs_t += time_delta # increase absolute elapsed time
13641351 # integer time units that passed this frame (number of texture pixels
@@ -1508,41 +1495,70 @@ def on_draw(self):
15081495 FastRenderSample (),
15091496)
15101497
1511- cur_sample = 0
1498+ def init_context (renderer : int ) -> tcod .context .Context :
1499+ """Return a new context with common parameters set.
1500+
1501+ This function exists to more easily switch between renderers.
1502+ """
1503+ libtcod_version = "%i.%i.%i" % (
1504+ tcod .lib .TCOD_MAJOR_VERSION ,
1505+ tcod .lib .TCOD_MINOR_VERSION ,
1506+ tcod .lib .TCOD_PATCHLEVEL ,
1507+ )
1508+ return tcod .context .new (
1509+ columns = root_console .width ,
1510+ rows = root_console .height ,
1511+ title = f"python-tcod samples"
1512+ f" (python-tcod { tcod .__version__ } , libtcod { libtcod_version } )" ,
1513+ renderer = renderer ,
1514+ vsync = False , # VSync turned off since this is for benchmarking.
1515+ tileset = tileset ,
1516+ )
15121517
15131518
15141519def main ():
1515- global cur_sample , root_console
1516- tcod .console_set_custom_font (
1517- FONT , tcod .FONT_TYPE_GREYSCALE | tcod .FONT_LAYOUT_TCOD
1518- )
1519- root_console = tcod .console_init_root (
1520- 80 , 50 , "python-tcod samples" , False , tcod .RENDERER_SDL2 , order = "F"
1520+ global context , tileset
1521+ tileset = tcod .tileset .load_tilesheet (
1522+ FONT , 32 , 8 , tcod .tileset .CHARMAP_TCOD
15211523 )
1522- credits_end = False
1523- SAMPLES [cur_sample ].on_enter ()
1524- draw_samples_menu ()
1525- draw_renderer_menu ()
1526-
1527- while not tcod .console_is_window_closed ():
1528- root_console .clear ()
1529- draw_samples_menu ()
1530- draw_renderer_menu ()
1531- # render credits
1532- if not credits_end :
1533- credits_end = tcod .console_credits_render (60 , 43 , 0 )
1534-
1535- # render the sample
1536- SAMPLES [cur_sample ].on_draw ()
1537- sample_console .blit (root_console , SAMPLE_SCREEN_X , SAMPLE_SCREEN_Y )
1538- draw_stats ()
1539- tcod .console_flush ()
1540- handle_events ()
1524+ context = init_context (tcod .RENDERER_SDL2 )
1525+ try :
1526+ credits_end = False
1527+ SAMPLES [cur_sample ].on_enter ()
1528+
1529+ while True :
1530+ root_console .clear ()
1531+ draw_samples_menu ()
1532+ draw_renderer_menu ()
1533+
1534+ # render the sample
1535+ SAMPLES [cur_sample ].on_draw ()
1536+ sample_console .blit (root_console , SAMPLE_SCREEN_X , SAMPLE_SCREEN_Y )
1537+ draw_stats ()
1538+ context .present (root_console )
1539+ handle_time ()
1540+ handle_events ()
1541+ finally :
1542+ # Normally context would be used in a with block and closed
1543+ # automatically. but since this context might be switched to one with a
1544+ # different renderer it is closed manually here.
1545+ context .close ()
1546+
1547+
1548+ def handle_time ():
1549+ if len (frame_times ) > 100 :
1550+ frame_times .pop (0 )
1551+ frame_length .pop (0 )
1552+ frame_times .append (time .perf_counter ())
1553+ frame_length .append (frame_times [- 1 ] - frame_times [- 2 ])
15411554
15421555
15431556def handle_events ():
15441557 for event in tcod .event .get ():
1558+ context .convert_event (event )
15451559 SAMPLES [cur_sample ].dispatch (event )
1560+ if isinstance (event , tcod .event .Quit ):
1561+ raise SystemExit ()
15461562
15471563
15481564def draw_samples_menu ():
@@ -1564,28 +1580,29 @@ def draw_samples_menu():
15641580
15651581
15661582def draw_stats ():
1583+ try :
1584+ fps = 1 / (sum (frame_length ) / len (frame_length ))
1585+ except ZeroDivisionError :
1586+ fps = 0
1587+
1588+ style = {"fg" : tcod .grey , "bg" : None , "alignment" : tcod .RIGHT }
15671589 root_console .print (
15681590 79 ,
15691591 46 ,
1570- " last frame : %3d ms (%3d fps)"
1571- % (tcod .sys_get_last_frame_length () * 1000.0 , tcod .sys_get_fps ()),
1572- fg = tcod .grey ,
1573- bg = None ,
1574- alignment = tcod .RIGHT ,
1592+ "last frame :%5.1f ms (%4d fps)"
1593+ % (frame_length [- 1 ] * 1000.0 , fps ),
1594+ ** style ,
15751595 )
15761596 root_console .print (
15771597 79 ,
15781598 47 ,
1579- "elapsed : %8d ms %4 .2fs"
1599+ "elapsed : %8d ms %5 .2fs"
15801600 % (time .perf_counter () * 1000 , time .perf_counter ()),
1581- fg = tcod .grey ,
1582- bg = None ,
1583- alignment = tcod .RIGHT ,
1601+ ** style ,
15841602 )
15851603
15861604
15871605def draw_renderer_menu ():
1588- current_renderer = tcod .sys_get_renderer ()
15891606 root_console .print (
15901607 42 ,
15911608 46 - (tcod .NB_RENDERERS + 1 ),
@@ -1594,7 +1611,7 @@ def draw_renderer_menu():
15941611 bg = tcod .black ,
15951612 )
15961613 for i , name in enumerate (RENDERER_NAMES ):
1597- if i == current_renderer :
1614+ if i == context . renderer_type :
15981615 fg = tcod .white
15991616 bg = tcod .light_blue
16001617 else :
0 commit comments