@@ -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 |
@@ -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 <stdio.h>, 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. | |||
@@ -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 (); | |||
} | |||