-
Notifications
You must be signed in to change notification settings - Fork 11
/
03. Event_Loop_Answer.c
138 lines (122 loc) · 4.46 KB
/
03. Event_Loop_Answer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// [task_3.c]
// In this task, you'll learn how to use the allegro5 library to
// implement the event loop, making the window's close button work.
// You only need to enter codes below the 'TODO' comments.
#include <stdio.h>
#include <allegro5/allegro.h>
// If defined, logs will be shown on console and written to file.
#define LOG_ENABLED
ALLEGRO_DISPLAY* game_display;
// TODO: [Declare variables]
// Declare the variables that stores the event queue.
ALLEGRO_EVENT_QUEUE* game_event_queue;
// Define screen width and height as constants.
const int SCREEN_W = 800;
const int SCREEN_H = 600;
/* Declare function prototypes. */
// Process events inside the event queue using an infinity loop.
void game_start_event_loop(void);
// Release resources.
// Free the pointers we allocated.
void game_destroy(void);
/* Declare function prototypes for debugging. */
// Display error message and exit the program, used like 'printf'.
// Write formatted output to stdout and file from the format string.
// If the program crashes unexpectedly, you can inspect "log.txt" for
// further information.
void game_abort(const char* format, ...);
// Log events for later debugging, used like 'printf'.
// Write formatted output to stdout and file from the format string.
// You can inspect "log.txt" for logs in the last run.
void game_log(const char* format, ...);
// Called by 'game_abort', 'game_log' to deal with va_lists.
void game_vlog(const char* format, va_list arg);
// Program entry point.
// Returns program exit code.
int main(void) {
// Initialize allegro5 library
if (!al_init())
game_abort("failed to initialize allegro");
game_display = al_create_display(SCREEN_W, SCREEN_H);
if (!game_display)
game_abort("failed to create display");
// TODO: [Create event queue]
// 1) Create event queue and store the pointer in the variable you just declared.
// 2) Check the pointer, call game_abort if the function failed.
game_event_queue = al_create_event_queue();
if (!game_event_queue)
game_abort("failed to create event queue");
// TODO: [Register display to event queue]
al_register_event_source(game_event_queue, al_get_display_event_source(game_display));
game_log("Allegro5 initialized");
game_log("Game begin");
game_log("Game start event loop");
// This call blocks until the game is finished.
game_start_event_loop();
game_log("Game end");
game_destroy();
return 0;
}
void game_start_event_loop(void) {
bool done = false;
ALLEGRO_EVENT event;
while (!done) {
// TODO: [Process events]
// 1) Wait for event and store it in the 'event' variable.
// 2) If the event's type is ALLEGRO_EVENT_DISPLAY_CLOSE, set
// 'done' to true.
al_wait_for_event(game_event_queue, &event);
if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
// Event for clicking the window close button.
game_log("Window close button clicked");
done = true;
}
}
}
void game_destroy(void) {
// TODO: [Release resources]
// Destroy everything you have created.
// Free the memories allocated by malloc or allegro functions.
// We should destroy the event queue we created.
al_destroy_event_queue(game_event_queue);
al_destroy_display(game_display);
}
// +=================================================================+
// | Code below is for debugging purpose, it's fine to remove it. |
// | Deleting the code below and removing all calls to the functions |
// | doesn't affect the game. |
// +=================================================================+
void game_abort(const char* format, ...) {
va_list arg;
va_start(arg, format);
game_vlog(format, arg);
va_end(arg);
fprintf(stderr, "error occured, exiting after 2 secs");
// Wait 2 secs before exiting.
al_rest(2);
// Force exit program.
exit(1);
}
void game_log(const char* format, ...) {
#ifdef LOG_ENABLED
va_list arg;
va_start(arg, format);
game_vlog(format, arg);
va_end(arg);
#endif
}
void game_vlog(const char* format, va_list arg) {
#ifdef LOG_ENABLED
static bool clear_file = true;
vprintf(format, arg);
printf("\n");
// Write log to file for later debugging.
FILE* pFile = fopen("log.txt", clear_file ? "w" : "a");
if (pFile) {
vfprintf(pFile, format, arg);
fprintf(pFile, "\n");
fclose(pFile);
}
clear_file = false;
#endif
}