PyTermint 0.0.2__tar.gz → 0.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pytermint-0.0.2 → pytermint-0.0.4}/PKG-INFO +6 -6
- {pytermint-0.0.2 → pytermint-0.0.4}/README.md +4 -4
- {pytermint-0.0.2 → pytermint-0.0.4}/pyproject.toml +2 -2
- {pytermint-0.0.2 → pytermint-0.0.4}/src/PyTermint/PyTerm.py +76 -55
- {pytermint-0.0.2 → pytermint-0.0.4}/LICENSE +0 -0
- {pytermint-0.0.2 → pytermint-0.0.4}/src/PyTermint/__init__.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyTermint
|
|
3
|
-
Version: 0.0.
|
|
4
|
-
Summary: A terminal interface that abstracts
|
|
3
|
+
Version: 0.0.4
|
|
4
|
+
Summary: A simple, light weight (under 27k), and 'No Dependencies' (except in linux but has auto fallbacks) terminal interface that abstracts complex ansi codes into a tilemap with 3 bit rgb support for charecter fore/background.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Antlar256/PyTerm
|
|
6
6
|
Project-URL: Issues, https://github.com/Antlar256/PyTerm/issues
|
|
7
7
|
Author-email: Antlar256 <antonio0granell2@gmail.com>
|
|
@@ -12,8 +12,8 @@ Classifier: Programming Language :: Python :: 3
|
|
|
12
12
|
Requires-Python: >=3.9
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
|
|
15
|
-
#
|
|
16
|
-
This is a cross-platform terminal abstraction that converts a tile map to a non-flickering terminal output with 3 bit rgb support using escape codes. It also has significant amounts of input automation for things like typing and movement. It clocks in at
|
|
15
|
+
# PyTermint
|
|
16
|
+
This is a cross-platform terminal abstraction that converts a tile map to a non-flickering terminal output with 3 bit rgb support using escape codes. It also has significant amounts of input automation for things like typing and movement. It clocks in at just under 27k bytes (k is 1024) *(uncompressed, It goes down to 16k just with windows file compression)* and has no significant dependencies outside of the [***Python Standard Library***](https://docs.python.org/3/library/index.html) (*other than evdev for linux input but it handles the lack of this automatically*). While ~27k bytes sounds like a lot this is boiler plate not in your project which means a full colored snake game comes in at around 2.2k bytes. It also has a large amount of graphics macros for things like drawing a window, a line, a rectangle or a text_box. Through gplot() the horozontal and vertical resolution are doubled into a 1bpp bitmap with 2x2 pixel 3bpp rgb attribute coloring. The array is edited and read through screen[y][x].
|
|
17
17
|
***
|
|
18
18
|
* **Install with "*pip install PyTermint*"**
|
|
19
19
|
* **Import as "*import PyTerm*"**
|
|
@@ -21,8 +21,8 @@ This is a cross-platform terminal abstraction that converts a tile map to a non-
|
|
|
21
21
|
* **Create a *tick()* command that takes as inputs *tick(screen, vars, keys)*. Screen is an array, vars is the dict you initialized in *init* and keys which is a set of every key thats pressed**
|
|
22
22
|
* **Call the *run(tick_func, init_func)***
|
|
23
23
|
***
|
|
24
|
-
```
|
|
25
|
-
|
|
24
|
+
```w
|
|
25
|
+
import PyTerm as pt
|
|
26
26
|
from PyTerm import clear, blit, color, TILE_SET, HEIGHT, WIDTH, pressed
|
|
27
27
|
|
|
28
28
|
def init(screen):
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#
|
|
2
|
-
This is a cross-platform terminal abstraction that converts a tile map to a non-flickering terminal output with 3 bit rgb support using escape codes. It also has significant amounts of input automation for things like typing and movement. It clocks in at
|
|
1
|
+
# PyTermint
|
|
2
|
+
This is a cross-platform terminal abstraction that converts a tile map to a non-flickering terminal output with 3 bit rgb support using escape codes. It also has significant amounts of input automation for things like typing and movement. It clocks in at just under 27k bytes (k is 1024) *(uncompressed, It goes down to 16k just with windows file compression)* and has no significant dependencies outside of the [***Python Standard Library***](https://docs.python.org/3/library/index.html) (*other than evdev for linux input but it handles the lack of this automatically*). While ~27k bytes sounds like a lot this is boiler plate not in your project which means a full colored snake game comes in at around 2.2k bytes. It also has a large amount of graphics macros for things like drawing a window, a line, a rectangle or a text_box. Through gplot() the horozontal and vertical resolution are doubled into a 1bpp bitmap with 2x2 pixel 3bpp rgb attribute coloring. The array is edited and read through screen[y][x].
|
|
3
3
|
***
|
|
4
4
|
* **Install with "*pip install PyTermint*"**
|
|
5
5
|
* **Import as "*import PyTerm*"**
|
|
@@ -7,8 +7,8 @@ This is a cross-platform terminal abstraction that converts a tile map to a non-
|
|
|
7
7
|
* **Create a *tick()* command that takes as inputs *tick(screen, vars, keys)*. Screen is an array, vars is the dict you initialized in *init* and keys which is a set of every key thats pressed**
|
|
8
8
|
* **Call the *run(tick_func, init_func)***
|
|
9
9
|
***
|
|
10
|
-
```
|
|
11
|
-
|
|
10
|
+
```w
|
|
11
|
+
import PyTerm as pt
|
|
12
12
|
from PyTerm import clear, blit, color, TILE_SET, HEIGHT, WIDTH, pressed
|
|
13
13
|
|
|
14
14
|
def init(screen):
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "PyTermint"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.4"
|
|
4
4
|
authors = [
|
|
5
5
|
{ name="Antlar256", email="antonio0granell2@gmail.com" },
|
|
6
6
|
]
|
|
7
|
-
description = "A terminal interface that abstracts
|
|
7
|
+
description = "A simple, light weight (under 27k), and 'No Dependencies' (except in linux but has auto fallbacks) terminal interface that abstracts complex ansi codes into a tilemap with 3 bit rgb support for charecter fore/background."
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
requires-python = ">=3.9"
|
|
10
10
|
classifiers = [
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#PyTerm.py
|
|
2
2
|
"""
|
|
3
|
-
This is a terminal engine which is desined to be imported by other python files to use its features
|
|
3
|
+
This is a terminal engine which is desined to be imported by other python files to use its features. The array is edited and read through screen[y][x]
|
|
4
4
|
init(screen); return bg_buffer, {vars dict}, "optional command string"
|
|
5
|
-
tick(screen, vars, keys)
|
|
5
|
+
tick(screen, vars, keys): return None
|
|
6
6
|
|
|
7
7
|
"""
|
|
8
8
|
import sys, time, os, random, collections, re, ctypes
|
|
@@ -231,10 +231,8 @@ def handle_input(v, keys, multiline=True, cursor_pos_name="cpos", use_text_from_
|
|
|
231
231
|
|
|
232
232
|
if pressed(keys, 'delete'):
|
|
233
233
|
if cx < len(lines[ly]):
|
|
234
|
-
# Remove character at current cursor position
|
|
235
234
|
lines[ly] = lines[ly][:cx] + lines[ly][cx+1:]
|
|
236
235
|
elif ly < len(lines) - 1:
|
|
237
|
-
# At end of line: pull the line below up to this line
|
|
238
236
|
lines[ly] += lines[ly+1]
|
|
239
237
|
lines.pop(ly + 1)
|
|
240
238
|
|
|
@@ -257,33 +255,6 @@ def handle_input(v, keys, multiline=True, cursor_pos_name="cpos", use_text_from_
|
|
|
257
255
|
if use_text_from_vars: v[text_name] = "\n".join(lines)
|
|
258
256
|
else: return "\n".join(lines)
|
|
259
257
|
|
|
260
|
-
def draw_window(arr, x, y, sx, sy, color_offset=0, char=None):
|
|
261
|
-
if isinstance(char, int):
|
|
262
|
-
for xi in range(x, sx):
|
|
263
|
-
for yi in range(y, sy):
|
|
264
|
-
if inside(arr, (xi, yi)):
|
|
265
|
-
arr[yi][xi] = char
|
|
266
|
-
for i in range(x, x + sx):
|
|
267
|
-
if inside(arr, (i, y)):
|
|
268
|
-
arr[y][i] = 101 + color_offset
|
|
269
|
-
for i in range(y, y + sy):
|
|
270
|
-
if inside(arr, (x, i)):
|
|
271
|
-
arr[i][x] = 100 + color_offset
|
|
272
|
-
for i in range(x, x + sx):
|
|
273
|
-
if inside(arr, (i, y + sy)):
|
|
274
|
-
arr[y + sy][i] = 101 + color_offset
|
|
275
|
-
for i in range(y, y + sy):
|
|
276
|
-
if inside(arr, (x + sx, i)):
|
|
277
|
-
arr[i][x + sx] = 100 + color_offset
|
|
278
|
-
if inside(arr, (x, y)):
|
|
279
|
-
arr[y][x] = 96 + color_offset
|
|
280
|
-
if inside(arr, (x + sx, y)):
|
|
281
|
-
arr[y][x + sx] = 99 + color_offset
|
|
282
|
-
if inside(arr, (x + sx, y + sy)):
|
|
283
|
-
arr[y + sy][x + sx] = 97 + color_offset
|
|
284
|
-
if inside(arr, (x, y + sy)):
|
|
285
|
-
arr[y + sy][x] = 98 + color_offset
|
|
286
|
-
|
|
287
258
|
|
|
288
259
|
# --- sound ---
|
|
289
260
|
|
|
@@ -409,6 +380,7 @@ def bin_to_csv(bin_path):
|
|
|
409
380
|
|
|
410
381
|
# Dim: gets the dimensions of an array
|
|
411
382
|
def dim(arr):
|
|
383
|
+
"""returns the length of an array as (width, height)"""
|
|
412
384
|
try: return len(arr[0]), len(arr)
|
|
413
385
|
except: return (0, 0)
|
|
414
386
|
|
|
@@ -446,7 +418,7 @@ for index, char in enumerate(TILE_SET):
|
|
|
446
418
|
# ANSI Colors (Foreground/background): Defualt 0, Black 1, White 2, Red 3, Green 4, Yellow 5, Blue 6, Magenta 7, Cyan 8
|
|
447
419
|
ANSI_COLORS = ["0","30","37","31","32","33","34","35","36"]
|
|
448
420
|
|
|
449
|
-
def color(tile, fg=2 , bg=1, invert=False):
|
|
421
|
+
def color(tile=0, fg=2 , bg=1, invert=False):
|
|
450
422
|
if isinstance(tile, str):
|
|
451
423
|
temp_tile = []
|
|
452
424
|
for char in list(tile):
|
|
@@ -479,50 +451,73 @@ def plot(screen, char, x, y, color=0):
|
|
|
479
451
|
def gplot(screen, x, y, state, color_idx):
|
|
480
452
|
tx, ty = x // 2, y // 2
|
|
481
453
|
if not inside(screen, (tx, ty)): return
|
|
482
|
-
t_len = len(TILE_SET);current_val = screen[ty][tx]
|
|
483
|
-
|
|
484
|
-
|
|
454
|
+
t_len = len(TILE_SET); current_val = screen[ty][tx]
|
|
455
|
+
char_idx = current_val % t_len; color_bits = current_val // t_len
|
|
456
|
+
if (not (char_idx >= 64 and char_idx <= 78)) and inside(screen, (x, y)):
|
|
457
|
+
tbgc = getbg(screen, (x, y)); screen[y][x] = color(char_idx, color_idx, tbgc)
|
|
458
|
+
curr_fg = (color_bits >> 4) & 0xF; curr_bg = color_bits & 0xF
|
|
485
459
|
raw_matrix = ilow_res.get(char_idx, ((0,0),(0,0)))
|
|
486
460
|
matrix = [list(row) for row in raw_matrix]
|
|
487
461
|
if state:
|
|
488
|
-
if
|
|
489
|
-
curr_fg = color_idx
|
|
490
|
-
elif color_idx == curr_bg and color_idx != curr_fg:
|
|
462
|
+
if color_idx == curr_bg:
|
|
491
463
|
curr_fg, curr_bg = curr_bg, curr_fg
|
|
492
|
-
for
|
|
493
|
-
for
|
|
494
|
-
|
|
464
|
+
for r in range(2):
|
|
465
|
+
for c in range(2):
|
|
466
|
+
matrix[r][c] = 1 - matrix[r][c]
|
|
467
|
+
curr_fg = color_idx
|
|
495
468
|
matrix[y % 2][x % 2] = 1 if state else 0
|
|
496
469
|
lookup_matrix = tuple(tuple(row) for row in matrix)
|
|
497
|
-
new_char_idx = low_res.get(lookup_matrix, 0)
|
|
498
|
-
new_color_bits = (curr_fg << 4) | curr_bg
|
|
470
|
+
new_char_idx = low_res.get(lookup_matrix, 0); new_color_bits = (curr_fg << 4) | curr_bg
|
|
499
471
|
screen[ty][tx] = new_char_idx + (t_len * new_color_bits)
|
|
500
472
|
|
|
501
|
-
def draw_box(arr, start_x, start_y, width, height, fg=
|
|
473
|
+
def draw_box(arr, start_x, start_y, width, height, fg=2, bg=1, invert=False, vertical_border=0, horozontal_border=0):
|
|
502
474
|
"""Draws a box."""
|
|
503
475
|
for y in range(start_y, start_y + height):
|
|
504
476
|
if 0 <= y < len(arr):
|
|
505
|
-
if 0 <= start_x < len(arr[y]): arr[y][start_x] = color(
|
|
506
|
-
if 0 <= start_x + 1 < len(arr[y]): arr[y][start_x + 1] = color(
|
|
507
|
-
if 0 <= start_x + width - 2 < len(arr[y]): arr[y][start_x + width - 2] = color(
|
|
508
|
-
if 0 <= start_x + width - 1 < len(arr[y]): arr[y][start_x + width - 1] = color(
|
|
477
|
+
if 0 <= start_x < len(arr[y]): arr[y][start_x] = color(vertical_border, fg, bg, invert)
|
|
478
|
+
if 0 <= start_x + 1 < len(arr[y]): arr[y][start_x + 1] = color(vertical_border, fg, bg, invert)
|
|
479
|
+
if 0 <= start_x + width - 2 < len(arr[y]): arr[y][start_x + width - 2] = color(vertical_border, fg, bg, invert)
|
|
480
|
+
if 0 <= start_x + width - 1 < len(arr[y]): arr[y][start_x + width - 1] = color(vertical_border, fg, bg, invert)
|
|
509
481
|
for x in range(start_x, start_x + width):
|
|
510
|
-
if 0 <= start_y < len(arr) and 0 <= x < len(arr[0]): arr[start_y][x] = color(
|
|
511
|
-
if 0 <= start_y + height - 1 < len(arr) and 0 <= x < len(arr[0]): arr[start_y + height - 1][x] = color(
|
|
482
|
+
if 0 <= start_y < len(arr) and 0 <= x < len(arr[0]): arr[start_y][x] = color(horozontal_border, fg, bg, invert)
|
|
483
|
+
if 0 <= start_y + height - 1 < len(arr) and 0 <= x < len(arr[0]): arr[start_y + height - 1][x] = color(horozontal_border, fg, bg, invert)
|
|
484
|
+
for y in range(start_y, start_y + height):
|
|
485
|
+
for x in range(start_x, start_x + width):
|
|
486
|
+
if inside(arr, (x, y)):
|
|
487
|
+
arr[y][x] = color(0, fg, bg)
|
|
488
|
+
|
|
489
|
+
|
|
512
490
|
|
|
513
491
|
def draw_tri(arr, sx, sy, ph, color_ = 0):
|
|
514
492
|
for o in range(ph):
|
|
515
493
|
if inside(arr, (sx, sy)): arr[sy][sx] = 3 + color_
|
|
516
|
-
sx += 1
|
|
517
|
-
sy -= 1
|
|
494
|
+
sx += 1; sy -= 1
|
|
518
495
|
|
|
519
496
|
if inside(arr, (sx, sy)): arr[sy][sx] = 3 + color_
|
|
520
497
|
sx += 1
|
|
521
498
|
for o in range(ph):
|
|
522
499
|
if inside(arr, (sx, sy)): arr[sy][sx] = 4 + color_
|
|
523
|
-
sx += 1
|
|
524
|
-
sy += 1
|
|
500
|
+
sx += 1; sy += 1
|
|
525
501
|
if inside(arr, (sx, sy)): arr[sy][sx] = 4 + color_
|
|
502
|
+
|
|
503
|
+
def draw_window(arr, x, y, sx, sy, color_offset=0, char=None):
|
|
504
|
+
if isinstance(char, int):
|
|
505
|
+
for xi in range(x, x +sx):
|
|
506
|
+
for yi in range(y, y + sy):
|
|
507
|
+
if inside(arr, (xi, yi)): arr[yi][xi] = char
|
|
508
|
+
for i in range(x, x + sx):
|
|
509
|
+
if inside(arr, (i, y)): arr[y][i] = 101 + color_offset
|
|
510
|
+
for i in range(y, y + sy):
|
|
511
|
+
if inside(arr, (x, i)): arr[i][x] = 100 + color_offset
|
|
512
|
+
for i in range(x, x + sx):
|
|
513
|
+
if inside(arr, (i, y + sy)): arr[y + sy][i] = 101 + color_offset
|
|
514
|
+
for i in range(y, y + sy):
|
|
515
|
+
if inside(arr, (x + sx, i)): arr[i][x + sx] = 100 + color_offset
|
|
516
|
+
if inside(arr, (x, y)): arr[y][x] = 96 + color_offset
|
|
517
|
+
if inside(arr, (x + sx, y)): arr[y][x + sx] = 99 + color_offset
|
|
518
|
+
if inside(arr, (x + sx, y + sy)): arr[y + sy][x + sx] = 97 + color_offset
|
|
519
|
+
if inside(arr, (x, y + sy)): arr[y + sy][x] = 98 + color_offset
|
|
520
|
+
|
|
526
521
|
def blit(arr0, arr1, sx, sy):
|
|
527
522
|
w, h = dim(arr1)
|
|
528
523
|
for y in range(h):
|
|
@@ -531,6 +526,32 @@ def blit(arr0, arr1, sx, sy):
|
|
|
531
526
|
t = arr1[y][x]
|
|
532
527
|
if t >= 0: arr0[y + sy][x + sx] = t
|
|
533
528
|
|
|
529
|
+
def draw_text_box(arr, x, y, text, text_color, box_color=0):
|
|
530
|
+
text_array = str_to_arr(text, text_color)
|
|
531
|
+
w, h = dim(text_array)
|
|
532
|
+
draw_window(arr, x, y, w + 1, h + 1, box_color)
|
|
533
|
+
blit(arr, text_array, x + 1, y + 1)
|
|
534
|
+
|
|
535
|
+
def draw_line(arr, x0, y0, x1, y1, color_offset):
|
|
536
|
+
dx = abs(x1 - x0)
|
|
537
|
+
dy = -abs(y1 - y0)
|
|
538
|
+
sx = 1 if x0 < x1 else -1
|
|
539
|
+
sy = 1 if y0 < y1 else -1
|
|
540
|
+
err = dx + dy
|
|
541
|
+
|
|
542
|
+
while True:
|
|
543
|
+
gplot(arr, x0, y0, 1, color_offset)
|
|
544
|
+
if x0 == x1 and y0 == y1:
|
|
545
|
+
break
|
|
546
|
+
|
|
547
|
+
e2 = 2 * err
|
|
548
|
+
if e2 >= dy:
|
|
549
|
+
err += dy
|
|
550
|
+
x0 += sx
|
|
551
|
+
if e2 <= dx:
|
|
552
|
+
err += dx
|
|
553
|
+
y0 += sy
|
|
554
|
+
|
|
534
555
|
def getfg(arr, xy):
|
|
535
556
|
"""Returns the foreground color index of a tile at (x, y)."""
|
|
536
557
|
x, y = xy
|
|
@@ -545,7 +566,7 @@ def getbg(arr, xy):
|
|
|
545
566
|
x, y = xy
|
|
546
567
|
if not inside(arr, xy): return 1
|
|
547
568
|
val = arr[y][x];t_len = len(TILE_SET)
|
|
548
|
-
if val < t_len:return
|
|
569
|
+
if val < t_len:return 0
|
|
549
570
|
color_bits = val // t_len;bg_idx = color_bits & 0xF
|
|
550
571
|
return bg_idx
|
|
551
572
|
|
|
File without changes
|
|
File without changes
|