1 /*
2 * Schism Tracker - a cross-platform Impulse Tracker clone
3 * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
4 * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
5 * copyright (c) 2009 Storlek & Mrs. Brisby
6 * copyright (c) 2010-2012 Storlek
7 * URL: http://schismtracker.org/
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #define NEED_TIME
25 #include "headers.h"
26 #include "it.h"
27 #include "sdlmain.h"
28 #include "version.h"
29
30
31 #define TOP_BANNER_CLASSIC "Impulse Tracker v2.14 Copyright (C) 1995-1998 Jeffrey Lim"
32
33 /* written by ver_init */
34 static char top_banner_normal[80];
35
36 /*
37 Lower 12 bits of the CWTV field in IT and S3M files.
38
39 "Proper" version numbers went the way of the dodo, but we can't really fit an eight-digit date stamp directly
40 into a twelve-bit number. Since anything < 0x50 already carries meaning (even though most of them weren't
41 used), we have 0xfff - 0x50 = 4015 possible values. By encoding the date as an offset from a rather arbitrarily
42 chosen epoch, there can be plenty of room for the foreseeable future.
43
44 < 0x020: a proper version (files saved by such versions are likely very rare)
45 = 0x020: any version between the 0.2a release (2005-04-29?) and 2007-04-17
46 = 0x050: anywhere from 2007-04-17 to 2009-10-31 (version was updated to 0x050 in hg changeset 2f6bd40c0b79)
47 > 0x050: the number of days since 2009-10-31, for example:
48 0x051 = (0x051 - 0x050) + 2009-10-31 = 2009-11-01
49 0x052 = (0x052 - 0x050) + 2009-10-31 = 2009-11-02
50 0x14f = (0x14f - 0x050) + 2009-10-31 = 2010-07-13
51 0xffe = (0xfff - 0x050) + 2009-10-31 = 2020-10-27
52 = 0xfff: a non-value indicating a date after 2020-10-27. in this case, the full version number is stored in a reserved header field.
53 this field follows the same format, using the same epoch, but without adding 0x50. */
54 unsigned short ver_cwtv;
55 unsigned short ver_reserved;
56
57 /* these should be 50 characters or shorter, as they are used in the startup dialog */
58 const char *ver_short_copyright =
59 "Copyright (c) 2003-2019 Storlek, Mrs. Brisby et al.";
60 const char *ver_short_based_on =
61 "Based on Impulse Tracker by Jeffrey Lim aka Pulse";
62
63 /* SEE ALSO: helptext/copyright (contains full copyright information, credits, and GPL boilerplate) */
64
65 static time_t epoch_sec;
66
67
schism_banner(int classic)68 const char *schism_banner(int classic)
69 {
70 return (classic
71 ? TOP_BANNER_CLASSIC
72 : top_banner_normal);
73 }
74
75 /*
76 Information at our disposal:
77
78 VERSION
79 "" or "YYYYMMDD"
80 A date here is the date of the last commit from git
81 empty string will happen if git isn't installed, or no .git
82
83 __DATE__ "Jun 3 2009"
84 __TIME__ "23:39:19"
85 __TIMESTAMP__ "Wed Jun 3 23:39:19 2009"
86 These are annoying to manipulate beacuse of the month being in text format -- but at
87 least I don't think they're ever localized, which would make it much more annoying.
88 Should always exist, especially considering that we require gcc. However, it is a
89 poor indicator of the age of the *code*, since it depends on the clock of the computer
90 that's building the code, and also there is the possibility that someone was hanging
91 onto the code for a really long time before building it.
92
93 */
94
get_version_tm(struct tm * version)95 static int get_version_tm(struct tm *version)
96 {
97 char *ret;
98
99 memset(version, 0, sizeof(*version));
100 ret = strptime(VERSION, "%Y %m %d", version);
101 if (ret && !*ret)
102 return 1;
103 /* Argh. */
104 memset(version, 0, sizeof(*version));
105 ret = strptime(__DATE__, "%b %e %Y", version);
106 if (ret && !*ret)
107 return 1;
108 /* Give up; we don't know anything. */
109 return 0;
110 }
111
ver_init(void)112 void ver_init(void)
113 {
114 struct tm version, epoch = { .tm_year = 109, .tm_mon = 9, .tm_mday = 31 }; /* 2009-10-31 */
115 time_t version_sec;
116 char ver[32] = VERSION;
117
118 if (get_version_tm(&version)) {
119 version_sec = mktime(&version);
120 } else {
121 printf("help, I am very confused about myself\n");
122 version_sec = epoch_sec;
123 }
124
125 epoch_sec = mktime(&epoch);
126 version_sec = mktime(&version);
127 ver_cwtv = 0x050 + (version_sec - epoch_sec) / 86400;
128 ver_reserved = ver_cwtv < 0xfff ? 0 : (ver_cwtv - 0x050);
129 ver_cwtv = CLAMP(ver_cwtv, 0x050, 0xfff);
130
131 /* show build date if we don't know last commit date (no git) */
132 if (ver[0]) {
133 snprintf(top_banner_normal, sizeof(top_banner_normal) - 1,
134 "Schism Tracker %s", ver);
135 } else {
136 snprintf(top_banner_normal, sizeof(top_banner_normal) - 1,
137 "Schism Tracker built %s %s", __DATE__, __TIME__);
138 }
139
140 top_banner_normal[sizeof(top_banner_normal) - 1] = '\0'; /* to be sure */
141 }
142
ver_decode_cwtv(uint16_t cwtv,uint32_t reserved,char * buf)143 void ver_decode_cwtv(uint16_t cwtv, uint32_t reserved, char *buf)
144 {
145 struct tm version;
146 time_t version_sec;
147
148 cwtv &= 0xfff;
149 if (cwtv > 0x050) {
150 // Annoyingly, mktime uses local time instead of UTC. Why etc.
151 version_sec = ((cwtv < 0xfff ? (cwtv - 0x050) : reserved) * 86400) + epoch_sec;
152 if (localtime_r(&version_sec, &version)) {
153 sprintf(buf, "%04d-%02d-%02d",
154 version.tm_year + 1900, version.tm_mon + 1, version.tm_mday);
155 return;
156 }
157 }
158 sprintf(buf, "0.%x", cwtv);
159 }
160
161