1 /*
2 * Portions of this file are copyright Rebirth contributors and licensed as
3 * described in COPYING.txt.
4 * Portions of this file are copyright Parallax Software and licensed
5 * according to the Parallax license below.
6 * See COPYING.txt for license details.
7
8 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
9 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
10 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
11 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
12 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
13 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
14 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
15 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
16 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
17 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
18 */
19
20 /*
21 *
22 * Autosave system:
23 * Saves current mine to disk to prevent loss of work, and support undo.
24 *
25 */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <math.h>
31 #include <string.h>
32 #include <time.h>
33
34 #include "dxxerror.h"
35
36 #include "inferno.h"
37 #include "editor.h"
38 #include "u_mem.h"
39 #include "ui.h"
40 #include "strutil.h"
41
42 #include "compiler-cf_assert.h"
43
44 namespace dcx {
45
46 #define AUTOSAVE_PERIOD 5 // Number of minutes for timed autosave
47
48 int Autosave_count;
49
50 namespace {
51
52 static int Autosave_numfiles;
53 static int Autosave_total;
54 static int undo_count;
55
set_autosave_name(mine_filename_type & out,const std::array<char,PATH_MAX> & in,const unsigned i)56 const char *set_autosave_name(mine_filename_type &out, const std::array<char, PATH_MAX> &in, const unsigned i)
57 {
58 d_strupr(out, in);
59 char *ext;
60 #define DXX_AUTOSAVE_MINE_EXTENSION ".MIN"
61 if (!strcmp(out.data(), "*" DXX_AUTOSAVE_MINE_EXTENSION))
62 {
63 #define DXX_DEFAULT_AUTOSAVE_MINE_NAME "TEMP" DXX_AUTOSAVE_MINE_EXTENSION
64 strcpy(out.data(), DXX_DEFAULT_AUTOSAVE_MINE_NAME);
65 ext = &out[sizeof(DXX_DEFAULT_AUTOSAVE_MINE_NAME) - sizeof(DXX_AUTOSAVE_MINE_EXTENSION)];
66 }
67 else
68 {
69 ext = strstr(out.data(), DXX_AUTOSAVE_MINE_EXTENSION);
70 if (!ext)
71 return ext;
72 }
73 #undef DXX_AUTOSAVE_MINE_EXTENSION
74 cf_assert(i < 10);
75 snprintf(ext + 2, 3, "%u", i);
76 return ext;
77 }
78
79 static int Timer_save_flag;
80
81 }
82 int Autosave_flag;
83
84 std::array<const char *, 10> undo_status;
85
init_autosave(void)86 void init_autosave(void) {
87 // int i;
88
89 Autosave_count = 0;
90 Autosave_numfiles = 0;
91 Autosave_flag = 0;
92 undo_count = 0;
93 autosave_mine(mine_filename);
94 }
95
close_autosave(void)96 void close_autosave(void) {
97 const unsigned t = Autosave_total;
98 cf_assert(t < 10);
99 for (unsigned i = 0; i < t; ++i)
100 {
101 mine_filename_type delname;
102 if (set_autosave_name(delname, mine_filename, i))
103 PHYSFS_delete(delname.data());
104 }
105 }
106
autosave_mine(const std::array<char,PATH_MAX> & name)107 void autosave_mine(const std::array<char, PATH_MAX> &name)
108 {
109 if (Autosave_flag) {
110 mine_filename_type savename;
111 if (!set_autosave_name(savename, name, Autosave_count))
112 return;
113
114 med_save_mine( savename );
115 Autosave_count++;
116 if (undo_count > 0) undo_count--;
117 if (Autosave_count > 9) Autosave_count -= 10;
118 if (Autosave_numfiles < 10)
119 Autosave_numfiles++;
120 if (Autosave_total < 10)
121 Autosave_total++;
122 }
123 }
124
125 tm Editor_time_of_day;
126
print_clock(grs_canvas & canvas,const grs_font & cv_font)127 static void print_clock(grs_canvas &canvas, const grs_font &cv_font)
128 {
129 gr_set_fontcolor(canvas, CBLACK, CGREY);
130 std::array<char, 20> message;
131 if (!strftime(message.data(), message.size(), "%m-%d %H:%M:%S", &Editor_time_of_day))
132 message[0] = 0;
133 const auto &&[w, h] = gr_get_string_size(cv_font, message.data());
134 const auto color = CGREY;
135 gr_rect(canvas, 700, 0, 799, h + 1, color);
136 gr_string(canvas, cv_font, 700, 0, message.data(), w, h);
137 gr_set_fontcolor(canvas, CBLACK, CWHITE);
138 }
139
set_editor_time_of_day()140 void set_editor_time_of_day()
141 {
142 time_t ltime;
143
144 time( <ime );
145 Editor_time_of_day = *localtime( <ime );
146 }
147
TimedAutosave(const std::array<char,PATH_MAX> & name)148 void TimedAutosave(const std::array<char, PATH_MAX> &name)
149 {
150 auto &canvas = grd_curscreen->sc_canvas;
151 gr_set_current_canvas(canvas);
152 {
153 print_clock(canvas, *canvas.cv_font);
154 }
155
156
157 #ifndef DEMO
158 const auto &minute = Editor_time_of_day.tm_min;
159 if (minute%AUTOSAVE_PERIOD != 0)
160 Timer_save_flag = 1;
161
162 if ((minute%AUTOSAVE_PERIOD == 0) && (Timer_save_flag)) {
163 time_t ltime;
164
165 autosave_mine(name);
166 Timer_save_flag = 0;
167 time( <ime );
168 diagnostic_message_fmt("Mine Autosaved at %s\n", ctime(<ime));
169 }
170 #endif
171
172 }
173
174
undo(void)175 int undo( void ) {
176 Int3();
177 return 2;
178 }
179
180
181 }
182