-
-
Save Experiment5X/6005507 to your computer and use it in GitHub Desktop.
Inspired by the show 24, I decided to try and re-create the famous clock in a linux terminal. To compile the app, you'll need to have ncurses installed, to do that use the following command in a debian environment. sudo apt-get install ncurses-dev Once that is installed, compilation is pretty straight-forward, paste the following into your termi…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <curses.h> | |
#include <time.h> | |
#define HORIZONTAL_BAR_LEN 3 | |
#define VERTICAL_BAR_LEN 2 | |
#define DIGIT_WIDTH ((HORIZONTAL_BAR_LEN * 2) + 5) | |
#define DIGIT_HEIGHT ((VERTICAL_BAR_LEN * 2) + 3) | |
void drawHorizontalBar (int x, int y, int len); | |
void drawVerticalBar (int x, int y, int len); | |
void drawTopLeft (int x, int y); | |
void drawTopRight (int x, int y); | |
void drawRightTop (int x, int y); | |
void drawRightBottom (int x, int y); | |
void drawMiddleLeft (int x, int y); | |
void drawMiddleRight (int x, int y); | |
void drawLeftTop (int x, int y); | |
void drawLeftBottom (int x, int y); | |
void drawBottomLeft (int x, int y); | |
void drawBottomRight (int x, int y); | |
void draw0 (int x, int y); | |
void draw1 (int x, int y); | |
void draw2 (int x, int y); | |
void draw3 (int x, int y); | |
void draw4 (int x, int y); | |
void draw5 (int x, int y); | |
void draw6 (int x, int y); | |
void draw7 (int x, int y); | |
void draw8 (int x, int y); | |
void draw9 (int x, int y); | |
void drawDigit (unsigned char digit, int x, int y); | |
void drawColon (int x, int y); | |
int main() | |
{ | |
initscr(); | |
noecho(); | |
curs_set(0); | |
// get the dimensions of the screen | |
int maxX, maxY; | |
getmaxyx(stdscr, maxY, maxX); | |
// make sure there's enough room for the clock | |
if (12 + 6 * DIGIT_WIDTH > maxX + 1 || DIGIT_HEIGHT > maxY + 1) | |
{ | |
move(0, 0); | |
printw("This terminal is too small to display the clock, make it larger and try again."); | |
refresh(); | |
getch(); | |
endwin(); | |
return 0; | |
} | |
// calculate the coordinates to put the digits on the screen | |
int yPos = (maxY / 2) - (2 * VERTICAL_BAR_LEN); | |
// stores the time digits, so 12:48:26 would be { 1, 2, 4, 8, 2, 6 } | |
unsigned char timeNums[6] = { 0 }; | |
unsigned char prevSec = 0xFF; | |
// forever, the user can stop it with an interrupt | |
for (;;) | |
{ | |
// get the current system time | |
time_t rawCurTime = time(NULL); | |
struct tm *curTime = localtime(&rawCurTime); | |
// calculate all of the digits that we want to display on the screen | |
timeNums[0] = curTime->tm_hour / 10; | |
timeNums[1] = curTime->tm_hour % 10; | |
timeNums[2] = curTime->tm_min / 10; | |
timeNums[3] = curTime->tm_min % 10; | |
timeNums[4] = curTime->tm_sec / 10; | |
timeNums[5] = curTime->tm_sec % 10; | |
// if the time didn't change, then don't redraw | |
if (prevSec == timeNums[5]) | |
continue; | |
// clear all of the current numbers from the screen | |
clear(); | |
// draw all of the time digits onto the screen | |
drawDigit(timeNums[0], 4, yPos); | |
drawDigit(timeNums[1], 4 + DIGIT_WIDTH, yPos); | |
drawColon(4 + 2 * DIGIT_WIDTH + 1, yPos); | |
drawDigit(timeNums[2], 4 + 2 * DIGIT_WIDTH + 4, yPos); | |
drawDigit(timeNums[3], 4 + 3 * DIGIT_WIDTH + 4, yPos); | |
drawColon(4 + 4 * DIGIT_WIDTH + 5, yPos); | |
drawDigit(timeNums[4], 4 + 4 * DIGIT_WIDTH + 8, yPos); | |
drawDigit(timeNums[5], 4 + 5 * DIGIT_WIDTH + 8, yPos); | |
// update the prev time so that it won't redraw every iteration | |
prevSec = timeNums[5]; | |
refresh(); | |
} | |
refresh(); | |
getch(); | |
endwin(); | |
return 0; | |
} | |
void drawVerticalBar(int x, int y, int len) | |
{ | |
for (int i = 0; i < len; i++) | |
{ | |
move(y++, x); | |
addch(' '|A_REVERSE); | |
} | |
} | |
void drawHorizontalBar(int x, int y, int len) | |
{ | |
move(y, x); | |
for (int i = 0; i < len; i++) | |
addch(' '|A_REVERSE); | |
} | |
inline void drawTopLeft(int x, int y) | |
{ | |
drawHorizontalBar(x + 1, y, HORIZONTAL_BAR_LEN); | |
} | |
inline void drawTopRight(int x, int y) | |
{ | |
drawHorizontalBar(x + HORIZONTAL_BAR_LEN + 2, y, HORIZONTAL_BAR_LEN); | |
} | |
inline void drawRightTop(int x, int y) | |
{ | |
drawVerticalBar(x + 2 * HORIZONTAL_BAR_LEN + 2, y + 1, VERTICAL_BAR_LEN); | |
} | |
inline void drawRightBottom(int x, int y) | |
{ | |
drawVerticalBar(x + 2 * HORIZONTAL_BAR_LEN + 2, y + VERTICAL_BAR_LEN + 2, VERTICAL_BAR_LEN); | |
} | |
inline void drawMiddleLeft(int x, int y) | |
{ | |
drawHorizontalBar(x + 1, y + VERTICAL_BAR_LEN + 1, HORIZONTAL_BAR_LEN); | |
} | |
inline void drawMiddleRight(int x, int y) | |
{ | |
drawHorizontalBar(x + HORIZONTAL_BAR_LEN + 2, y + VERTICAL_BAR_LEN + 1, HORIZONTAL_BAR_LEN); | |
} | |
inline void drawLeftTop(int x, int y) | |
{ | |
drawVerticalBar(x, y + 1, VERTICAL_BAR_LEN); | |
} | |
inline void drawLeftBottom(int x, int y) | |
{ | |
drawVerticalBar(x, y + VERTICAL_BAR_LEN + 2, VERTICAL_BAR_LEN); | |
} | |
inline void drawBottomLeft(int x, int y) | |
{ | |
drawHorizontalBar(x + 1, y + 2 * VERTICAL_BAR_LEN + 2, HORIZONTAL_BAR_LEN); | |
} | |
inline void drawBottomRight(int x, int y) | |
{ | |
drawHorizontalBar(x + HORIZONTAL_BAR_LEN + 2, y + 2 * VERTICAL_BAR_LEN + 2, HORIZONTAL_BAR_LEN); | |
} | |
void draw0(int x, int y) | |
{ | |
drawTopLeft(x, y); | |
drawTopRight(x, y); | |
drawRightTop(x, y); | |
drawRightBottom(x, y); | |
drawLeftTop(x, y); | |
drawLeftBottom(x, y); | |
drawBottomLeft(x, y); | |
drawBottomRight(x, y); | |
} | |
void draw1(int x, int y) | |
{ | |
// so it extends the full length | |
drawVerticalBar(x + 2 * HORIZONTAL_BAR_LEN + 2, y, 1); | |
drawVerticalBar(x + 2 * HORIZONTAL_BAR_LEN + 2, y + 2 * VERTICAL_BAR_LEN + 2, 1); | |
drawRightTop(x, y); | |
drawRightBottom(x, y); | |
} | |
void draw2(int x, int y) | |
{ | |
drawTopLeft(x, y); | |
drawTopRight(x, y); | |
drawRightTop(x, y); | |
drawMiddleLeft(x, y); | |
drawMiddleRight(x, y); | |
drawLeftBottom(x, y); | |
drawBottomLeft(x, y); | |
drawBottomRight(x, y); | |
} | |
void draw3(int x, int y) | |
{ | |
drawTopLeft(x, y); | |
drawTopRight(x, y); | |
drawRightTop(x, y); | |
drawRightBottom(x, y); | |
drawMiddleLeft(x, y); | |
drawMiddleRight(x, y); | |
drawBottomLeft(x, y); | |
drawBottomRight(x, y); | |
} | |
void draw4(int x, int y) | |
{ | |
// so it extends the full length | |
drawVerticalBar(x, y, 1); | |
drawVerticalBar(x + 2 * HORIZONTAL_BAR_LEN + 2, y, 1); | |
drawVerticalBar(x + 2 * HORIZONTAL_BAR_LEN + 2, y + 2 * VERTICAL_BAR_LEN + 2, 1); | |
drawRightTop(x, y); | |
drawRightBottom(x, y); | |
drawMiddleLeft(x, y); | |
drawMiddleRight(x, y); | |
drawLeftTop(x, y); | |
} | |
void draw5(int x, int y) | |
{ | |
drawTopLeft(x, y); | |
drawTopRight(x, y); | |
drawRightBottom(x, y); | |
drawMiddleLeft(x, y); | |
drawMiddleRight(x, y); | |
drawLeftTop(x, y); | |
drawBottomLeft(x, y); | |
drawBottomRight(x, y); | |
} | |
void draw6(int x, int y) | |
{ | |
drawTopLeft(x, y); | |
drawTopRight(x, y); | |
drawRightBottom(x, y); | |
drawMiddleLeft(x, y); | |
drawMiddleRight(x, y); | |
drawLeftTop(x, y); | |
drawLeftBottom(x, y); | |
drawBottomLeft(x, y); | |
drawBottomRight(x, y); | |
} | |
void draw7(int x, int y) | |
{ | |
// so it extends the full length | |
drawVerticalBar(x + 2 * HORIZONTAL_BAR_LEN + 2, y + 2 * VERTICAL_BAR_LEN + 2, 1); | |
drawTopLeft(x, y); | |
drawTopRight(x, y); | |
drawRightTop(x, y); | |
drawRightBottom(x, y); | |
} | |
void draw8(int x, int y) | |
{ | |
drawTopLeft(x, y); | |
drawTopRight(x, y); | |
drawRightTop(x, y); | |
drawRightBottom(x, y); | |
drawMiddleLeft(x, y); | |
drawMiddleRight(x, y); | |
drawLeftTop(x, y); | |
drawLeftBottom(x, y); | |
drawBottomLeft(x, y); | |
drawBottomRight(x, y); | |
} | |
void draw9(int x, int y) | |
{ | |
drawTopLeft(x, y); | |
drawTopRight(x, y); | |
drawRightTop(x, y); | |
drawRightBottom(x, y); | |
drawMiddleLeft(x, y); | |
drawMiddleRight(x, y); | |
drawLeftTop(x, y); | |
drawBottomLeft(x, y); | |
drawBottomRight(x, y); | |
} | |
void drawDigit(unsigned char digit, int x, int y) | |
{ | |
switch (digit) | |
{ | |
case 0: | |
draw0(x, y); | |
break; | |
case 1: | |
draw1(x, y); | |
break; | |
case 2: | |
draw2(x, y); | |
break; | |
case 3: | |
draw3(x, y); | |
break; | |
case 4: | |
draw4(x, y); | |
break; | |
case 5: | |
draw5(x, y); | |
break; | |
case 6: | |
draw6(x, y); | |
break; | |
case 7: | |
draw7(x, y); | |
break; | |
case 8: | |
draw8(x, y); | |
break; | |
case 9: | |
draw9(x, y); | |
break; | |
} | |
} | |
void drawColon(int x, int y) | |
{ | |
int third = (2 * VERTICAL_BAR_LEN + 3) / 3; | |
drawVerticalBar(x, y + third, 1); | |
drawVerticalBar(x, y + 2 * third, 1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment