OSDN Git Service

README-jp.txtのBOMを削除した
[starfighter-jp/starfighter-jp.git] / src / engine.cpp
1 /*
2 Copyright (C) 2003 Parallel Realities
3 Copyright (C) 2011, 2012, 2013 Guus Sliepen
4 Copyright (C) 2015, 2016 onpon4 <onpon4@riseup.net>
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 3
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "Starfighter.h"
21
22 #include <sys/types.h>
23 #include <pwd.h>
24 #include <unistd.h>
25 #include <errno.h>
26
27 Engine engine;
28
29 void engine_init()
30 {
31         engine.musicVolume = 100;
32         engine.useAudio = true;
33
34         engine.maxAliens = 9;
35
36         engine.ssx = 0;
37         engine.ssy = 0;
38         engine.smx = 0;
39         engine.smy = 0;
40
41         engine.bulletHead = new object;
42         engine.bulletHead->next = NULL;
43         engine.bulletTail = engine.bulletHead;
44
45         engine.explosionHead = new object;
46         engine.explosionHead->next = NULL;
47         engine.explosionTail = engine.explosionHead;
48
49         engine.collectableHead = new collectables;
50         engine.collectableHead->next = NULL;
51         engine.collectableTail = engine.collectableHead;
52
53         engine.debrisHead = new object;
54         engine.debrisHead->next = NULL;
55         engine.debrisTail = engine.debrisHead;
56
57         engine.commsSection = 0;
58
59         for (int i = 0; i < KEY_LAST; i++)
60                 engine.keyState[i] = 0;
61
62         engine.eventTimer = 0;
63         engine.counter2 = 0;
64         engine.timeTaken = 0;
65         engine.timeMission = 0;
66         engine.counter = 0;
67         engine.seconds = 0;
68         engine.minutes = 0;
69         engine.paused = false;
70         engine.gameSection = SECTION_TITLE;
71
72         engine.cheat = false;
73         engine.cheatShield = false;
74         engine.cheatAmmo = false;
75         engine.cheatCash = false;
76 }
77
78 /*
79 Something went wrong. This stops the game, present the error message and
80 prompts the user to press space or ctrl to exit the game. This is unlikely to
81 be seen by people unless something really stoopid happens!
82 */
83 void engine_showError(int errorId, const char *name)
84 {
85         screen_clear(black);
86
87         if (errorId != 2)
88         {
89                 screen_renderString("A file error has occurred", -1, 200, FONT_RED);
90         }
91         else
92         {
93                 printf("Couldn't create or write to directory '%s'\n", name);
94                 exit(1);
95         }
96
97         char string[255];
98
99         switch(errorId)
100         {
101                 case 0:
102                         sprintf(string, "%s was not found in the Starfighter data package", name);
103                         screen_renderString(string, -1, 250, FONT_WHITE);
104                         screen_renderString("Please try again. If this error persists, contact the authors", -1, 275, FONT_WHITE);
105                         screen_renderString("or reinstall the game", -1, 300, FONT_WHITE);
106                         break;
107                 case 1:
108                         screen_renderString("Project: Starfighter encountered an error whilst", -1, 250, FONT_WHITE);
109                         screen_renderString("attempting to load game data. Please try running", -1, 275, FONT_WHITE);
110                         screen_renderString("the game again. If the errors persist, reinstall the game", -1, 300, FONT_WHITE);
111                         break;
112                 case 2:
113                         screen_renderString("Project: Starfighter encountered a critical error", -1, 250, FONT_WHITE);
114                         screen_renderString("while attempting to perform a required program function.", -1, 275, FONT_WHITE);
115                         screen_renderString("Please contact the authors with details.", -1, 300, FONT_WHITE);
116                         break;
117         }
118
119         screen_renderString("Project: Starfighter will now exit", -1, 450, FONT_WHITE);
120         screen_renderString("Press Space to continue", -1, 475, FONT_WHITE);
121
122         renderer_update();
123
124         engine.keyState[KEY_ALTFIRE] = 0;
125
126         while (!engine.keyState[KEY_ALTFIRE])
127         {
128                 getPlayerInput();
129                 game_delayFrame();
130         }
131
132         exit(1);
133 }
134
135 /*
136 This gets the user's home directory, then creates the config directory.
137 */
138 void engine_setupConfigDirectory()
139 {
140         const char *userHome;
141
142         if ((userHome = getenv("HOME")) == NULL)
143                 userHome = getpwuid(getuid())->pw_dir;
144
145         char dir[PATH_MAX];
146         strcpy(dir, "");
147
148         sprintf(dir, "%s/.config", userHome);
149         if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
150                 engine_showError(2, dir);
151
152         sprintf(dir, "%s/.config/starfighter", userHome);
153         if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
154                 engine_showError(2, dir);
155
156         sprintf(engine.configDirectory, "%s/.config/starfighter/", userHome);
157 }
158
159 /*
160 This sets up the video and sound system, and creates Starfighter's window.
161 */
162 void engine_setMode()
163 {
164         strcpy(engine.configDirectory, "");
165
166         engine_setupConfigDirectory();
167
168         /* Initialize the SDL library */
169         if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_JOYSTICK) < 0)
170         {
171                 printf("Couldn't initialize SDL: %s\n", SDL_GetError());
172                 exit(1);
173         }
174
175         char filename[PATH_MAX];
176         int fullScreen = 0;
177         int useSound = 1;
178         int useMusic = 1;
179         int autoPause = 0;
180
181         FILE *fp;
182         sprintf(filename, "%sconf", engine.configDirectory);
183         fp = fopen(filename, "rb");
184
185         if (fp != NULL)
186         {
187                 if (fscanf(fp, "%d %d %d %d", &fullScreen, &useSound, &useMusic, &autoPause) < 4)
188                         printf("Warning: Config file \"%s\" is not correctly formatted\n", filename);
189                 fclose(fp);
190         }
191
192         engine.fullScreen = fullScreen;
193         engine.useSound = useSound;
194         engine.useMusic = useMusic;
195         engine.autoPause = autoPause;
196
197         screen = SDL_CreateRGBSurface(0, screenWidth, screenHeight, 32, 0xff0000, 0xff00, 0xff, 0xff000000);
198
199         if (!screen)
200         {
201                 printf("Couldn't create %ix%ix32 surface: %s\n", screenWidth, screenHeight, SDL_GetError());
202                 exit(1);
203         }
204
205         window = SDL_CreateWindow("Project: Starfighter", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen->w, screen->h, 0);
206
207         if (window == NULL)
208         {
209                 printf("Could not create window: %s\n", SDL_GetError());
210                 exit(1);
211         }
212
213         SDL_SetWindowIcon(window, gfx_loadImage("gfx/alienDevice.png"));
214         SDL_SetWindowFullscreen(window, engine.fullScreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
215
216         renderer = SDL_CreateRenderer(window, -1, 0);
217
218         if (!renderer)
219         {
220                 printf("Could not create renderer: %s\n", SDL_GetError());
221                 exit(1);
222         }
223
224         SDL_RenderSetLogicalSize(renderer, screen->w, screen->h);
225
226         renderer_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, screen->w, screen->h);
227
228         if (!renderer_texture)
229         {
230                 printf("Couldn't create %ix%ix32 texture: %s\n", screen->w, screen->h, SDL_GetError());
231                 exit(1);
232         }
233
234         if (engine.useAudio)
235         {
236                 if (Mix_OpenAudio(44100, AUDIO_S16, engine.useAudio * 2, 1024) < 0)
237                 {
238                         printf("Warning: Couldn't set 44100 Hz 16-bit stereo audio - Reason:\n%s\n", Mix_GetError());
239                         printf("Sound and Music will be disabled\n");
240                         engine.useAudio = false;
241                 }
242         }
243
244         SDL_ShowCursor(SDL_DISABLE);
245         SDL_EventState(SDL_MOUSEMOTION, SDL_DISABLE);
246
247         SDL_JoystickEventState(SDL_ENABLE);
248         SDL_JoystickOpen(0);
249 }
250
251 /*
252 Removes [hopefully] all the resources that has been
253 loaded and created during the game. This is called by
254 atexit();
255 */
256 void engine_cleanup()
257 {
258         gfx_free();
259         SDL_FreeSurface(gfx_background);
260         audio_free();
261         resetLists();
262         delete(engine.bulletHead);
263         delete(engine.explosionHead);
264         delete(engine.collectableHead);
265         delete(screen_bufferHead);
266
267         for (int i = 0 ; i < FONT_MAX ; i++)
268         {
269                 if (gfx_fontSprites[i] != NULL)
270                         SDL_FreeSurface(gfx_fontSprites[i]);
271         }
272
273         char filename[PATH_MAX];
274         strcpy(filename, "");
275         
276         sprintf(filename, "%smusic.mod", engine.configDirectory);
277         remove(filename);
278
279         sprintf(filename, "%smusic.s3m", engine.configDirectory);
280         remove(filename);
281
282         if (engine.useAudio)
283         {
284                 Mix_CloseAudio();
285         }
286
287         // Save the config using current settings
288         FILE *fp;
289         sprintf(filename, "%sconf", engine.configDirectory);
290         fp = fopen(filename, "wb");
291         if (fp != NULL)
292         {
293                 fprintf(fp, "%d %d %d %d\n", engine.fullScreen, engine.useSound,
294                         engine.useMusic, engine.autoPause);
295                 fclose(fp);
296         }
297         else
298         {
299                 printf("Error saving config\n");
300         }
301
302         SDL_Quit();
303         printf("Thank You for playing Starfighter\n");
304 }