-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
168 lines (153 loc) · 5.63 KB
/
main.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// #include "src/include/toml.h"
// #include "src/include/control.h"
#include "control.h"
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include <SDL2/SDL_mixer.h>
int main(int argc, char const *argv[])
{
// SDL系統初始化
if (SDL_Init(SDL_INIT_EVERYTHING))
{
printf("SDL_Init failed: %s\n", SDL_GetError());
return 1;
}
if (TTF_Init())
{
printf("TTF_Init failed: %s\n", TTF_GetError());
return 1;
}
// 建立視窗
SDL_Window *GameWindow = SDL_CreateWindow("Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, 0);
// 建立渲染器
// SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
SDL_Renderer *renderer = SDL_CreateRenderer(GameWindow, -1, SDL_RENDERER_ACCELERATED);
// 啟用透明(alpha值)材質
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
// 載入字體
gFontDefault = TTF_OpenFont("assets/fonts/kaiu.ttf", 30);
// 圖形介面排版初始化 (建立各個物件需要用的方框)
// scene顯示方框
// dialogue顯示方框
// 文字 ?檢查文字大小、行數
// 物品
// 頭像
// 立繪
// 當前scene的路徑
SDL_Event event;
int32_t game_is_running = 1;
setCentre(&gRectBackground, &gRectDialogue);
setCentre(&gRectBackground, &gRectTachie);
gRectText.w = gRectDialogue.w - 30;
setCentre(&gRectDialogue, &gRectText);
gRectAvatar.x = gRectDialogue.x + 5;
gRectAvatarFrame.x = gRectDialogue.x;
gRectAvatar.y = gRectDialogue.y + gRectDialogue.h - gRectAvatar.h - 5;
gRectAvatarFrame.y = gRectDialogue.y + gRectDialogue.h - gRectAvatarFrame.h;
gRectNext.x = gRectDialogue.x + gRectDialogue.w - gRectNext.w;
gRectNext.y = gRectDialogue.y + gRectDialogue.h - gRectNext.h;
// 遊戲資料變數
script_t mainScript = {0};
scriptRead(ScriptPath, &mainScript);
GameSave_t saving = {0};
NEXT_ACTION NextAction = _eEVENT;
// 遊戲主迴圈
while (game_is_running)
{
// # 清除畫面
SDL_RenderClear(renderer);
// 透過遊戲選單選擇,並根據回傳值執行接下來的劇情
int8_t retVal_StartMenu = GameStartMenu(renderer, &mainScript, &saving);
if(retVal_StartMenu == -1 || retVal_StartMenu == EXIT_FAILURE){
printf("Exception: terminate \n");
goto end;
}else if(retVal_StartMenu == _eGAMEQUIT){
game_is_running = 0;
goto end;
}
// 遊戲劇情迴圈
// 退出條件:玩家從選單選擇退出
while (1)
{
SDL_RenderClear(renderer);
switch (NextAction)
{
case _eEVENT:
// # 下一個事件更新並處理
NextAction = eventHandler(renderer, &mainScript, &saving);
break;
case _eDIALOGUE:
// # 下一個對話更新並處理
NextAction = dialogueHandler(renderer, &mainScript, &saving);
break;
case _eENDING:
// # 遊戲結局顯示
// game_is_running = 0;
break;
case _eGAMEQUIT:
// # 遊戲結束
game_is_running = 0;
goto end;
break;
case _eEMPTY:
default:
// # 錯誤發生
fprintf(stderr, "Error in Game Script Loop\n");
fprintf(stderr, "Dialogue at %s \n", toml_table_key(saving.tabCurDialogue));
goto end;
}
// # 音樂播放
// - 背景音樂:如果有切換則切換,若無則繼續播放
// - 音效
// # 畫面繪製
// 繪製圖像
// 物品
// description
// 背景
DisplayImg(renderer, TOML_USE_STRING(toml_string_in(toml_table_in(mainScript.scene, TOML_USE_STRING(saving.nowScene.scene)), "background")), NULL, &gRectBackground); //
// 立繪
// DisplayImg(renderer, TOML_USE_STRING(toml_string_in(toml_table_in(mainScript.character, TOML_USE_STRING(saving.nowScene.character)), "tachie")), NULL, &gRectAvatar);
// DisplayImg(); // 物品欄
// 角色頭像
// DisplayImg(renderer, TOML_USE_STRING(toml_string_in(toml_table_in(mainScript.character, TOML_USE_STRING(saving.nowScene.character)), "avatar")), NULL, &gRectAvatar);
// DisplayImg(); // 角色頭像邊框
// 繪製文字
// # 聆聽事件(偵測滑鼠/鍵盤輸入) 包含音效 //目前只支援關閉視窗
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
game_is_running = 0;
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
{
game_is_running = 0;
}
break;
}
}
// 點擊選項
// 物品預覽
// # 更新畫面
SDL_RenderPresent(renderer);
}
}
// 程式結束,以相反順序釋放資源
end:
GameSaveWrite(saving.SaveName, &saving);
if (mainScript.rootTable)
toml_free(mainScript.rootTable);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(GameWindow);
TTF_Quit(); // 關閉TTF
SDL_Quit(); // 關閉SDL
return 0;
}