A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007-2009 Joshua Simmons <mud at majidejima dot com>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "game.h"
23#include "types.h"
24#include "board.h"
25#include "goban.h"
26#include "sgf.h"
27#include "sgf_output.h"
28#include "sgf_parse.h"
29#include "sgf_storage.h"
30#include "display.h"
31
32static void pre_game_setup (void);
33
34char save_file[SAVE_FILE_LENGTH];
35bool game_dirty = false; /* flag for unsaved changes */
36bool autosave_dirty = false; /* flag for unsaved changes which haven't even
37 been autosaved yet */
38
39int move_num = 0;
40
41unsigned char current_player = BLACK;
42
43struct header_t header; /* game metadata header info */
44
45void
46set_game_modified (void)
47{
48 game_dirty = true;
49 autosave_dirty = true;
50}
51
52bool
53load_game (const char *filename)
54{
55 rb->memset (&header, 0, sizeof (header));
56
57 if (rb->strlen (filename) + 1 > SAVE_FILE_LENGTH)
58 {
59 DEBUGF ("file name too long\n");
60 return false;
61 }
62
63 if (!rb->file_exists (filename))
64 {
65 DEBUGF ("file doesn't exist!\n");
66 return false;
67 }
68
69 pre_game_setup ();
70
71 rb->strcpy (save_file, filename);
72
73#ifdef HAVE_ADJUSTABLE_CPU_FREQ
74 rb->cpu_boost (true);
75#endif
76
77 rb->splash (0, "Loading...");
78
79 bool parse_failed = false;
80 if (!parse_sgf (save_file))
81 {
82 rb->splash (3 * HZ, "Unable to parse SGF file. Will overwrite.");
83 parse_failed = true;
84 }
85
86 game_dirty = false;
87 autosave_dirty = false;
88
89#ifdef HAVE_ADJUSTABLE_CPU_FREQ
90 rb->cpu_boost (false);
91#endif
92
93 if (header.handicap >= 2)
94 {
95 current_player = WHITE;
96 }
97
98 post_game_setup_sgf ();
99
100 if (!parse_failed)
101 {
102 draw_screen_display();
103 if (rb->strcmp(filename, DEFAULT_SAVE))
104 {
105 metadata_summary();
106 }
107 }
108
109 return true;
110}
111
112
113bool
114save_game (const char *filename)
115{
116 if (rb->strlen (filename) + 1 > SAVE_FILE_LENGTH)
117 {
118 return false;
119 }
120
121 /* We only have to do something if the game is dirty, or we're being
122 asked to save to a different location than we loaded from.
123
124 If the game isn't dirty and we're being asked to save to default,
125 we also don't have to do anything.*/
126 if (!game_dirty &&
127 (rb->strcmp (filename, save_file) == 0 ||
128 rb->strcmp (filename, DEFAULT_SAVE) == 0))
129 {
130 return true;
131 }
132
133#ifdef HAVE_ADJUSTABLE_CPU_FREQ
134 rb->cpu_boost (true);
135#endif
136
137 rb->splash (0, "Saving...");
138
139 if (output_sgf (filename))
140 {
141 /* saving only "cleans" the game if it's not a save to default,
142 * or if our save_file is actually default
143 *
144 * (so autosaves won't prevent legitimate saves to a Save As or
145 * loaded file)
146 */
147 if (rb->strcmp (filename, DEFAULT_SAVE) ||
148 rb->strcmp (save_file, DEFAULT_SAVE) == 0)
149 {
150 game_dirty = false;
151 }
152
153 /* but saving anywhere means that autosave isn't dirty */
154 autosave_dirty = false;
155
156#ifdef HAVE_ADJUSTABLE_CPU_FREQ
157 rb->cpu_boost (false);
158#endif
159 /* The save succeeded. Now, if we saved to an actual file (not to the
160 * DEFAULT_SAVE), then we should delete the DEFAULT_SAVE file because
161 * the changes stored in it are no longer unsaved.
162 */
163 if (rb->strcmp (filename, DEFAULT_SAVE))
164 {
165 rb->remove(DEFAULT_SAVE);
166 }
167
168 return true;
169 }
170 else
171 {
172#ifdef HAVE_ADJUSTABLE_CPU_FREQ
173 rb->cpu_boost (false);
174#endif
175 return false;
176 }
177}
178
179
180static void
181pre_game_setup (void)
182{
183 rb->memset (&header, 0, sizeof (header));
184
185 clear_caches_sgf ();
186 free_tree_sgf ();
187
188 set_size_board (MAX_BOARD_SIZE, MAX_BOARD_SIZE);
189
190 clear_board ();
191
192 game_dirty = true;
193 move_num = 0;
194
195 play_mode = MODE_PLAY;
196
197 rb->strcpy (save_file, DEFAULT_SAVE);
198
199 header_marked = false;
200}
201
202
203bool
204setup_game (int width, int height, int handicap, int komi)
205{
206 pre_game_setup ();
207
208 if (!set_size_board (width, height))
209 {
210 return false;
211 }
212
213 clear_board ();
214
215 /* place handicap */
216 if (handicap >= 2)
217 {
218 current_player = WHITE;
219 }
220 else if (handicap < 0)
221 {
222 return false;
223 }
224 else
225 {
226 current_player = BLACK;
227 }
228
229 header.handicap = handicap;
230 setup_handicap_sgf ();
231
232 header.komi = komi;
233
234 post_game_setup_sgf ();
235
236 return true;
237}