format urealtime.realtime as " D days, H hours, M minutes and S seconds" with any fields having a value of 0 omitted: 0-00:00:20 => " 20 seconds" 0-00:15:05 => " 15 minutes and 5 seconds" 0-00:16:00 => " 16 minutes" 0-01:15:10 => " 1 hour, 15 minutes and 10 seconds" 0-02:00:01 => " 2 hours and 1 second" 3-00:25:40 => " 3 days, 25 minutes and 40 seconds"
| 311 | [style-wise] optional comma before "and" but in this instance it does not) |
| 312 | */ |
| 313 | staticfn char * |
| 314 | fmt_elapsed_time(char *outbuf, int final) |
| 315 | { |
| 316 | int fieldcnt; |
| 317 | long edays, ehours, eminutes, eseconds; |
| 318 | /* for a game that's over, reallydone() has updated urealtime.realtime |
| 319 | to its final value before calling us during end of game disclosure; |
| 320 | for a game that's still in progress, it holds the amount of elapsed |
| 321 | game time from previous sessions up through most recent save/restore |
| 322 | (or up through latest level change when 'checkpoint' is On); |
| 323 | '.start_timing' has a non-zero value even if '.realtime' is 0 */ |
| 324 | long etim = urealtime.realtime; |
| 325 | |
| 326 | if (!final) |
| 327 | etim += timet_delta(getnow(), urealtime.start_timing); |
| 328 | /* we could use localtime() to convert the value into a 'struct tm' |
| 329 | to get date and time fields but this is simple and straightforward */ |
| 330 | eseconds = etim % 60L, etim /= 60L; |
| 331 | eminutes = etim % 60L, etim /= 60L; |
| 332 | ehours = etim % 24L; |
| 333 | edays = etim / 24L; |
| 334 | fieldcnt = !!edays + !!ehours + !!eminutes + !!eseconds; |
| 335 | |
| 336 | Strcpy(outbuf, fieldcnt ? "" : " none"); /* 'none' should never happen */ |
| 337 | if (edays) { |
| 338 | Sprintf(eos(outbuf), " %ld day%s", edays, plur(edays)); |
| 339 | if (fieldcnt > 1) /* hours and/or minutes and/or seconds to follow */ |
| 340 | Strcat(outbuf, (fieldcnt == 2) ? " and" : ","); |
| 341 | --fieldcnt; /* edays has been processed */ |
| 342 | } |
| 343 | if (ehours) { |
| 344 | Sprintf(eos(outbuf), " %ld hour%s", ehours, plur(ehours)); |
| 345 | if (fieldcnt > 1) /* minutes and/or seconds to follow */ |
| 346 | Strcat(outbuf, (fieldcnt == 2) ? " and" : ","); |
| 347 | --fieldcnt; /* ehours has been processed */ |
| 348 | } |
| 349 | if (eminutes) { |
| 350 | Sprintf(eos(outbuf), " %ld minute%s", eminutes, plur(eminutes)); |
| 351 | if (fieldcnt > 1) /* seconds to follow */ |
| 352 | Strcat(outbuf, " and"); |
| 353 | /* eminutes has been processed but no need to decrement fieldcnt */ |
| 354 | } |
| 355 | if (eseconds) |
| 356 | Sprintf(eos(outbuf), " %ld second%s", eseconds, plur(eseconds)); |
| 357 | return outbuf; |
| 358 | } |
| 359 | |
| 360 | /* "once" vs "twice" vs "17 times", used in several places */ |
| 361 | staticfn char * |
no test coverage detected