Skip to content

Instantly share code, notes, and snippets.

@Experiment5X
Last active December 19, 2015 19:19
Show Gist options
  • Save Experiment5X/6005507 to your computer and use it in GitHub Desktop.
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…
#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