From a5b5842d94aa7a97ac6e4d17b057b44e07acf671 Mon Sep 17 00:00:00 2001 From: Oskar Date: Tue, 16 Mar 2021 01:01:32 +0100 Subject: [PATCH] Initial commit, C WASM version working --- .gitignore | 2 + html_template/shell_minimal.html | 38 +++++++ klock4.c | 181 +++++++++++++++++++++++++++++++ klock4.py | 136 +++++++++++++++++++++++ klock4_wasm.c | 165 ++++++++++++++++++++++++++++ 5 files changed, 522 insertions(+) create mode 100644 .gitignore create mode 100644 html_template/shell_minimal.html create mode 100644 klock4.c create mode 100644 klock4.py create mode 100644 klock4_wasm.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..33531fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +klock4 +html_out/ diff --git a/html_template/shell_minimal.html b/html_template/shell_minimal.html new file mode 100644 index 0000000..e1c9f0e --- /dev/null +++ b/html_template/shell_minimal.html @@ -0,0 +1,38 @@ + + + + + + klock4 WASM version + + + + + + {{{ SCRIPT }}} + + diff --git a/klock4.c b/klock4.c new file mode 100644 index 0000000..4ef82a5 --- /dev/null +++ b/klock4.c @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include +#include + +const unsigned char TEXT[] = "\ +ESXISTXFÜNF\ +ZEHNZWANZIG\ +DREIVIERTEL\ +VORGESTNACH\ +HALBXELFÜNF\ +EINSXLEZWEI\ +DREIXTXVIER\ +SECHSXXACHT\ +SIEBENZWÖLF\ +ZEHNEUNXUHR"; + +typedef unsigned long long uint64; +typedef unsigned __int128 uint128; + +#define ES_IST ((uint128) 0b11 << 0 | 0b111 << 3 ) +#define FÜNF_PRE ((uint128) 0b1111 << 7 ) +#define FÜNFZEHN ((uint128) 0b11111111 << 7 ) +#define ZEHN_PRE ((uint128) 0b1111 << 11 ) +#define ZWANZIG ((uint128) 0b1111111 << 15 ) +#define DREIVIERTEL ((uint128) 0b11111111111 << 22 ) +#define VIERTEL ((uint128) 0b1111111 << 26 ) +#define VOR ((uint128) 0b111 << 33 ) +#define NACH ((uint128) 0b1111 << 40 ) +#define HALB ((uint128) 0b1111 << 44 ) +#define ELF ((uint128) 0b111 << 49 ) +#define FÜNF_UHR ((uint128) 0b1111 << 51 ) +#define EINS ((uint128) 0b1111 << 55 ) +#define ZWEI ((uint128) 0b1111 << 62 ) +#define DREI ((uint128) 0b1111 << 66 ) +#define VIER ((uint128) 0b1111 << 73 ) +#define SECHS ((uint128) 0b11111 << 77 ) +#define ACHT ((uint128) 0b1111 << 84 ) +#define SIEBEN ((uint128) 0b111111 << 88 ) +#define ZWÖLF ((uint128) 0b11111 << 94 ) +#define ZEHN_UHR ((uint128) 0b1111 << 99 ) +#define NEUN ((uint128) 0b1111 << 102) +#define UHR ((uint128) 0b111 << 107) +#define STELLE ((uint128) 0b11 << 38 | 0b11 << 49 | 0b11 << 60) +#define GESTELLT ((uint128) 0b1111 << 36 | 0b11 << 49 | 0b1 << 60 | 0b1 << 71) + +uint128 HOURS[] = { + ZWÖLF, EINS, ZWEI, DREI, VIER, FÜNF_UHR, + SECHS, SIEBEN, ACHT, NEUN, ZEHN_UHR, ELF +}; +uint128 PARTS[] = { + UHR, FÜNF_PRE, ZEHN_PRE, VIERTEL, + ZWANZIG, FÜNF_PRE | HALB, HALB +}; + +uint128 active = 0; + +void print128(uint128 n) { + printf("0x%016llx%016llx\n", + (uint64) (n >> 64), (uint64) n & 0xFFFFFFFFFFFFFFFF); +} + +void set(uint128 seg) { + active |= seg; +} + +void reset(void) { + active = 0; + set(ES_IST); +} + +void settime(time_t ts) { + + unsigned int second = ts % 60; + + unsigned int minute = (ts / 60) % 60; + float fminute = (float) minute + (float) second / 60; + minute = 5 * (unsigned int) roundf(fminute / 5); + + unsigned int hour = (ts / (60*60) + 1) % 12; + + //printf("%02d:%02d\n", hour, minute); + + int before = 0; + + if (minute >= 25) { + hour = (hour+1) % 12; + before = 1; + minute = 60-minute; + if (minute == 35) { + minute = 25; + before = 0; + } + } + + //printf("%02d %s %02d\n", minute, before ? "vor" : "nach", hour); + + if (minute == 25) + before = !before; + + reset(); + + if (minute != 0 && minute != 30) + set(before ? (uint128) VOR : (uint128) NACH); + + set((uint128) HOURS[hour]); + set((uint128) PARTS[minute/5]); + +} + +void dump() { + + const int ROWS = 10; + const int COLS = 11; + + const char WHITE[] = "\033[1;37m"; + const char GRAY[] = "\033[0;30m"; + + uint128 buffer = active; + + int ci = 0; + + for (int bi = 0; bi < sizeof(TEXT); bi++) { + + // utf8 tail byte + if (TEXT[bi] >> 6 == 0b10) { + putc(TEXT[bi], stdout); + continue; + } + + int col = ci % COLS; + int row = ci / COLS; + if (col == 0) + printf("\n "); + + const char* color = (buffer & (uint128) 1) ? WHITE : GRAY; + + printf(" %s%c", color, TEXT[bi]); + + buffer = buffer >> 1; + ci++; + + } + + #define RESET_COLORS "\033[0m" + printf(RESET_COLORS "\n"); + +} + +int main(int argc, char* argv[]) { + + int demo = 0; + int live = 0; + if (argc > 1) { + if (strncmp(argv[1], "demo", 5) == 0) + demo = 1; + else if (strncmp(argv[1], "live", 5) == 0) + live = 1; + else + active = atol(argv[1]); + } + + time_t ts = time(NULL); + + while (1) { + printf("\033c"); + if (demo) printf("DEMO Mode!\n"); + ts = demo ? ts + 5 * 60 : time(NULL); + settime(ts); + dump(); + + if (!live) return 0; + + sleep(5); + }; + + return 0; + +} diff --git a/klock4.py b/klock4.py new file mode 100644 index 0000000..7c609d1 --- /dev/null +++ b/klock4.py @@ -0,0 +1,136 @@ +TEXT = """\ +ESXISTXFÜNF\ +ZEHNZWANZIG\ +DREIVIERTEL\ +VORGESTNACH\ +HALBXELFÜNF\ +EINSXLEZWEI\ +DREIXTXVIER\ +SECHSXXACHT\ +SIEBENZWÖLF\ +ZEHNEUNXUHR\ +""" + +SEGMENTS = { + 'ES IST': [(0, 2), (3, 3)], + 'FÜNF_PRE': [(7, 4)], + 'FÜNFZEHN': [(7, 8)], + 'ZEHN_PRE': [(11, 4)], + 'ZWANZIG': [(15, 7)], + 'DREIVIERTEL': [(22, 11)], + 'VIERTEL': [(26, 7)], + 'VOR': [(33, 3)], + 'NACH': [(40, 4)], + 'HALB': [(44, 4)], + 'ELF': [(49, 3)], + 'FÜNF_UHR': [(51, 4)], + 'EINS': [(55, 4)], + 'ZWEI': [(62, 4)], + 'DREI': [(66, 4)], + 'VIER': [(73, 4)], + 'SECHS': [(77, 5)], + 'ACHT': [(84, 4)], + 'SIEBEN': [(88, 6)], + 'ZWÖLF': [(94, 5)], + 'ZEHN_UHR': [(99, 4)], + 'NEUN': [(102, 4)], + 'UHR': [(107, 3)], + 'STELLE': [(38, 2), (49, 2), (60, 2)], + 'GESTELLT': [(36, 4), (49, 2), (60, 1), (71, 1)], +} + +HOURS = ['ZWÖLF', 'EINS', 'ZWEI', 'DREI', 'VIER', 'FÜNF_UHR', 'SECHS', 'SIEBEN', 'ACHT', 'NEUN', 'ZEHN_UHR', 'ELF' ] +PARTS = [['UHR'], ['FÜNF_PRE'], ['ZEHN_PRE'], ['VIERTEL'], ['ZWANZIG'], ['FÜNF_PRE', 'HALB'], ['HALB']] + +active = [False] * len(TEXT) + +def set(segment, val=True): + for word in segment: + idx, len = word + active[idx:idx+len] = [val for _ in range(len)] + +def reset(): + global active + set([(0, len(TEXT))], False) + set(SEGMENTS['ES IST']) + +def settime(time): + reset() + + hour = time.hour % 12 + minute = 5 * round((time.minute + time.second/60) / 5) + before = False + + if minute >= 25: + hour = (hour + 1) % 12 + before = True + minute = (60-minute) + if minute == 35: + minute = 25 + before = False + + print(minute, 'vor' if before else 'nach', hour) + + # 25 before 6 -> 5 after half 6 + # 25 after 6 -> 5 before half 6 + if minute == 25: + before = not before + + if not minute in [0, 30]: + set(SEGMENTS['VOR' if before else 'NACH']) + + set(SEGMENTS[HOURS[hour]]) + + for part in PARTS[minute//5]: + set(SEGMENTS[part]) + + +def dump(): + COLS = 11 + RESET = '\033[0m' + WHITE = '\033[1;37m' + GRAY = '\033[0;30m' + for i, char in enumerate(TEXT): + col = i % COLS + row = i // COLS + if (col == 0): + print('\n ', end='') + color = (WHITE if active[i] else GRAY) if i==0 or active[i] != active[i-1] else '' + print(f' {color}{char} ', end='') + print(RESET+'\n') + + +def live(): + import time + from datetime import datetime + while True: + print('\033c', end='') + + now = datetime.now() + print(now) + + settime(now) + dump() + + time.sleep(1) + +def demo(): + import time + import datetime + t = datetime.datetime.now() + while True: + print('\033c', end='') + print(t) + + settime(t) + dump() + + time.sleep(1) + t += datetime.timedelta(minutes=1) + +if __name__ == '__main__': + import sys + if len(sys.argv) > 1 and sys.argv[1] == 'demo': + demo() + else: + live() diff --git a/klock4_wasm.c b/klock4_wasm.c new file mode 100644 index 0000000..f4e4001 --- /dev/null +++ b/klock4_wasm.c @@ -0,0 +1,165 @@ +#include +#include +#include +#include +#include +#include +#include + +const unsigned char TEXT[] = "\ +ESXISTXFÜNF\ +ZEHNZWANZIG\ +DREIVIERTEL\ +VORGESTNACH\ +HALBXELFÜNF\ +EINSXLEZWEI\ +DREIXTXVIER\ +SECHSXXACHT\ +SIEBENZWÖLF\ +ZEHNEUNXUHR"; + +typedef unsigned long long uint64; +typedef unsigned __int128 uint128; + +#define ES_IST ((uint128) 0b11 << 0 | 0b111 << 3 ) +#define FÜNF_PRE ((uint128) 0b1111 << 7 ) +#define FÜNFZEHN ((uint128) 0b11111111 << 7 ) +#define ZEHN_PRE ((uint128) 0b1111 << 11 ) +#define ZWANZIG ((uint128) 0b1111111 << 15 ) +#define DREIVIERTEL ((uint128) 0b11111111111 << 22 ) +#define VIERTEL ((uint128) 0b1111111 << 26 ) +#define VOR ((uint128) 0b111 << 33 ) +#define NACH ((uint128) 0b1111 << 40 ) +#define HALB ((uint128) 0b1111 << 44 ) +#define ELF ((uint128) 0b111 << 49 ) +#define FÜNF_UHR ((uint128) 0b1111 << 51 ) +#define EINS ((uint128) 0b1111 << 55 ) +#define ZWEI ((uint128) 0b1111 << 62 ) +#define DREI ((uint128) 0b1111 << 66 ) +#define VIER ((uint128) 0b1111 << 73 ) +#define SECHS ((uint128) 0b11111 << 77 ) +#define ACHT ((uint128) 0b1111 << 84 ) +#define SIEBEN ((uint128) 0b111111 << 88 ) +#define ZWÖLF ((uint128) 0b11111 << 94 ) +#define ZEHN_UHR ((uint128) 0b1111 << 99 ) +#define NEUN ((uint128) 0b1111 << 102) +#define UHR ((uint128) 0b111 << 107) +#define STELLE ((uint128) 0b11 << 38 | 0b11 << 49 | 0b11 << 60) +#define GESTELLT ((uint128) 0b1111 << 36 | 0b11 << 49 | 0b1 << 60 | 0b1 << 71) + +uint128 HOURS[] = { + ZWÖLF, EINS, ZWEI, DREI, VIER, FÜNF_UHR, + SECHS, SIEBEN, ACHT, NEUN, ZEHN_UHR, ELF +}; +uint128 PARTS[] = { + UHR, FÜNF_PRE, ZEHN_PRE, VIERTEL, + ZWANZIG, FÜNF_PRE | HALB, HALB +}; + +uint128 active = 0; + +void print128(uint128 n) { + printf("0x%016llx%016llx\n", + (uint64) (n >> 64), (uint64) n & 0xFFFFFFFFFFFFFFFF); +} + +void set(uint128 seg) { + active |= seg; +} + +void reset(void) { + active = 0; + set(ES_IST); +} + +void settime(time_t ts) { + + unsigned int second = ts % 60; + + unsigned int minute = (ts / 60) % 60; + float fminute = (float) minute + (float) second / 60; + minute = 5 * (unsigned int) roundf(fminute / 5); + + unsigned int hour = (ts / (60*60) + 1) % 12; + + //printf("%02d:%02d\n", hour, minute); + + int before = 0; + + if (minute >= 25) { + hour = (hour+1) % 12; + before = 1; + minute = 60-minute; + if (minute == 35) { + minute = 25; + before = 0; + } + } + + //printf("%02d %s %02d\n", minute, before ? "vor" : "nach", hour); + + if (minute == 25) + before = !before; + + reset(); + + if (minute != 0 && minute != 30) + set(before ? (uint128) VOR : (uint128) NACH); + + set((uint128) HOURS[hour]); + set((uint128) PARTS[minute/5]); + +} + +void dump() { + + const int ROWS = 10; + const int COLS = 11; + + const char WHITE_PRE[] = ""; + const char WHITE_PST[] = ""; + const char GRAY_PRE[] = ""; + const char GRAY_PST[] = ""; + + uint128 buffer = active; + + int ci = 0; + + for (int bi = 0; bi < sizeof(TEXT); bi++) { + + int col = ci % COLS; + int row = ci / COLS; + if (col == 0) + printf("\n "); + + const char* color_pre = (buffer & (uint128) 1) ? WHITE_PRE : GRAY_PRE; + const char* color_pst = (buffer & (uint128) 1) ? WHITE_PST : GRAY_PST; + + printf(" %s%c", color_pre, TEXT[bi]); + if (TEXT[bi] >> 5 == 0b110) + putc(TEXT[++bi], stdout); + printf("%s", color_pst); + + buffer = buffer >> 1; + ci++; + + } + +} + +void render(void) { + + printf("clear\n"); + time_t ts = time(NULL); + settime(ts); + dump(); + +} + +int main(int argc, char* argv[]) { + + emscripten_set_main_loop(render, 1, 1); + + return 0; + +}