diff --git a/chapter/chapter_5.c b/chapter/chapter_5.c index 6c22402..794b624 100644 --- a/chapter/chapter_5.c +++ b/chapter/chapter_5.c @@ -13,17 +13,35 @@ It is distributed in the hope that it will be useful or harmful, it really depen /* So, what are actually getters and setters, and why you should never use them? Lets explain. - -@C -static number_t game_get_screen_width (game_t * game) { return (game->screen_width); } -static number_t game_get_screen_height (game_t * game) { return (game->screen_height); } -static number_t game_set_screen_width (game_t * game, number_t width) { return (game->screen_width = width); } -static number_t game_set_screen_height (game_t * game, number_t height) { return (game->screen_height = height); } -@ */ #define MEMORY_LIMIT (1024 * 1024) +static void generate_fill_function (world_t * world, number_t width, number_t height, number_t x, number_t y, block_t * block) { + number_t i, j; + + (void) width; + (void) height; + (void) x; + (void) y; + + for (j = 0; j < world->height; ++j) { + for (i = 0; i < world->width; ++i) { + world->block [j * world->width + i] = block; + } + } +} + +static void generate_rectangle_function (world_t * world, number_t width, number_t height, number_t x, number_t y, block_t * block) { + number_t i, j; + + for (j = 0; j < height; ++j) { + for (i = 0; i < width; ++i) { + world->block [(j + y) * world->width + (i + x)] = block; + } + } +} + memory_t memorize (number_t size) { static string_t memory_store [MEMORY_LIMIT] = { 0 }; static number_t memory_count = 0; @@ -59,19 +77,29 @@ symbol_t * format_symbol (number_t character, number_t colour, number_t effect) return (symbol); } +generator_t * game_generator (generate_t function) { + generator_t * generator; + + generator = memorize ((number_t) sizeof (* generator)); + + generator->generate = function; + + return (generator); +} + attribute_t * game_attribute (string_t name, bundle_t * points, ...) { attribute_t * attribute; va_list list; number_t action; - va_start (list, points); - attribute = memorize ((number_t) sizeof (* attribute)); string_copy ((attribute->name = memorize (string_length (name) + 1)), name); memory_copy ((attribute->points = memorize ((number_t) sizeof (* attribute->points))), points, (number_t) sizeof (* points)); + va_start (list, points); + for (;;) { action = (number_t) va_arg (list, int); @@ -96,14 +124,14 @@ skill_t * game_skill (string_t name, bundle_t * points, ...) { va_list list; number_t action; - va_start (list, points); - skill = memorize ((number_t) sizeof (* skill)); string_copy ((skill->name = memorize (string_length (name) + 1)), name); memory_copy ((skill->points = memorize ((number_t) sizeof (* skill->points))), points, (number_t) sizeof (* points)); + va_start (list, points); + for (;;) { action = (number_t) va_arg (list, int); @@ -149,10 +177,14 @@ block_t * game_block (string_t name, symbol_t * symbol, number_t collision, numb return (block); } -world_t * game_world (number_t width, number_t height, block_t * floor, block_t * wall) { - world_t * world; +world_t * game_world (number_t width, number_t height, ...) { + world_t * world; + va_list list; + generator_t * generator; + number_t w, h, x, y; + block_t * block; - number_t x, y; + //~number_t i, j; world = memorize ((number_t) sizeof (* world)); @@ -161,13 +193,31 @@ world_t * game_world (number_t width, number_t height, block_t * floor, block_t world->block = memorize (width * height * (number_t) sizeof (* world->block)); - for (y = 0; y < height; ++y) { - for (x = 0; x < width; ++x) { - world->block [y * width + x] = floor; - } + va_start (list, height); + + for (;;) { + generator = (generator_t *) va_arg (list, void *); + + if (generator != (generator_t *) 0XDEADBEEF) { + w = (number_t) va_arg (list, int); + h = (number_t) va_arg (list, int); + x = (number_t) va_arg (list, int); + y = (number_t) va_arg (list, int); + block = (block_t *) va_arg (list, void *); + + generator->generate (world, w, h, x, y, block); + } else break; } - world->block [6] = wall; + //~for (j = 0; j < height; ++j) { + //~for (i = 0; i < width; ++i) { + //~world->block [j * width + i] = terrain; + //~} + //~} + + //~world->block [6] = wall; + + va_end (list); return (world); } @@ -205,18 +255,22 @@ void game_render_world (world_t * world, number_t x, number_t y, number_t width, for (j = 0; (j < height) && (j < world->height); ++j) { for (i = 0; (i < width) && (i < world->width); ++i) { - game_render_block (world->block [(j + y) * world->width + (i + x)], i, j); + game_render_block (world->block [j * world->width + i], i + x, j + y); } } } void play_game (void) { player_t * player; - block_t * floor, * wall; + block_t * grass, * stone_floor, * stone_wall; world_t * world; - skill_t * blades, * axes, * bows, * spears, * puppet_magic, * nature_magic, * rune_magic, * charm_magic; + generator_t * fill, * rectangle; attribute_t * strength, * edurance, * wisdom, * agility; + skill_t * blades, * axes, * bows, * spears, * puppet_magic, * nature_magic, * rune_magic, * charm_magic; + + fill = game_generator (generate_fill_function); + rectangle = game_generator (generate_rectangle_function); strength = game_attribute ("Strength", format_bundle (1, 12, 0), GAME_ACTION_SWING_BLADE, GAME_ACTION_SWING_AXE, -GAME_ACTION_CAMP, 0); edurance = game_attribute ("Edurance", format_bundle (1, 12, 0), GAME_ACTION_WALK, GAME_ACTION_CAMP, -GAME_ACTION_REST, 0); @@ -234,44 +288,47 @@ void play_game (void) { player = game_player ("Riri", format_symbol ('@', COLOUR_CYAN, EFFECT_BOLD)); - floor = game_block ("Floor", format_symbol ('.', COLOUR_GREY, EFFECT_BOLD), FALSE, FALSE); - wall = game_block ("Wall", format_symbol ('#', COLOUR_GREY, EFFECT_BOLD), TRUE, FALSE); + grass = game_block ("Grass", format_symbol (',', COLOUR_GREEN, EFFECT_BOLD), FALSE, FALSE); + stone_floor = game_block ("Stone Floor", format_symbol ('.', COLOUR_GREY, EFFECT_BOLD), FALSE, FALSE); + stone_wall = game_block ("Stone Wall", format_symbol ('#', COLOUR_GREY, EFFECT_BOLD), TRUE, FALSE); - world = game_world (80, 24, floor, wall); + world = game_world (80, 24, fill, 0, 0, 0, 0, grass, + rectangle, 20, 10, 2, 4, stone_wall, + (generator_t *) 0XDEADBEEF); curses_configure (); while (curses_active) { curses_render_background (' ', COLOUR_WHITE, EFFECT_NORMAL); - //~curses_render_string ("Attributes:", COLOUR_WHITE, EFFECT_BOLD, 0, 0); + curses_render_string ("Attributes:", COLOUR_WHITE, EFFECT_BOLD, 0, 0); - //~game_render_attribute (strength, 2, 1); - //~game_render_attribute (edurance, 2, 2); - //~game_render_attribute (wisdom, 2, 3); - //~game_render_attribute (agility, 2, 4); + game_render_attribute (strength, 2, 1); + game_render_attribute (edurance, 2, 2); + game_render_attribute (wisdom, 2, 3); + game_render_attribute (agility, 2, 4); - //~curses_render_string ("Skills:", COLOUR_WHITE, EFFECT_BOLD, 0, 5); + curses_render_string ("Skills:", COLOUR_WHITE, EFFECT_BOLD, 0, 5); - //~game_render_skill (blades, 2, 6); - //~game_render_skill (axes, 2, 7); - //~game_render_skill (bows, 2, 8); - //~game_render_skill (spears, 2, 9); - //~game_render_skill (puppet_magic, 2, 10); - //~game_render_skill (nature_magic, 2, 11); - //~game_render_skill (rune_magic, 2, 12); - //~game_render_skill (charm_magic, 2, 13); + game_render_skill (blades, 2, 6); + game_render_skill (axes, 2, 7); + game_render_skill (bows, 2, 8); + game_render_skill (spears, 2, 9); + game_render_skill (puppet_magic, 2, 10); + game_render_skill (nature_magic, 2, 11); + game_render_skill (rune_magic, 2, 12); + game_render_skill (charm_magic, 2, 13); - game_render_world (world, 0, 0, curses_screen_width, curses_screen_height); + game_render_world (world, 40, 0, curses_screen_width, curses_screen_height); game_render_player (player); switch (curses_character) { - case 'w': player->y -= 1; break; - case 's': player->y += 1; break; - case 'a': player->x -= 1; break; - case 'd': player->x += 1; break; - default: break; + case SIGNAL_ARROW_UP: player->y -= 1; break; + case SIGNAL_ARROW_DOWN: player->y += 1; break; + case SIGNAL_ARROW_LEFT: player->x -= 1; break; + case SIGNAL_ARROW_RIGHT: player->x += 1; break; + default: break; } curses_synchronize (); diff --git a/chapter/chapter_5.h b/chapter/chapter_5.h index f10b94c..fee3317 100644 --- a/chapter/chapter_5.h +++ b/chapter/chapter_5.h @@ -37,19 +37,20 @@ typedef enum action_t { GAME_ACTION_COUNT } action_t; -typedef struct symbol_t { - number_t character, colour, effect; -} symbol_t; - typedef struct bundle_t { number_t minimum, maximum, current; } bundle_t; +typedef struct symbol_t { + number_t character, colour, effect; +} symbol_t; + typedef struct attribute_t { string_t name; number_t positive_count, negative_count; bundle_t * points; - action_t * positive, * negative; + action_t * positive; + action_t * negative; } attribute_t; typedef struct skill_t { @@ -61,8 +62,8 @@ typedef struct skill_t { typedef struct player_t { string_t name; - symbol_t * symbol; number_t x, y; + symbol_t * symbol; //~bundle_t * health, * armour, * mana, * stamina; //~attribute_t strength, edurance, intelligence, agility; //~skill_t blades, axes, bows, spears; @@ -71,9 +72,8 @@ typedef struct player_t { typedef struct block_t { string_t name; + number_t collision, override; symbol_t * symbol; - number_t collision; - number_t override; } block_t; typedef struct world_t { @@ -81,16 +81,23 @@ typedef struct world_t { block_t * * block; } world_t; +typedef void (* generate_t) (world_t *, number_t, number_t, number_t, number_t, block_t *); + +typedef struct generator_t { + generate_t generate; +} generator_t; + extern memory_t memorize (number_t size); -extern bundle_t * format_bundle (number_t minimum, number_t maximum, number_t current); -extern symbol_t * format_symbol (number_t character, number_t colour, number_t effect); +extern bundle_t * format_bundle (number_t minimum, number_t maximum, number_t current); +extern symbol_t * format_symbol (number_t character, number_t colour, number_t effect); +extern generator_t * game_generator (generate_t generator); extern attribute_t * game_attribute (string_t name, bundle_t * points, ...); extern skill_t * game_skill (string_t name, bundle_t * points, ...); extern player_t * game_player (string_t name, symbol_t * symbol); extern block_t * game_block (string_t name, symbol_t * symbol, number_t collision, number_t override); -extern world_t * game_world (number_t width, number_t height, block_t * floor, block_t * wall); +extern world_t * game_world (number_t width, number_t height, ...); extern void game_render_attribute (attribute_t * attribute, number_t x, number_t y); extern void game_render_skill (skill_t * skill, number_t x, number_t y);