You'll remember that, decades ago, people hooked up to a single, central computer using dumb terminals. Thus programs living on the central computer were expected to communicate with terminal screens. Like, if a C program printed a specific code to a terminal then it could control its behavior (cursor positioning, instructions to clear the screen, change colors, and so on.) The class of programs that have a terminal device as their output are called terminal-oriented. Today's terminals are emulators that mimic the old ones, such that terminal-oriented programs like the vi editor -- from 1976 -- still work today.
These days, you can write a program that opens up a pseudoterminal (pty), which is a virtual device with a bi-directional channel for inter-process communication. On one end of the channel, you have the pty "master," and on the other is the "slave." It is the slave end that is special, because it simulates a physical terminal device. Here's the diagram:
So if you're writing a terminal, you want to understand its place in the diagram above. The driver program is your actual console app which should employ a pseudoterminal (the pty master & slave pipe) and does the fork / exec operations necessary to ensure it has master, and its child process the slave. The child would become the terminal-oriented program like the vi editor, or, more generally, a shell such as bash. They write their output to the slave, which pretends to be a real terminal and can process or discard all the codes on your behalf.
Hopefully I got that right. I recommend reading The Linux Programming Interface
book, last chapter. It's where I got this diagram from and gives you the basic source code to begin writing a terminal.
EDIT: Your driver will need to process certain codes itself, but getting into the nitty gritty is out of the scope of this post.