From ebaeadbd679cff8257032f8ce4cea611a4171a8c Mon Sep 17 00:00:00 2001 From: xolatile Date: Sat, 11 Nov 2023 07:39:09 -0500 Subject: [PATCH] More on ASCII escape sequences and numbers... --- chapters/chapter_2.c | 17 +++++------------ chapters/chapter_2.h | 31 +++++++++++++++++++++++++++++++ xhartae.c | 17 +++++++++++++++-- 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/chapters/chapter_2.c b/chapters/chapter_2.c index a58da08..fee2994 100644 --- a/chapters/chapter_2.c +++ b/chapters/chapter_2.c @@ -447,12 +447,12 @@ We've mentioned before, in chapter zero, that you can implement 'string_*' funct explanatory, so you can do a "homework" of reading them and trying to understand what they'll do. Since I use very verbose naming style, I hope that won't be a problem... */ -int curses_render_string (char * string, int colour, int effect, int x, int y) { +int curses_render_string (char * string, int colour, int effect, int x, int y) { // Keep in mind, we could reimplement this to be very similar to "limited" version. return (curses_render_string_limit (string, string_length (string), colour, effect, x, y)); } -int curses_render_number (int number, int colour, int effect, int x, int y) { - return (curses_render_number_limit (number, 32, colour, effect, x, y)); +int curses_render_number (int number, int colour, int effect, int x, int y) { // This is not particularly smart solution, but it's simple to understand. + return (curses_render_string (number_to_string (number), colour, effect, x, y)); } int curses_render_string_limit (char * string, int limit, int colour, int effect, int x, int y) { @@ -473,15 +473,8 @@ int curses_render_string_limit (char * string, int limit, int colour, int effect return (limit); } -int curses_render_number_limit (int number, int limit, int colour, int effect, int x, int y) { // TO DO (: - (void) number; - (void) limit; - (void) colour; - (void) effect; - (void) x; - (void) y; - - return (limit); +int curses_render_number_limit (int number, int limit, int colour, int effect, int x, int y) { + return (curses_render_string (format_to_string (number, 1, 10, limit, ' '), colour, effect, x, y)); } #endif diff --git a/chapters/chapter_2.h b/chapters/chapter_2.h index 20b5207..d8d31a8 100644 --- a/chapters/chapter_2.h +++ b/chapters/chapter_2.h @@ -119,6 +119,37 @@ output object files (.o), and then we can link them together (most compilers are functions declared in "chapter_2.h" and defined in "chapter_2.c" in completely separate file "chapter_3.c", if we have included it with '#include "chapter_2.h". Keep in mind that header files can be included recursively, that's why we use those header guards, '#ifndef SOMETHING', '#define SOMETHING' and '#endif' at the end. That way, they'll be included only once, so compiler won't be confused and spit out errors. + +Now, lets talk about ASCII escape sequences. Most terminals support some special combination of characters, that aren't printed like you'd normally expect. We call them escape +sequences because they all start with character literal '\033', '\x1b' or '\e', which is same as decimal 27, and in our character enumeration 'CHARACTER_ESCAPE'. They are somewhat +standardized way of interacting with your terminal. I'll use '\033' here because it does well with C strings and it's the most widely supported. Also, we'll use formatting of +'printf' function from , which we'll need to cover later in more details. + +"\033[H": Set cursor position to upper left corner (position 1, 1). +"\033[%i;%iH": Set cursor position at Y and X coordinates, ranging from 1 to N (I simply limit N as 1000, and they can be prefixed with '0's). +"\033[6n": Get current cursor position, this will output response string defined just below. +"\033[%i;%iR": Response is similar to 'set-cursor-position' string, except it's 'R' instead of 'H', so you'll need to parse it. +"\033[2K": Clear an entire line. +"\033[2J": Clear an entire screen. +"\033[c": Reset terminal to initial state, we won't use this string, but 'tcsetattr' function. +"\033[%dA": Move cursor N characters up, if you don't provide N, it's assumed to be equal to 1. +"\033[%dB": Move cursor N characters down, if you don't provide N, it's assumed to be equal to 1. +"\033[%dC": Move cursor N characters right, if you don't provide N, it's assumed to be equal to 1. +"\033[%dD": Move cursor N characters left, if you don't provide N, it's assumed to be equal to 1. Multiple cursors edited this file... +"\033[%d;3%dm": Set character attributes (effect and colour) to types described below, first is effect, second is colour. +"\033[0m": Reset character attributes to default state. + +Effects: Colours: +- Normal: 0 - Grey: 0 +- Bold: 1 - Red: 1 +- Italic: 3 - Green: 2 +- Underline: 4 - Yellow: 3 +- Blink: 5 - Blue: 4 +- Reverse: 7 - Pink: 5 + - Cyan: 6 + - White: 7 + +Instead of hardcoding values yourself and remembering those, you can just use enumerations from "chapter_0.h", like, COLOUR_BLUE and EFFECT_BOLD. */ extern int curses_character; // Literal character (integer) that user has pressed, some of them are more than single byte, like arrow keys defined above. diff --git a/xhartae.c b/xhartae.c index 1098ecd..6ca7e2e 100644 --- a/xhartae.c +++ b/xhartae.c @@ -17,6 +17,17 @@ This is the ultimate C programming language guide, brought to you by Ognjen 'xol this "book" will be full of grammatical mistakes, but not compiler warnings. Please be patient, C is a small language, even for the time when it was made, so if you ignore my rambling and focus on what's written outside of the comments, you'll easily learn it. Good luck and have fun... +With that being said, I'll tell you the honest truth. No amount of books or source code you read (that's written in C or any other language) will make you good in programming (in +C or any other language). You get good in programming by writing the programs. Knowing what some statement, expression or library function will do is just a small advantage that's +saving you the time in order not to read (read yet again...) some documentation or specification. Sure, you can write literal machine code for some CPU instruction set, but you +still need to know what instructions are supported and how they translate to machine code. The sad thing about programming is that you need very small subset of information to +achieve creating almost anything, and yet, you need huge set of informations to do it in more concise way. That's the tradeoff. + +Either learn very small subset of "building materials" and "architecture", then proceed building sewers, roads, houses, malls, factories, skyscrapers and in the end create a town, +or learn huge set of "pre-made houses, pre-made factories, pre-made road blocks", and create a same-looking town. If you use any kind of library functions, even the one's we'll +use in some parts of this program, you'll end up as a "interior designer" rather than an "architect". C programming language is the minimal kind of tool that's widely supported +and lets do write "quick assembly", we'll have entire chapter about assembly and machine code, so you can make your own language. + We're dealing with a low-level functional (and procedural) programming language called C. So, disengage all safety protocols, think twice, write once, enter the Great C and learn to sail on it after some practice. This will never be a book. It has no readers. It's not even printed. It's pages are files. It's cover is a folder. This will never be a book. I, for the most part, am having fun writing this, same as I have fun while programming. You won't get a job after reading this "book", only some knowledge. @@ -99,8 +110,10 @@ int main (int argc, char * * argv) { curses_configure (); while (curses_active != 0) { - curses_render_background ('.', COLOUR_GREY, EFFECT_BOLD); - curses_render_character ('@', COLOUR_RED, EFFECT_BOLD, 1, 1); + curses_render_background ('.', COLOUR_GREY, EFFECT_BOLD); + curses_render_character ('@', COLOUR_RED, EFFECT_BOLD, 1, 1); + curses_render_string ("Heyo world!", COLOUR_GREEN, EFFECT_ITALIC, 2, 2); + curses_render_number_limit (-420, 6, COLOUR_YELLOW, EFFECT_UNDERLINE, 0, 3); curses_synchronize (); }