Skip to content

Commit 9554fab

Browse files
committed
Switch Python samples to use contexts.
This removes the credits banner from the samples since that doesn't support contexts. It's possible this won't be placed in the library with a working version.
1 parent 007ad8d commit 9554fab

File tree

1 file changed

+89
-72
lines changed

1 file changed

+89
-72
lines changed

examples/samples_tcod.py

Lines changed: 89 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
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+
810
import copy
911
import math
1012
import os
@@ -37,10 +39,16 @@ def get_data(path: str) -> str:
3739
SAMPLE_SCREEN_Y = 10
3840
FONT = 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")
4146
sample_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

4654
class 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):
487486
DARK_GROUND = (50, 50, 150)
488487
LIGHT_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

515514
FOV_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

15141519
def 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

15431556
def 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

15481564
def draw_samples_menu():
@@ -1564,28 +1580,29 @@ def draw_samples_menu():
15641580

15651581

15661582
def 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

15871605
def 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

Comments
 (0)