src/object_writer.cc

changeset 75
bf8c57437231
child 77
ad17801b1a36
equal deleted inserted replaced
74:007fbadfa7f9 75:bf8c57437231
1 /*
2 Copyright (c) 2012-2014, Santeri Piippo
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 * Neither the name of the <organization> nor the
16 names of its contributors may be used to endorse or promote products
17 derived from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
23 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "main.h"
32 #include "object_writer.h"
33 #include "data_buffer.h"
34 #include "stringtable.h"
35
36 extern bool g_GotMainLoop;
37
38 object_writer::object_writer()
39 {
40 MainBuffer = new data_buffer;
41 MainLoopBuffer = new data_buffer;
42 OnEnterBuffer = new data_buffer;
43 SwitchBuffer = null; // created on demand
44 numWrittenBytes = 0;
45 numWrittenReferences = 0;
46 }
47
48 void object_writer::write_string (string a)
49 {
50 write (a.length());
51
52 for (int i = 0; i < a.length(); i++)
53 write (a[i]);
54 }
55
56 void object_writer::write_buffer (data_buffer* buf)
57 {
58 get_current_buffer()->merge (buf);
59 }
60
61 void object_writer::write_member_buffers()
62 {
63 // If there was no mainloop defined, write a dummy one now.
64 if (!g_GotMainLoop)
65 {
66 MainLoopBuffer->write (dh_main_loop);
67 MainLoopBuffer->write (dh_end_main_loop);
68 }
69
70 // Write the onenter and mainloop buffers, IN THAT ORDER
71 for (int i = 0; i < 2; i++)
72 {
73 data_buffer** buf = (!i) ? &OnEnterBuffer : &MainLoopBuffer;
74 write_buffer (*buf);
75
76 // Clear the buffer afterwards for potential next state
77 *buf = new data_buffer;
78 }
79
80 // Next state definitely has no mainloop yet
81 g_GotMainLoop = false;
82 }
83
84 // Write string table
85 void object_writer::write_string_table()
86 {
87 int stringcount = num_strings_in_table();
88
89 if (!stringcount)
90 return;
91
92 // Write header
93 write (dh_string_list);
94 write (stringcount);
95
96 // Write all strings
97 for (int a = 0; a < stringcount; a++)
98 write_string (get_string_table()[a]);
99 }
100
101 // Write main buffer to file
102 void object_writer::write_to_file (string filepath)
103 {
104 fp = fopen (filepath, "w");
105 CHECK_FILE (fp, filepath, "writing");
106
107 // First, resolve references
108 numWrittenReferences = 0;
109
110 for (int u = 0; u < MAX_MARKS; u++)
111 {
112 ScriptMarkReference* ref = MainBuffer->refs[u];
113
114 if (!ref)
115 continue;
116
117 // Substitute the placeholder with the mark position
118 generic_union<word> uni;
119 uni.as_word = static_cast<word> (MainBuffer->marks[ref->num]->pos);
120
121 for (int v = 0; v < (int) sizeof (word); v++)
122 memset (MainBuffer->buffer + ref->pos + v, uni.as_bytes[v], 1);
123
124 /*
125 printf ("reference %u at %d resolved to %u at %d\n",
126 u, ref->pos, ref->num, MainBuffer->marks[ref->num]->pos);
127 */
128 numWrittenReferences++;
129 }
130
131 // Then, dump the main buffer to the file
132 for (int x = 0; x < MainBuffer->writesize; x++)
133 write_data_to_file<byte> (*(MainBuffer->buffer + x));
134
135 print ("-- %1 byte%s1 written to %2\n", numWrittenBytes, filepath);
136 fclose (fp);
137 }
138
139 data_buffer* object_writer::get_current_buffer()
140 {
141 return SwitchBuffer ? SwitchBuffer :
142 (g_CurMode == MODE_MAINLOOP) ? MainLoopBuffer :
143 (g_CurMode == MODE_ONENTER) ? OnEnterBuffer :
144 MainBuffer;
145 }
146
147 ScriptMark* g_ScriptMark = null;
148
149 // Adds a mark
150 int object_writer::add_mark (string name)
151 {
152 return get_current_buffer()->add_mark (name);
153 }
154
155 // Adds a reference
156 int object_writer::add_reference (int mark)
157 {
158 data_buffer* b = get_current_buffer();
159 return b->add_reference (mark);
160 }
161
162 // Finds a mark
163 int object_writer::find_byte_mark (string name)
164 {
165 data_buffer* b = get_current_buffer();
166
167 for (int u = 0; u < MAX_MARKS; u++)
168 {
169 if (b->marks[u] && b->marks[u]->name.to_uppercase() == name.to_uppercase())
170 return u;
171 }
172
173 return MAX_MARKS;
174 }
175
176 // Moves a mark to the current position
177 void object_writer::move_mark (int mark)
178 {
179 get_current_buffer()->move_mark (mark);
180 }
181
182 // Deletes a mark
183 void object_writer::delete_mark (int mark)
184 {
185 get_current_buffer()->delete_mark (mark);
186 }
187
188 void object_writer::offset_mark (int mark, int offset)
189 {
190 get_current_buffer()->offset_mark (mark, offset);
191 }

mercurial