src/object_writer.cc

changeset 75
bf8c57437231
child 77
ad17801b1a36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/object_writer.cc	Mon Jan 13 23:44:15 2014 +0200
@@ -0,0 +1,191 @@
+/*
+	Copyright (c) 2012-2014, Santeri Piippo
+	All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are met:
+
+		* Redistributions of source code must retain the above copyright
+		  notice, this list of conditions and the following disclaimer.
+
+		* Redistributions in binary form must reproduce the above copyright
+		  notice, this list of conditions and the following disclaimer in the
+		  documentation and/or other materials provided with the distribution.
+
+		* Neither the name of the <organization> nor the
+		  names of its contributors may be used to endorse or promote products
+		  derived from this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+	ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+	DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+	DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "main.h"
+#include "object_writer.h"
+#include "data_buffer.h"
+#include "stringtable.h"
+
+extern bool g_GotMainLoop;
+
+object_writer::object_writer()
+{
+	MainBuffer = new data_buffer;
+	MainLoopBuffer = new data_buffer;
+	OnEnterBuffer = new data_buffer;
+	SwitchBuffer = null; // created on demand
+	numWrittenBytes = 0;
+	numWrittenReferences = 0;
+}
+
+void object_writer::write_string (string a)
+{
+	write (a.length());
+
+	for (int i = 0; i < a.length(); i++)
+		write (a[i]);
+}
+
+void object_writer::write_buffer (data_buffer* buf)
+{
+	get_current_buffer()->merge (buf);
+}
+
+void object_writer::write_member_buffers()
+{
+	// If there was no mainloop defined, write a dummy one now.
+	if (!g_GotMainLoop)
+	{
+		MainLoopBuffer->write (dh_main_loop);
+		MainLoopBuffer->write (dh_end_main_loop);
+	}
+
+	// Write the onenter and mainloop buffers, IN THAT ORDER
+	for (int i = 0; i < 2; i++)
+	{
+		data_buffer** buf = (!i) ? &OnEnterBuffer : &MainLoopBuffer;
+		write_buffer (*buf);
+
+		// Clear the buffer afterwards for potential next state
+		*buf = new data_buffer;
+	}
+
+	// Next state definitely has no mainloop yet
+	g_GotMainLoop = false;
+}
+
+// Write string table
+void object_writer::write_string_table()
+{
+	int stringcount = num_strings_in_table();
+
+	if (!stringcount)
+		return;
+
+	// Write header
+	write (dh_string_list);
+	write (stringcount);
+
+	// Write all strings
+	for (int a = 0; a < stringcount; a++)
+		write_string (get_string_table()[a]);
+}
+
+// Write main buffer to file
+void object_writer::write_to_file (string filepath)
+{
+	fp = fopen (filepath, "w");
+	CHECK_FILE (fp, filepath, "writing");
+
+	// First, resolve references
+	numWrittenReferences = 0;
+
+	for (int u = 0; u < MAX_MARKS; u++)
+	{
+		ScriptMarkReference* ref = MainBuffer->refs[u];
+
+		if (!ref)
+			continue;
+
+		// Substitute the placeholder with the mark position
+		generic_union<word> uni;
+		uni.as_word = static_cast<word> (MainBuffer->marks[ref->num]->pos);
+
+		for (int v = 0; v < (int) sizeof (word); v++)
+			memset (MainBuffer->buffer + ref->pos + v, uni.as_bytes[v], 1);
+
+		/*
+		printf ("reference %u at %d resolved to %u at %d\n",
+			u, ref->pos, ref->num, MainBuffer->marks[ref->num]->pos);
+		*/
+		numWrittenReferences++;
+	}
+
+	// Then, dump the main buffer to the file
+	for (int x = 0; x < MainBuffer->writesize; x++)
+		write_data_to_file<byte> (*(MainBuffer->buffer + x));
+
+	print ("-- %1 byte%s1 written to %2\n", numWrittenBytes, filepath);
+	fclose (fp);
+}
+
+data_buffer* object_writer::get_current_buffer()
+{
+	return	SwitchBuffer ? SwitchBuffer :
+			(g_CurMode == MODE_MAINLOOP) ? MainLoopBuffer :
+			(g_CurMode == MODE_ONENTER) ? OnEnterBuffer :
+			MainBuffer;
+}
+
+ScriptMark* g_ScriptMark = null;
+
+// Adds a mark
+int object_writer::add_mark (string name)
+{
+	return get_current_buffer()->add_mark (name);
+}
+
+// Adds a reference
+int object_writer::add_reference (int mark)
+{
+	data_buffer* b = get_current_buffer();
+	return b->add_reference (mark);
+}
+
+// Finds a mark
+int object_writer::find_byte_mark (string name)
+{
+	data_buffer* b = get_current_buffer();
+
+	for (int u = 0; u < MAX_MARKS; u++)
+	{
+		if (b->marks[u] && b->marks[u]->name.to_uppercase() == name.to_uppercase())
+			return u;
+	}
+
+	return MAX_MARKS;
+}
+
+// Moves a mark to the current position
+void object_writer::move_mark (int mark)
+{
+	get_current_buffer()->move_mark (mark);
+}
+
+// Deletes a mark
+void object_writer::delete_mark (int mark)
+{
+	get_current_buffer()->delete_mark (mark);
+}
+
+void object_writer::offset_mark (int mark, int offset)
+{
+	get_current_buffer()->offset_mark (mark, offset);
+}

mercurial