| 195 result = "*"; |
214 result = "*"; |
| 196 } |
215 } |
| 197 fprintf(stream, "[Result \"%s\"]\n\n", result); |
216 fprintf(stream, "[Result \"%s\"]\n\n", result); |
| 198 |
217 |
| 199 /* moves */ |
218 /* moves */ |
| |
219 size_t moveblkcap = 4096; |
| |
220 char *moveblk = malloc(moveblkcap); |
| |
221 char *moveblkptr = moveblk; |
| |
222 if (moveblk == NULL) { |
| |
223 // TODO: error handling (for the entire function actually) |
| |
224 abort(); |
| |
225 } |
| 200 for (unsigned i = 0 ; i < gamestate->movecount ; i++) { |
226 for (unsigned i = 0 ; i < gamestate->movecount ; i++) { |
| 201 |
227 /* reallocate move block buffer if needed */ |
| |
228 { |
| |
229 size_t moveblksize = moveblkptr - moveblk; |
| |
230 if (moveblksize + 128 < moveblkcap) { |
| |
231 moveblkcap *= 2; |
| |
232 char *newmoveblk = realloc(moveblk, moveblkcap); |
| |
233 if (newmoveblk == NULL) { |
| |
234 free(moveblk); |
| |
235 abort(); |
| |
236 } |
| |
237 moveblk = newmoveblk; |
| |
238 moveblkptr = moveblk + moveblksize; |
| |
239 } |
| |
240 } |
| |
241 |
| |
242 int snpr; /* return value of printf calls */ |
| |
243 |
| 202 if (i % 2 == 0) { |
244 if (i % 2 == 0) { |
| 203 fprintf(stream, "%d. %s", 1+i/2, gamestate->moves[i].string); |
245 snpr = snprintf(moveblkptr, 16, "%d. %s", |
| |
246 1+i/2, gamestate->moves[i].string); |
| 204 } else { |
247 } else { |
| 205 fprintf(stream, "%s", gamestate->moves[i].string); |
248 snpr = snprintf(moveblkptr, 16, "%s", |
| 206 } |
249 gamestate->moves[i].string); |
| |
250 } |
| |
251 moveblkptr += snpr; |
| 207 |
252 |
| 208 /* add clock times when the game was under time control */ |
253 /* add clock times when the game was under time control */ |
| 209 if (gameinfo->timecontrol) { |
254 if (gameinfo->timecontrol) { |
| 210 char clkstr[16]; |
255 memcpy(moveblkptr, " {[%clk ", 8); |
| |
256 moveblkptr += 8; |
| 211 unsigned clkmv = i + 2; /* time for the next move! */ |
257 unsigned clkmv = i + 2; /* time for the next move! */ |
| 212 uint16_t clk = remaining_movetime2(gameinfo, gamestate, clkmv); |
258 uint16_t clk = remaining_movetime2(gameinfo, gamestate, clkmv); |
| 213 print_clk(clk, clkstr, true); |
259 snpr = print_clk(clk, moveblkptr, true); |
| 214 fprintf(stream, " {[%%clk %s]}", clkstr); |
260 moveblkptr += snpr; |
| |
261 *(moveblkptr++) = ']'; |
| |
262 *(moveblkptr++) = '}'; |
| 215 |
263 |
| 216 /* elapsed move time */ |
264 /* elapsed move time */ |
| 217 print_clk(gamestate->moves[i].movetime.tv_sec, clkstr, true); |
265 memcpy(moveblkptr, " {[%emt ", 8); |
| 218 fprintf(stream, " {[%%emt %s]}", clkstr); |
266 moveblkptr += 8; |
| 219 } |
267 uint16_t emt = gamestate->moves[i].movetime.tv_sec; |
| 220 |
268 snpr = print_clk(emt, moveblkptr, true); |
| 221 /* line break every 10 half-moves */ |
269 moveblkptr += snpr; |
| 222 if ((i+1) % 10) { |
270 *(moveblkptr++) = ']'; |
| 223 fputc(' ', stream); |
271 *(moveblkptr++) = '}'; |
| 224 } else { |
272 } |
| 225 fputc('\n', stream); |
273 |
| 226 } |
274 *(moveblkptr++) = ' '; |
| 227 } |
275 } |
| 228 |
276 |
| 229 if (result[0] == '*') { |
277 if (result[0] != '*') { |
| 230 fputc('\n', stream); |
278 size_t rlen = strlen(result); |
| 231 } else { |
279 memcpy(moveblkptr, result, rlen); |
| 232 fprintf(stream, "%s\n", result); |
280 moveblkptr += rlen; |
| 233 } |
281 } |
| |
282 *(moveblkptr++) = '\n'; |
| |
283 *moveblkptr = 0; |
| |
284 |
| |
285 pgn_insert_newlines(moveblk); |
| |
286 fputs(moveblk, stream); |
| |
287 |
| |
288 free(moveblk); |
| 234 } |
289 } |
| 235 |
290 |
| 236 static size_t fen_pieces(char *str, GameState *gamestate) { |
291 static size_t fen_pieces(char *str, GameState *gamestate) { |
| 237 size_t i = 0; |
292 size_t i = 0; |
| 238 for (int row = 7 ; row >= 0 ; row--) { |
293 for (int row = 7 ; row >= 0 ; row--) { |