discky is a terminal graphics library to draw colored 2D preimitives in terminal window using ASCII.
It provides API to:
- create drawable objects
- rendering them into a frame buffer
- and display frames continuously for static scenes or animation.
Important: You can increase the effective terminal resolution by reducing the text size (press Ctrl + -). A larger terminal window allows more characters to fit on the screen, resulting in a higher resolution display.
This initializes the terminal , so discky can render graphics correctly. Call this once before creating and using Discky
This restore the terminal sate when the program exits. Call this before returning from main()
Each draw calls returns an objId , which can be used to identify them.
objId drawRectangle(const Coordinate& a , const Coordinate& b , const objColor& color , const double& border = 1.0 , const double& opacity = 1.0);Draws a rectangle using two corner coordinates.
example :
discky.drawRectangle(NOR_COORD( -0.5 , -0.5) , NOR_COORD( 0.5 ,0.5) , DISCKY_COLOR_RED); objId drawTriangle(const Coordinate& a , const Coordinate& b , const Coordinate& c , const objColor& color , const double& border = 1.0 , const double& opacity = 1.0);Draw a triangle using 3 coordinates of its vertices.
example :
discky.drawTriangle(NOR_COORD(0 , -0.5) , NOR_COORD(0.5 , 0.5) , NOR_COORD(-0.5 , 0.5) , DISCKY_COLOR_GREEN); objId drawCircle(const Coordinate& a , const Coordinate& b , const objColor& color , const double& border = 1.0 , const double& opacity = 1.0);Draw a circle using 1 coordinate of its center and a radius(using radius style coordinate).
example:
discky.drawCircle(NOR_COORD(0.0 , 0.0) , NOR_LEN_MONO(0.2) , DISCKY_COLOR_RED);objId drawPoly(const std::vector<Coordinate> &ver ,const objColor &color , const double& border =1.0 , const double& opacity = 1.0);Draw a polygon from a vertex list
example:
discky.drawPoly({NOR_COORD(0 , -0.5) , NOR_COORD(0.5 , 0) , NOR_COORD(0 , 0.5) , NOR_COORD(-0.5 , 0)} , DISCKY_COLOR_RED);objId drawRawTxt(const Coordinate& a ,const std::string& txt , const objColor& color);Draw text at given coordinate
example:
discky.drawRawTxt(NOR_COORD(0.0 , 0.0) , "HELLO WORLD" , DISCKY_COLOR_RED);discky has a simple polling gbased input system to handle keyboard and moouse . it lives in "input.h" and is independed of Discky class (no instace is required)
call initInput() once , after iniTerminal() , to put the terminal into raw input mode and enable mouse reporting. call shutdownInput() before the program exits to restore the terminal original input mode
Call updateInput() every frame before checking any key or mouse state.
You can check with the Key enum or with a raw char(regular character).
enum class Key{
NONE,
CHAR,
UP,
DOWN,
LEFT,
RIGHT,
ENTER,
ESC,
BACKSPACE,
TAB,
HOME,
END,
F1,
F2,
F3,
F4,
};
bool isKeyDown(Key key)/bool isKeyDown(char c): this return true every frame the key is held downbool isKeyPressed(Key key)/bool isKeyPressed(char c): this return true only on the frame the key was pressedbool isKeyReleased(Key key)/bool isKeyReleased(char c): this return true only on the frame the key was released
example:
if(isKeyPressed('w'))<your code>;
if(isKeyDown(Key::RIGHT))<your code>;
if(isKeyReleased(Key::ESC))<your code>;
enum class MouseButton{
LEFT,
MIDDLE,
RIGHT,
NONE,
};
bool isMouseButtonDown(MouseButton button): it returns true every frame the button is pressed downbool isMouseButtonPressed(MouseButton button)" it returns true only on the frame the button was first pressedbool isMouseButtonReleased(MouseButton button): it returns true only on the frame the button was releasedint getMouseX()/int getMouseY(): returns the pixel coordinate of last known position of mouseint getScrollDelta(): returns the scroll amount since the lastupdateInput()call (positive = scroll up , negative = scroll down)
It support two coordinate modes , for both position and lengths
NOR_COORD(x, y)normalized coordinate where x,y ∈ [-1,1]SCR_COORD(x , y)exact pixel coordinate where x ∈ [0 , terminal maximum horizontal length] , y ∈[0,terminal maximum vertical length]
NOR_LEN_MONO(x)normalized length (depends on min(terminal max horizontal length , terminal max vertical length)) where x ∈ [-1 , 1]SCR_LEN_MONO(x)exact pixel length (depends on min(terminal max horizontal length , terminal max vertical length)) where x ∈ [0 , min(terminal max horizontal length , terminal max vertical length)]NOR_LEN_DI(x , y)normalized length (diffrent length in diffrent axis) where x,y ∈ [-1 , 1]SCR_LEN_DI(x , y)exact pixel length (diffrent length in diffrent axis) where x ∈ [0 , max terminal horizontal length] , y ∈ [0 , max terminal vertical length]
you can create custom color from 0-225 values usiing : cpp DISCKY_COLOR_RGB(r , g ,b) where r,g,b ∈ [0 , 255]
discky also has some predefined colors in colors.h which is included by discky.h
examples : DISCKY_COLOR_BLUE , DISCKY_COLOR_RED and many more
void setAntiAliasing(const antiAliasing& mode);Modes:
AA_NONE: No antialiasingAA_LOW: 2x2 samplingAA_MEDIUM: 4x4 samplingAA_HIGH: 8x8 sampling (not recommended)
void onDisckyError(ERRORS e, const std::string& msg) {
// custom logging / recovery
}
...
d.setErrorHandleFunc(onDisckyError);Use this to centralize diagnostics for invalid input, terminal info failures, and internal/runtime errors.
Discky use internal buffers ( backBuffer and frontBuffer)
the program should use this pipeline:
- Initilize terminal using
iniTerminal() - Declare Discky
- [optional] set error handle function example:
discky.setErrorHandleFunc(handler), where discky is Discky datatype and handler is:void handleDisckyError(ERRORS error ,const std::string& msg){ std::cerr<<msg; } - [optional , default = black background] set background color example :
discky.setBackground(DISCKY_COLOR_BLUE) - [optional , default : AA_NONE] set anti-aliasing mode , example :
discky.setAntiAliasing(antiAliasing::AA_LOW) - Draw/update objects
- render the frame according to current terminal size using example :
discky.render() - display the rendered frame to terminal example :
discky.display() - [optional] refresh draw list , example :
discky.refresh();
-
int getTerminalSizeX()returns max terminal horizontal length as int value -
int getTerminalSizeY()returns max terminal vertical length as int value -
bool isObjectTouchingBoundryX(objId obj)returns true if the provided objId's object is touching terminal horizontal boundry -
bool isObjectTouchingBoundryY(objId obj)return true if the provided objId's object is touching terminal vertical boundry -
bool isTxtTouchingBoundryX(objId obj)return true if the provided objId's text is touching terminal horizontal boundry -
bool isTxtTouchingBoundryY(objId obj)return true if the provided objId's text is touching terminal vertical boundry -
bool checkOverlap(objId a , objId b)return true if objects of provided objId are overlaping each others
There are examples in "example" folder , you can observe the code and learn from them for better experience
Here are some pics of examples:
rectangle.cpp

animate_rectangle.cpp :
D__repos_discky_bin_animate_rectangle.exe.2026-08-02.03-06-55.mp4
animate_circle.cpp :
D__repos_discky_bin_animate_circle.exe.2026-08-02.03-10-00.mp4
pacman.cpp :
D__repos_discky_bin_pacman.exe.2026-08-02.03-11-40.mp4
Build:
mkdir -p build
cd build
cmake ..
cmake --build .Binary of all examples will be generated in bin/ folder

