src/object_writer.cc

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

mercurial