Resizing works.
This commit is contained in:
parent
561b4ba599
commit
893f18a7e0
@ -8,8 +8,7 @@
|
||||
|
||||
void card_malloc(struct card **card) {
|
||||
if (!(*card = malloc(sizeof(**card)))) {
|
||||
fprintf(stderr, tty_solitaire_error_message(errno, __FILE__, __LINE__));
|
||||
exit(errno);
|
||||
tty_solitaire_generic_error(errno, __FILE__, __LINE__);
|
||||
}
|
||||
frame_malloc(&((*card)->frame));
|
||||
}
|
||||
|
21
src/common.c
21
src/common.c
@ -1,16 +1,25 @@
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ncurses.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
char *tty_solitaire_error_message(int errno, char *file, int line) {
|
||||
char *message = malloc(sizeof(ERROR_MESSAGE_BUFFER_SIZE));
|
||||
bool term_size_ok() {
|
||||
int lines, columns;
|
||||
getmaxyx(stdscr, lines, columns);
|
||||
return(lines >= MIN_TERM_LINES && columns >= MIN_TERM_COLS);
|
||||
}
|
||||
|
||||
void tty_solitaire_generic_error(int errno, char *file, int line) {
|
||||
char message[TTY_SOLITAIRE_BUFSIZ];
|
||||
snprintf(message,
|
||||
ERROR_MESSAGE_BUFFER_SIZE,
|
||||
"%s: %s (%s:%d)\n",
|
||||
TTY_SOLITAIRE_BUFSIZ,
|
||||
"%s: %s (%s:%d)",
|
||||
program_name,
|
||||
strerror(errno),
|
||||
file,
|
||||
line - 1);
|
||||
return(message);
|
||||
fprintf(stderr, "%s\n", message);
|
||||
exit(errno);
|
||||
}
|
||||
|
13
src/common.h
13
src/common.h
@ -1,8 +1,17 @@
|
||||
#ifndef TTY_SOLITAIRE_COMMON_H
|
||||
#define TTY_SOLITAIRE_COMMON_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MIN_TERM_LINES 28
|
||||
#define MIN_TERM_COLS 57
|
||||
#define TTY_SOLITAIRE_BUFSIZ 100
|
||||
|
||||
#define SMALL_TERM_MSG "Please increase your terminal size to at least 57x28 or press q to quit."
|
||||
|
||||
extern const char *program_name;
|
||||
#define ERROR_MESSAGE_BUFFER_SIZE 100
|
||||
char *tty_solitaire_error_message(int, char *, int);
|
||||
|
||||
void tty_solitaire_generic_error(int, char *, int);
|
||||
bool term_size_ok();
|
||||
|
||||
#endif
|
||||
|
@ -11,8 +11,7 @@
|
||||
|
||||
void cursor_malloc(struct cursor **cursor) {
|
||||
if (!(*cursor = malloc(sizeof(**cursor)))) {
|
||||
fprintf(stderr, tty_solitaire_error_message(errno, __FILE__, __LINE__));
|
||||
exit(errno);
|
||||
tty_solitaire_generic_error(errno, __FILE__, __LINE__);
|
||||
}
|
||||
(*cursor)->window = newwin(1, 1, CURSOR_BEGIN_Y, CURSOR_BEGIN_X);
|
||||
}
|
||||
|
@ -8,8 +8,7 @@
|
||||
|
||||
void deck_malloc(struct deck **deck) {
|
||||
if (!(*deck = malloc(sizeof(**deck)))) {
|
||||
fprintf(stderr, tty_solitaire_error_message(errno, __FILE__, __LINE__));
|
||||
exit(errno);
|
||||
tty_solitaire_generic_error(errno, __FILE__, __LINE__);
|
||||
}
|
||||
stack_malloc(&((*deck)->stock));
|
||||
stack_malloc(&((*deck)->waste_pile));
|
||||
|
@ -8,8 +8,7 @@
|
||||
|
||||
void frame_malloc(struct frame **frame) {
|
||||
if (!(*frame = malloc(sizeof(**frame)))) {
|
||||
fprintf(stderr, tty_solitaire_error_message(errno, __FILE__, __LINE__));
|
||||
exit(errno);
|
||||
tty_solitaire_generic_error(errno, __FILE__, __LINE__);
|
||||
}
|
||||
(*frame)->window = newwin(FRAME_HEIGHT, FRAME_WIDTH, 0, 0);
|
||||
}
|
||||
|
@ -149,8 +149,7 @@ static void shuffle_deck(struct deck *deck) {
|
||||
int random;
|
||||
|
||||
if (!(card = malloc(NUMBER_OF_CARDS * sizeof(*card)))) {
|
||||
fprintf(stderr, tty_solitaire_error_message(errno, __FILE__, __LINE__));
|
||||
exit(errno);
|
||||
tty_solitaire_generic_error(errno, __FILE__, __LINE__);
|
||||
}
|
||||
for (int i = 0; i < NUMBER_OF_CARDS; i++) {
|
||||
card[i] = stack_pop(&(deck->stock));
|
||||
|
309
src/keyboard.c
309
src/keyboard.c
@ -1,4 +1,5 @@
|
||||
#include <stdlib.h>
|
||||
#include <ncurses.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "keyboard.h"
|
||||
@ -7,6 +8,18 @@
|
||||
#include "game.h"
|
||||
#include "cursor.h"
|
||||
#include "gui.h"
|
||||
#include "common.h"
|
||||
|
||||
static void handle_term_resize() {
|
||||
clear();
|
||||
refresh();
|
||||
if (term_size_ok()) {
|
||||
draw_deck(deck);
|
||||
draw_cursor(cursor);
|
||||
} else {
|
||||
mvprintw(1, 1, SMALL_TERM_MSG);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: this function does not work on stacks with no marked cards.
|
||||
* In that case it returns the stack's length. */
|
||||
@ -35,12 +48,11 @@ static void unmark_cards(struct stack *stack) {
|
||||
|
||||
static void handle_card_movement(struct cursor *cursor) {
|
||||
struct stack **origin = cursor_stack(cursor);
|
||||
int option;
|
||||
int key;
|
||||
|
||||
if (cursor_on_invalid_spot(cursor) || stack_empty(*origin)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (maneuvre_stack(*origin)) {
|
||||
erase_stack(*origin);
|
||||
card_mark((*origin)->card);
|
||||
@ -51,8 +63,136 @@ static void handle_card_movement(struct cursor *cursor) {
|
||||
cursor_mark(cursor);
|
||||
draw_cursor(cursor);
|
||||
|
||||
while (1) {
|
||||
switch (option = getch()) {
|
||||
for (;;) {
|
||||
if ((key = getch()) == 'q' || key == 'Q') {
|
||||
endwin();
|
||||
exit(0);
|
||||
}
|
||||
if (term_size_ok()) {
|
||||
switch (key) {
|
||||
case 'h':
|
||||
case 'j':
|
||||
case 'k':
|
||||
case 'l':
|
||||
case KEY_LEFT:
|
||||
case KEY_DOWN:
|
||||
case KEY_UP:
|
||||
case KEY_RIGHT:
|
||||
erase_cursor(cursor);
|
||||
cursor_move(cursor, cursor_direction(key));
|
||||
draw_cursor(cursor);
|
||||
break;
|
||||
case 'm':
|
||||
if (origin == cursor_stack(cursor) && maneuvre_stack(*origin)) {
|
||||
for (struct stack *i = *origin; i && i->next; i = i->next) {
|
||||
if (i->next->card->face == EXPOSED &&
|
||||
(i->card->frame->begin_y - i->next->card->frame->begin_y) > 1) {
|
||||
erase_stack(*origin);
|
||||
card_mark(i->next->card);
|
||||
draw_stack(*origin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
if (origin == cursor_stack(cursor) && maneuvre_stack(*origin)) {
|
||||
for (struct stack *i = (*origin)->next; i; i = i->next) {
|
||||
if (i->next) {
|
||||
if ((i->card->frame->begin_y - i->next->card->frame->begin_y) > 1) {
|
||||
erase_stack(*origin);
|
||||
card_unmark(i->card);
|
||||
draw_stack(*origin);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (i->card->frame->begin_y == (MANEUVRE_BEGIN_Y + 1)) {
|
||||
erase_stack(*origin);
|
||||
card_unmark(i->card);
|
||||
draw_stack(*origin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KEY_SPACEBAR:;
|
||||
/* http://www.mail-archive.com/gcc-bugs@gcc.gnu.org/msg259382.html */
|
||||
struct stack **destination = cursor_stack(cursor);
|
||||
int _marked_cards_count = marked_cards_count(*origin);
|
||||
if (maneuvre_stack(*origin) && _marked_cards_count > 0) {
|
||||
erase_stack(*origin);
|
||||
unmark_cards(*origin);
|
||||
draw_stack(*origin);
|
||||
}
|
||||
if (destination) {
|
||||
erase_stack(*origin);
|
||||
erase_cursor(cursor);
|
||||
if (_marked_cards_count > 1 &&
|
||||
maneuvre_stack(*origin) &&
|
||||
maneuvre_stack(*destination)) {
|
||||
struct stack *block = *origin;
|
||||
for (int i = 1; i < _marked_cards_count; block = block->next, i++)
|
||||
;
|
||||
if (valid_move(block, *destination)) {
|
||||
move_block(origin, destination, _marked_cards_count);
|
||||
}
|
||||
} else {
|
||||
if (valid_move(*origin, *destination)) {
|
||||
if (maneuvre_stack(*destination)) {
|
||||
cursor->y++;
|
||||
}
|
||||
move_card(origin, destination);
|
||||
}
|
||||
}
|
||||
draw_stack(*origin);
|
||||
draw_stack(*destination);
|
||||
if (maneuvre_stack(*origin) && *origin == *destination) {
|
||||
erase_cursor(cursor);
|
||||
cursor->y--;
|
||||
}
|
||||
}
|
||||
cursor_unmark(cursor);
|
||||
draw_cursor(cursor);
|
||||
return;
|
||||
case KEY_ESCAPE:
|
||||
if (cursor_stack(cursor) == origin && maneuvre_stack(*origin)) {
|
||||
erase_cursor(cursor);
|
||||
cursor->y--;
|
||||
}
|
||||
if (marked_cards_count(*origin) > 0) {
|
||||
erase_stack(*origin);
|
||||
unmark_cards(*origin);
|
||||
draw_stack(*origin);
|
||||
}
|
||||
if (cursor->marked) {
|
||||
cursor_unmark(cursor);
|
||||
draw_cursor(cursor);
|
||||
}
|
||||
return;
|
||||
case KEY_RESIZE:
|
||||
handle_term_resize();
|
||||
break;
|
||||
case 'q':
|
||||
case 'Q':
|
||||
endwin();
|
||||
game_end();
|
||||
exit(0);
|
||||
}
|
||||
} else if (key == KEY_RESIZE) {
|
||||
handle_term_resize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_event(int key) {
|
||||
if (key == 'q' || key == 'Q') {
|
||||
endwin();
|
||||
game_end();
|
||||
exit(0);
|
||||
}
|
||||
if (term_size_ok()) {
|
||||
switch (key) {
|
||||
case 'h':
|
||||
case 'j':
|
||||
case 'k':
|
||||
@ -62,151 +202,46 @@ static void handle_card_movement(struct cursor *cursor) {
|
||||
case KEY_UP:
|
||||
case KEY_RIGHT:
|
||||
erase_cursor(cursor);
|
||||
cursor_move(cursor, cursor_direction(option));
|
||||
cursor_move(cursor, cursor_direction(key));
|
||||
draw_cursor(cursor);
|
||||
break;
|
||||
case 'm':
|
||||
if (origin == cursor_stack(cursor) && maneuvre_stack(*origin)) {
|
||||
for (struct stack *i = *origin; i && i->next; i = i->next) {
|
||||
if (i->next->card->face == EXPOSED &&
|
||||
(i->card->frame->begin_y - i->next->card->frame->begin_y) > 1) {
|
||||
erase_stack(*origin);
|
||||
card_mark(i->next->card);
|
||||
draw_stack(*origin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
if (origin == cursor_stack(cursor) && maneuvre_stack(*origin)) {
|
||||
for (struct stack *i = (*origin)->next; i; i = i->next) {
|
||||
if (i->next) {
|
||||
if ((i->card->frame->begin_y - i->next->card->frame->begin_y) > 1) {
|
||||
erase_stack(*origin);
|
||||
card_unmark(i->card);
|
||||
draw_stack(*origin);
|
||||
break;
|
||||
case KEY_SPACEBAR:
|
||||
if (cursor_on_stock(cursor)) {
|
||||
if (stack_empty(deck->stock)) {
|
||||
if (game.passes_through_deck_left >= 1) {
|
||||
while (!stack_empty(deck->waste_pile)) {
|
||||
move_card(&(deck->waste_pile), &(deck->stock));
|
||||
card_cover(deck->stock->card);
|
||||
}
|
||||
} else {
|
||||
if (i->card->frame->begin_y == (MANEUVRE_BEGIN_Y + 1)) {
|
||||
erase_stack(*origin);
|
||||
card_unmark(i->card);
|
||||
draw_stack(*origin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KEY_SPACEBAR:;
|
||||
/* http://www.mail-archive.com/gcc-bugs@gcc.gnu.org/msg259382.html */
|
||||
struct stack **destination = cursor_stack(cursor);
|
||||
int _marked_cards_count = marked_cards_count(*origin);
|
||||
if (maneuvre_stack(*origin) && _marked_cards_count > 0) {
|
||||
erase_stack(*origin);
|
||||
unmark_cards(*origin);
|
||||
draw_stack(*origin);
|
||||
}
|
||||
if (destination) {
|
||||
erase_stack(*origin);
|
||||
erase_cursor(cursor);
|
||||
if (_marked_cards_count > 1 &&
|
||||
maneuvre_stack(*origin) &&
|
||||
maneuvre_stack(*destination)) {
|
||||
struct stack *block = *origin;
|
||||
for (int i = 1; i < _marked_cards_count; block = block->next, i++)
|
||||
;
|
||||
if (valid_move(block, *destination)) {
|
||||
move_block(origin, destination, _marked_cards_count);
|
||||
draw_stack(deck->stock);
|
||||
draw_stack(deck->waste_pile);
|
||||
}
|
||||
} else {
|
||||
if (valid_move(*origin, *destination)) {
|
||||
if (maneuvre_stack(*destination)) {
|
||||
cursor->y++;
|
||||
}
|
||||
move_card(origin, destination);
|
||||
}
|
||||
}
|
||||
draw_stack(*origin);
|
||||
draw_stack(*destination);
|
||||
if (maneuvre_stack(*origin) && *origin == *destination) {
|
||||
erase_cursor(cursor);
|
||||
cursor->y--;
|
||||
}
|
||||
}
|
||||
cursor_unmark(cursor);
|
||||
draw_cursor(cursor);
|
||||
return;
|
||||
case KEY_ESCAPE:
|
||||
if (cursor_stack(cursor) == origin && maneuvre_stack(*origin)) {
|
||||
erase_cursor(cursor);
|
||||
cursor->y--;
|
||||
}
|
||||
if (marked_cards_count(*origin) > 0) {
|
||||
erase_stack(*origin);
|
||||
unmark_cards(*origin);
|
||||
draw_stack(*origin);
|
||||
}
|
||||
if (cursor->marked) {
|
||||
cursor_unmark(cursor);
|
||||
draw_cursor(cursor);
|
||||
}
|
||||
return;
|
||||
case 'q':
|
||||
case 'Q':
|
||||
endwin();
|
||||
game_end();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_event(int key) {
|
||||
switch (key) {
|
||||
case 'h':
|
||||
case 'j':
|
||||
case 'k':
|
||||
case 'l':
|
||||
case KEY_LEFT:
|
||||
case KEY_DOWN:
|
||||
case KEY_UP:
|
||||
case KEY_RIGHT:
|
||||
erase_cursor(cursor);
|
||||
cursor_move(cursor, cursor_direction(key));
|
||||
draw_cursor(cursor);
|
||||
break;
|
||||
case KEY_SPACEBAR:
|
||||
if (cursor_on_stock(cursor)) {
|
||||
if (stack_empty(deck->stock)) {
|
||||
if (game.passes_through_deck_left >= 1) {
|
||||
while (!stack_empty(deck->waste_pile)) {
|
||||
move_card(&(deck->waste_pile), &(deck->stock));
|
||||
card_cover(deck->stock->card);
|
||||
move_card(&(deck->stock), &(deck->waste_pile));
|
||||
if (stack_empty(deck->stock)) {
|
||||
game.passes_through_deck_left--;
|
||||
}
|
||||
card_expose(deck->waste_pile->card);
|
||||
erase_stack(deck->waste_pile);
|
||||
draw_stack(deck->stock);
|
||||
draw_stack(deck->waste_pile);
|
||||
}
|
||||
} else {
|
||||
move_card(&(deck->stock), &(deck->waste_pile));
|
||||
if (stack_empty(deck->stock)) {
|
||||
game.passes_through_deck_left--;
|
||||
struct card *card;
|
||||
if (cursor_stack(cursor) &&
|
||||
(card = (*cursor_stack(cursor))->card)->face == COVERED) {
|
||||
card_expose(card);
|
||||
draw_card(card);
|
||||
} else {
|
||||
handle_card_movement(cursor);
|
||||
}
|
||||
card_expose(deck->waste_pile->card);
|
||||
erase_stack(deck->waste_pile);
|
||||
draw_stack(deck->stock);
|
||||
draw_stack(deck->waste_pile);
|
||||
}
|
||||
} else {
|
||||
struct card *card;
|
||||
if (cursor_stack(cursor) &&
|
||||
(card = (*cursor_stack(cursor))->card)->face == COVERED) {
|
||||
card_expose(card);
|
||||
draw_card(card);
|
||||
} else {
|
||||
handle_card_movement(cursor);
|
||||
}
|
||||
break;
|
||||
case KEY_RESIZE:
|
||||
handle_term_resize();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} else if (key == KEY_RESIZE) {
|
||||
handle_term_resize();
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,7 @@
|
||||
|
||||
void stack_malloc(struct stack **stack) {
|
||||
if (!(*stack = malloc(sizeof(**stack)))) {
|
||||
fprintf(stderr, tty_solitaire_error_message(errno, __FILE__, __LINE__));
|
||||
exit(errno);
|
||||
tty_solitaire_generic_error(errno, __FILE__, __LINE__);
|
||||
}
|
||||
card_malloc(&((*stack)->card));
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "gui.h"
|
||||
#include "game.h"
|
||||
#include "keyboard.h"
|
||||
#include "common.h"
|
||||
@ -12,35 +11,9 @@
|
||||
const char *program_name;
|
||||
struct game game;
|
||||
|
||||
void draw_greeting() {
|
||||
mvprintw(8, 26, "Welcome to tty-solitaire.");
|
||||
mvprintw(10, 23, "Move with the arrow keys or hjkl.");
|
||||
mvprintw(11, 19, "Use the space bar to mark and move cards.");
|
||||
mvprintw(12, 16, "After marking a card you can use m to increase ");
|
||||
mvprintw(13, 17, "and n to decrease the number of marked cards.");
|
||||
mvprintw(15, 19, "Press the space bar to play or q to quit.");
|
||||
}
|
||||
|
||||
void usage(const char *program_name) {
|
||||
printf("usage: %s [-v|--version] [-h|--help] [-p|--passes=NUMBER]\n", program_name);
|
||||
printf(" -v, --version Show version\n");
|
||||
printf(" -h, --help Show this message\n");
|
||||
printf(" -p, --passes Number of passes through the deck\n");
|
||||
}
|
||||
|
||||
void version() {
|
||||
FILE *version_file;
|
||||
char version_string[6];
|
||||
|
||||
if (!(version_file = fopen("VERSION", "rb"))) {
|
||||
fprintf(stderr, tty_solitaire_error_message(errno, __FILE__, __LINE__));
|
||||
exit(errno);
|
||||
}
|
||||
fread(version_string, 1, 5, version_file);
|
||||
version_string[5] = '\0';
|
||||
printf("%s\n", version_string);
|
||||
fclose(version_file);
|
||||
}
|
||||
void version();
|
||||
void usage(const char *);
|
||||
void draw_greeting();
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int option;
|
||||
@ -83,31 +56,44 @@ int main(int argc, char *argv[]) {
|
||||
init_pair(3, COLOR_WHITE, COLOR_BLUE);
|
||||
init_pair(4, COLOR_WHITE, COLOR_GREEN);
|
||||
|
||||
draw_greeting();
|
||||
|
||||
int key;
|
||||
do {
|
||||
switch (key = getch()) {
|
||||
case KEY_SPACEBAR:
|
||||
clear();
|
||||
refresh();
|
||||
game_init(&game, passes_through_deck);
|
||||
break;
|
||||
case 'q':
|
||||
case 'Q':
|
||||
|
||||
while (!term_size_ok()) {
|
||||
clear();
|
||||
mvprintw(1, 1, SMALL_TERM_MSG);
|
||||
refresh();
|
||||
if ((key = getch()) == 'q' || key == 'Q') {
|
||||
endwin();
|
||||
return(0);
|
||||
}
|
||||
} while (key != KEY_SPACEBAR);
|
||||
}
|
||||
|
||||
do {
|
||||
clear();
|
||||
draw_greeting();
|
||||
refresh();
|
||||
|
||||
for (;;) {
|
||||
if ((key = getch()) == 'q' || key == 'Q') {
|
||||
endwin();
|
||||
game_end();
|
||||
exit(0);
|
||||
} else {
|
||||
keyboard_event(key);
|
||||
return(0);
|
||||
}
|
||||
if (term_size_ok()) {
|
||||
clear();
|
||||
draw_greeting();
|
||||
refresh();
|
||||
if (key == KEY_SPACEBAR) {
|
||||
game_init(&game, passes_through_deck);
|
||||
break;
|
||||
}
|
||||
} else if (key == KEY_RESIZE) {
|
||||
clear();
|
||||
mvprintw(1, 1, SMALL_TERM_MSG);
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
keyboard_event(getch());
|
||||
} while (!game_won());
|
||||
|
||||
endwin();
|
||||
@ -116,3 +102,32 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void draw_greeting() {
|
||||
mvprintw(8, 26, "Welcome to tty-solitaire.");
|
||||
mvprintw(10, 23, "Move with the arrow keys or hjkl.");
|
||||
mvprintw(11, 19, "Use the space bar to mark and move cards.");
|
||||
mvprintw(12, 16, "After marking a card you can use m to increase ");
|
||||
mvprintw(13, 17, "and n to decrease the number of marked cards.");
|
||||
mvprintw(15, 19, "Press the space bar to play or q to quit.");
|
||||
}
|
||||
|
||||
void usage(const char *program_name) {
|
||||
printf("usage: %s [-v|--version] [-h|--help] [-p|--passes=NUMBER]\n", program_name);
|
||||
printf(" -v, --version Show version\n");
|
||||
printf(" -h, --help Show this message\n");
|
||||
printf(" -p, --passes Number of passes through the deck\n");
|
||||
}
|
||||
|
||||
void version() {
|
||||
FILE *version_file;
|
||||
char version_string[6];
|
||||
|
||||
if (!(version_file = fopen("VERSION", "rb"))) {
|
||||
tty_solitaire_generic_error(errno, __FILE__, __LINE__);
|
||||
}
|
||||
fread(version_string, 1, 5, version_file);
|
||||
version_string[5] = '\0';
|
||||
printf("%s\n", version_string);
|
||||
fclose(version_file);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user