From b208ea10df6bc8568c2d644208e309f5901aa1dc Mon Sep 17 00:00:00 2001 From: xolatile Date: Wed, 29 Nov 2023 06:56:22 -0500 Subject: [PATCH] Added fill and line, and commented stuff out... --- chapter/chapter_2.c | 26 +++++++++++++++++++++++++- chapter/chapter_2.h | 3 ++- program/program_2.c | 7 ++----- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/chapter/chapter_2.c b/chapter/chapter_2.c index 07628a0..9679ab8 100644 --- a/chapter/chapter_2.c +++ b/chapter/chapter_2.c @@ -234,6 +234,18 @@ static void curses_initialize (void) { string_copy_limit (curses_screen + skip + next, "\r\n", string_length ("\r\n")); // And lastly, we copy those line breaks at this offset into our screen buffer. } // Keep in mind that word-wrapping is slow on some terminals, hence I use this. + // So, what's difference with using these two examples? Really, nothing. + // string_copy (& string [offset], source); + // string_copy ( string + offset , source); + // Unary operator '&' references the variable, returning it's memory address (pointer of its' type). + // Unary operator '*' (not multiplication!) dereferences the variable, returning value found at some memory address (with type). + // Arrays in C are just pointers to the first element of that array, and since they lay next to each other in memory, we can access them by doing: + // array [element] <=> * (array + sizeof (* array) * element) + // So, to explain, we're adding pointer to the first element of that array with size of one element multiplied by index of wanted element, and dereferencing that. + // Since referencing and then immediately dereferencing something does nothing, we can ommit that '& (* variable)' into just 'variable'. + // & array [element] <=> array + sizeof (* array) * element + // In the end, use whatever you like, compiler will make sure to optimize it, since this is a simple optimization process, it won't cause bugs. + terminal_clear (); } @@ -477,7 +489,7 @@ void curses_render_background (char character, int colour, int effect) { } } -void curses_render_rectangle (char character, int colour, int effect, int x, int y, int width, int height) { +void curses_render_rectangle_fill (char character, int colour, int effect, int x, int y, int width, int height) { for (int j = 0; j < height; ++j) { // You can declare type of those iterators in for loops. for (int i = 0; i < width; ++i) { // This only works if you're not using ANSI C (C89 / C90) standard. curses_render_character (character, colour, effect, x + i, y + j); // Now, we render character by character again... @@ -485,6 +497,18 @@ void curses_render_rectangle (char character, int colour, int effect, int x, int } } +void curses_render_rectangle_line (char character, int colour, int effect, int x, int y, int width, int height) { + for (int offset = 0; offset < width; ++offset) { // Now, we only want to render line, rectangle has 4 lines, so we need 2 loops. + curses_render_character (character, colour, effect, x + offset, y); // First we're rendering horizontal lines, then vertical lines. + curses_render_character (character, colour, effect, x + offset, y + height - 1); // We also need to offset X or Y, depending on rectangle width or height. + } + + for (int offset = 0; offset < height; ++offset) { // Now, we only want to render line, rectangle has 4 lines, so we need 2 loops. + curses_render_character (character, colour, effect, x, y + offset); // I prefer to use 'offset' instead of 'i' and 'j', but I have no strict rule. + curses_render_character (character, colour, effect, x + width - 1, y + offset); // I'm mixing them here, so you can see what you find more readable. + } +} + /* We've mentioned before, in chapter zero, that you can implement 'string_*' functions by 'string_*_limit', and here's an example of that. Functions below are quite self 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... diff --git a/chapter/chapter_2.h b/chapter/chapter_2.h index 0a557c9..17304db 100644 --- a/chapter/chapter_2.h +++ b/chapter/chapter_2.h @@ -170,7 +170,8 @@ extern void curses_render_cursor (int x, int y); // Render terminal cursor at po extern void curses_render_character (char character, int colour, int effect, int x, int y); // Render single character at position X and Y. extern void curses_render_background (char character, int colour, int effect); // Render entire buffer with the same character. -extern void curses_render_rectangle (char character, int colour, int effect, int x, int y, int width, int height); // Guess what this function does...? +extern void curses_render_rectangle_fill (char character, int colour, int effect, int x, int y, int width, int height); // Guess what these functions do...? +extern void curses_render_rectangle_line (char character, int colour, int effect, int x, int y, int width, int height); // Remember that in chapter zero, I've separated 'string_*' and 'string_*_limit' functions. Now, there's always more ways to logically organize your code, for example, as below: extern int curses_render_string (char * string, int colour, int effect, int x, int y); diff --git a/program/program_2.c b/program/program_2.c index 5c279a4..54274bd 100644 --- a/program/program_2.c +++ b/program/program_2.c @@ -36,14 +36,11 @@ int main (void) { while (curses_active) { curses_render_background ('.', COLOUR_GREY, EFFECT_BOLD); - curses_render_rectangle (',', COLOUR_GREEN, EFFECT_NORMAL, 10, 10, 80, 24); + curses_render_rectangle_fill (',', COLOUR_GREEN, EFFECT_NORMAL, 10, 10, 80, 24); + curses_render_rectangle_line ('#', COLOUR_WHITE, EFFECT_NORMAL, 10, 10, 80, 24); curses_render_character ('@', COLOUR_CYAN, EFFECT_BOLD, player_x, player_y); - for (int i = 0; i < 50; ++i) { - curses_render_character ('#', COLOUR_BLUE, EFFECT_BOLD, i, i); - } - curses_synchronize (); }