Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 9 additions & 53 deletions c_test_files/tetris.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,40 +51,13 @@ int readch() {

// Tetromino definitions (7 pieces, each as 4x4 block string)
const char *tetromino[7] = {
"...."
"XXXX"
"...."
"....", // I

".X.."
".X.."
".XX."
"....", // J

"..X."
"..X."
".XX."
"....", // L

".XX."
".XX."
"...."
"....", // O

".XX."
"XX.."
"...."
"....", // S

".X.."
".XXX"
"...."
"....", // T

"XX.."
".XX."
"...."
"...." // Z
"....XXXX........", // I
".X...X...XX.....", // J
"..X...X..XX.....", // L
".XX..XX.........", // O
".XX.XX..........", // S
".X...XXX........", // T
"XX...XX........." // Z
};

// ANSI color codes for each piece
Expand Down Expand Up @@ -153,8 +126,7 @@ void draw_screen(int currentPiece, int currentRotation, int currentX,
// Draw header with box drawing characters
printf("\x1b[0m");
printf("╔════════════════════════════╗ ╔═══════════════╗\n");
printf("║ \x1b[1;97mT E T R I S\x1b[0m ║ ║ \x1b[1mNEXT "
"PIECE\x1b[0m ║\n");
printf("║ \x1b[1;97mT E T R I S\x1b[0m ║ ║ \x1b[1mNEXT PIECE\x1b[0m ║\n");
printf("╠════════════════════════════╣ ║ ║\n");

// Draw visible area with next piece preview
Expand Down Expand Up @@ -295,23 +267,7 @@ int main() {
gameOver = 1;
break;
}
// Handle escape sequences for arrow keys
if (c == 27) { // ESC
if (kbhit()) {
int c2 = readch();
if (c2 == '[' && kbhit()) {
int c3 = readch();
if (c3 == 'A')
key = 'U'; // Up arrow
if (c3 == 'B')
key = 'D'; // Down arrow
if (c3 == 'C')
key = 'R'; // Right arrow
if (c3 == 'D')
key = 'L'; // Left arrow
}
}
}

// Regular keys
if (c == 'a' || c == 'A')
key = 'L';
Expand Down
16 changes: 8 additions & 8 deletions std/termfx.lx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ pub const MAGENTA: *char = "\x1b[35m";
pub const CYAN: *char = "\x1b[36m";
pub const WHITE: *char = "\x1b[37m";

pub const BRIGHT_BLACK: *char = "\x1b[90m";
pub const BRIGHT_RED: *char = "\x1b[91m";
pub const BRIGHT_GREEN: *char = "\x1b[92m";
pub const BRIGHT_YELLOW: *char = "\x1b[93m";
pub const BRIGHT_BLUE: *char = "\x1b[94m";
pub const BRIGHT_MAGENTA: *char = "\x1b[95m";
pub const BRIGHT_CYAN: *char = "\x1b[96m";
pub const BRIGHT_WHITE: *char = "\x1b[97m";
pub const BRIGHT_BLACK: *char = "\x1b[1;90m";
pub const BRIGHT_RED: *char = "\x1b[1;91m";
pub const BRIGHT_GREEN: *char = "\x1b[1;92m";
pub const BRIGHT_YELLOW: *char = "\x1b[1;93m";
pub const BRIGHT_BLUE: *char = "\x1b[1;94m";
pub const BRIGHT_MAGENTA: *char = "\x1b[1;95m";
pub const BRIGHT_CYAN: *char = "\x1b[1;96m";
pub const BRIGHT_WHITE: *char = "\x1b[1;97m";

pub const BG_BLACK: *char = "\x1b[40m";
pub const BG_RED: *char = "\x1b[41m";
Expand Down
102 changes: 86 additions & 16 deletions std/terminal.lx
Original file line number Diff line number Diff line change
@@ -1,18 +1,69 @@
@module "terminal"

// @use "string" as string
@use "string" as string
@use "termfx" as fx

// Get a single character without waiting for Enter
pub const getch -> fn () char {
// Disable canonical mode and echo
system("stty -icanon -echo");
// Global flag to track raw mode state
let raw_mode_enabled: int = 0;

// Enable raw mode - BLOCKING (waits for input)
pub const enable_raw_mode -> fn () void {
if (raw_mode_enabled == 1) {
return; // Already enabled
}

// Read single character
let c: char = input<char>("");
// Save terminal state and set up restoration on exit
system("stty -g > /tmp/luma_termios_backup");

// Restore terminal settings
system("stty icanon echo");
// Configure raw mode:
// -icanon: disable line buffering (read char by char)
// -echo: don't echo input
// -isig: disable interrupt signals (Ctrl+C, Ctrl+Z)
// -ixon: disable software flow control (Ctrl+S, Ctrl+Q)
// -icrnl: don't translate CR to NL
// min 1 time 0: blocking read (wait for at least 1 character)
system("stty -icanon -echo -isig -ixon -icrnl min 0 time 0");

// Hide cursor
output(fx::CURSOR_HIDE);

raw_mode_enabled = 1;
}

// Disable raw mode - restore terminal to normal
pub const disable_raw_mode -> fn () void {
if (raw_mode_enabled == 0) {
return; // Already disabled
}

// Restore original terminal settings
system("stty $(cat /tmp/luma_termios_backup)");
system("rm /tmp/luma_termios_backup");

// Show cursor
output(fx::CURSOR_SHOW);

// Reset colors
output(fx::RESET);

raw_mode_enabled = 0;
}

// Blocking input in raw mode - waits for a key but no Enter needed
// Use with enable_raw_mode() (not enable_raw_mode_nonblock)
pub const getch_raw -> fn () char {
if (raw_mode_enabled == 0) {
enable_raw_mode();
}

let c: char = input<char>("");
return c;
}

// Get a single character without waiting for Enter
pub const getch -> fn () char {
// Just try to read input; don't touch stty here
let c: char = input<char>("");
return c;
}

Expand All @@ -35,15 +86,16 @@ pub const getche -> fn () char {
}

// Check if a key is pressed (non-blocking)
// WARNING: This consumes the character! Don't use in raw mode.
pub const kbhit -> fn () int {
system("stty -icanon -echo min 0 time 0");
let c: char = input<char>("");
system("stty icanon echo");

if (c == cast<char>(0)) {
return 0;
// Non-blocking test only
let result: int = system("read -t 0 -n 1 key < /dev/tty");
if (result == cast<int>(0)) {
// put the char back for getch()
system("read -t 0 -n 1 key < /dev/tty && printf '%s' $key > /tmp/luma_kbhit_buf");
return 1;
}
return 1;
return 0;
}

// Wait for any key press
Expand Down Expand Up @@ -110,3 +162,21 @@ pub const getpass -> fn (prompt: *char) *char {

return password;
}

// Sleep for milliseconds (more precise than system("sleep"))
pub const sleep_ms -> fn (ms: int) void {
let cmd: *char = cast<*char>(alloc(64 * sizeof<char>));
defer { free(cmd); }

// Multiply milliseconds by 1000 for microseconds
string::cat(cmd, "usleep ", string::from_int(ms * 1000));

system(cmd);
}

// Get terminal size
pub const get_terminal_size -> fn () void {
system("tput cols > /tmp/luma_cols");
system("tput lines > /tmp/luma_lines");
// Read back from files...
}
Loading