Maelstrom: Added the first XML screen - the splash screen!

From 33f995157303299a7d89d0be7abed0caebffba1a Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 22 Oct 2011 18:07:50 -0400
Subject: [PATCH] Added the first XML screen - the splash screen!

---
 Makefile.am                |  4 ++++
 UIElementTexture.cpp       | 33 +++++++++++++++++++++++++++++++++
 UIElementTexture.h         | 21 +++++++++++++++++++++
 UIElementTitle.cpp         | 29 +++++++++++++++++++++++++++++
 UIElementTitle.h           | 15 +++++++++++++++
 UIElements.cpp             |  5 +++++
 init.cpp                   | 13 ++++---------
 screenlib/SDL_FrameBuf.cpp |  2 ++
 screenlib/UIArea.cpp       |  6 +++---
 screenlib/UIElement.cpp    |  1 +
 screenlib/UIElement.h      |  6 +++---
 screenlib/UIPanel.cpp      |  8 +++++---
 screenlib/UIPanel.h        |  4 +++-
 splash.xml                 |  7 +++++++
 14 files changed, 135 insertions(+), 19 deletions(-)
 create mode 100644 UIElementTexture.cpp
 create mode 100644 UIElementTexture.h
 create mode 100644 UIElementTitle.cpp
 create mode 100644 UIElementTitle.h
 create mode 100644 splash.xml

diff --git a/Makefile.am b/Makefile.am
index 8c541214..1722fb99 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -29,6 +29,10 @@ Maelstrom_SOURCES =		\
 	rect.h			\
 	scores.cpp		\
 	scores.h		\
+	UIElementTexture.cpp	\
+	UIElementTexture.h	\
+	UIElementTitle.cpp	\
+	UIElementTitle.h	\
 	UIElements.cpp		\
 	UIElements.h
 
diff --git a/UIElementTexture.cpp b/UIElementTexture.cpp
new file mode 100644
index 00000000..89a61f19
--- /dev/null
+++ b/UIElementTexture.cpp
@@ -0,0 +1,33 @@
+
+#include "UIElementTexture.h"
+#include "screenlib/SDL_FrameBuf.h"
+
+
+UIElementTexture::UIElementTexture(UIPanel *panel, const char *name) :
+	UIElement(panel, name)
+{
+	m_texture = NULL;
+}
+
+UIElementTexture::~UIElementTexture()
+{
+	if (m_texture) {
+		m_screen->FreeImage(m_texture);
+	}
+}
+
+void
+UIElementTexture::SetTexture(SDL_Texture *texture)
+{
+	m_texture = texture;
+	m_rect.w = m_screen->GetImageWidth(texture);
+	m_rect.h = m_screen->GetImageHeight(texture);
+}
+
+void
+UIElementTexture::Draw()
+{
+	if (m_texture) {
+		m_screen->QueueBlit(m_rect.x, m_rect.y, m_texture, NOCLIP);
+	}
+}
diff --git a/UIElementTexture.h b/UIElementTexture.h
new file mode 100644
index 00000000..25538df7
--- /dev/null
+++ b/UIElementTexture.h
@@ -0,0 +1,21 @@
+#ifndef _UIElementTexture_h
+#define _UIElementTexture_h
+
+#include "screenlib/UIElement.h"
+
+
+class UIElementTexture : public UIElement
+{
+public:
+	UIElementTexture(UIPanel *panel, const char *name = "");
+	virtual ~UIElementTexture();
+
+	void SetTexture(SDL_Texture *texture);
+
+	virtual void Draw();
+
+private:
+	SDL_Texture *m_texture;
+};
+
+#endif // _UIElementTexture_h
diff --git a/UIElementTitle.cpp b/UIElementTitle.cpp
new file mode 100644
index 00000000..de815249
--- /dev/null
+++ b/UIElementTitle.cpp
@@ -0,0 +1,29 @@
+
+#include "UIElementTitle.h"
+#include "load.h"
+
+UIElementTitle::UIElementTitle(UIPanel *panel, const char *name) :
+	UIElementTexture(panel, name)
+{
+}
+
+bool
+UIElementTitle::Load(rapidxml::xml_node<> *node)
+{
+	rapidxml::xml_attribute<> *attr;
+
+	attr = node->first_attribute("id", 0, false);
+	if (!attr) {
+		SetError("Element 'Title' missing attribute 'id'");
+		return false;
+	}
+
+	SDL_Texture *texture = Load_Title(m_screen, atoi(attr->value()));
+	if (!texture) {
+		SetError("Unable to load title %d", atoi(attr->value()));
+		return false;
+	}
+	SetTexture(texture);
+
+	return UIElementTexture::Load(node);
+}
diff --git a/UIElementTitle.h b/UIElementTitle.h
new file mode 100644
index 00000000..6a29782c
--- /dev/null
+++ b/UIElementTitle.h
@@ -0,0 +1,15 @@
+#ifndef _UIElementTitle_h
+#define _UIElementTitle_h
+
+#include "UIElementTexture.h"
+
+
+class UIElementTitle : public UIElementTexture
+{
+public:
+	UIElementTitle(UIPanel *panel, const char *name = "");
+
+	virtual bool Load(rapidxml::xml_node<> *node);
+};
+
+#endif // _UIElementTitle_h
diff --git a/UIElements.cpp b/UIElements.cpp
index 7079d8a9..0f8843bf 100644
--- a/UIElements.cpp
+++ b/UIElements.cpp
@@ -1,8 +1,13 @@
 
 #include "UIElements.h"
+#include "UIElementTitle.h"
+
 
 UIElement *
 CreateMaelstromUIElement(UIPanel *panel, const char *name)
 {
+	if (strcasecmp(name, "Title") == 0) {
+		return new UIElementTitle(panel);
+	}
 	return NULL;
 }
diff --git a/init.cpp b/init.cpp
index 5e112af2..23b3d4f2 100644
--- a/init.cpp
+++ b/init.cpp
@@ -64,18 +64,13 @@ static int LoadSmallSprite(Mac_Resource *spriteres,
 /* Put up an Ambrosia Software splash screen */
 void DoSplash(void)
 {
-	SDL_Texture *splash;
+	UIPanel panel(screen);
 
-	splash = Load_Title(screen, 999);
-	if ( splash == NULL ) {
-		error("Can't load Ambrosia splash title! (ID=%d)\n", 999);
-		return;
-        }
 	screen->Clear();
-	screen->QueueBlit(SCREEN_WIDTH/2-screen->GetImageWidth(splash)/2,
-			  SCREEN_HEIGHT/2-screen->GetImageHeight(splash)/2, splash, NOCLIP);
+	if (panel.Load("splash.xml")) {
+		panel.Draw();
+	}
 	screen->Update();
-	screen->FreeImage(splash);
 }
 
 /* ----------------------------------------------------------------- */
diff --git a/screenlib/SDL_FrameBuf.cpp b/screenlib/SDL_FrameBuf.cpp
index 9e97ba20..0108e8e8 100644
--- a/screenlib/SDL_FrameBuf.cpp
+++ b/screenlib/SDL_FrameBuf.cpp
@@ -130,6 +130,8 @@ FrameBuf:: QueueBlit(int dstx, int dsty, SDL_Texture *src,
 void
 FrameBuf:: Fade(void)
 {
+// Temporary for development
+return;
 	const int max = 32;
 	Uint16 ramp[256];   
 
diff --git a/screenlib/UIArea.cpp b/screenlib/UIArea.cpp
index 2bc188f3..f12086f2 100644
--- a/screenlib/UIArea.cpp
+++ b/screenlib/UIArea.cpp
@@ -94,7 +94,7 @@ UIArea::Load(rapidxml::xml_node<> *node)
 		AnchorLocation anchorTo = TOPLEFT;
 		int x, y;
 
-		attr = node->first_attribute("anchorElement", 0, false);
+		attr = child->first_attribute("anchorElement", 0, false);
 		anchorElement = GetAnchorElement(attr ? attr->value() : NULL);
 		if (!anchorElement) {
 			SetError("Element 'anchor' couldn't find anchor element %s",
@@ -102,11 +102,11 @@ UIArea::Load(rapidxml::xml_node<> *node)
 			return false;
 		}
 
-		attr = node->first_attribute("anchorFrom", 0, false);
+		attr = child->first_attribute("anchorFrom", 0, false);
 		if (attr) {
 			anchorFrom = ParseAnchorLocation(attr->value());
 		}
-		attr = node->first_attribute("anchorTo", 0, false);
+		attr = child->first_attribute("anchorTo", 0, false);
 		if (attr) {
 			anchorTo = ParseAnchorLocation(attr->value());
 		}
diff --git a/screenlib/UIElement.cpp b/screenlib/UIElement.cpp
index 9417d8f1..6b43892a 100644
--- a/screenlib/UIElement.cpp
+++ b/screenlib/UIElement.cpp
@@ -28,6 +28,7 @@ UIElement::UIElement(UIPanel *panel, const char *name) : UIArea()
 	m_name = new char[strlen(name)+1];
 	strcpy(m_name, name);
 
+	m_screen = panel->GetScreen();
 	m_panel = panel;
 }
 
diff --git a/screenlib/UIElement.h b/screenlib/UIElement.h
index 6719c7e8..a83a9015 100644
--- a/screenlib/UIElement.h
+++ b/screenlib/UIElement.h
@@ -27,7 +27,6 @@
 
 #include "../utils/rapidxml.h"
 
-#include "ErrorBase.h"
 #include "UIArea.h"
 
 class FrameBuf;
@@ -43,15 +42,16 @@ class UIElement : public UIArea
 		return m_name;
 	}
 
-	bool Load(rapidxml::xml_node<> *node);
+	virtual bool Load(rapidxml::xml_node<> *node);
 
 	virtual UIArea *GetAnchorElement(const char *name);
 
-	virtual void Draw(FrameBuf *) { }
+	virtual void Draw() { }
 	virtual bool HandleEvent(const SDL_Event &event) { return false; }
 
 protected:
 	char *m_name;
+	FrameBuf *m_screen;
 	UIPanel *m_panel;
 };
 
diff --git a/screenlib/UIPanel.cpp b/screenlib/UIPanel.cpp
index 930ab3d1..317843ec 100644
--- a/screenlib/UIPanel.cpp
+++ b/screenlib/UIPanel.cpp
@@ -89,13 +89,14 @@ UIPanel::Load(const char *file)
 
 	rapidxml::xml_node<> *node = doc.first_node();
 	rapidxml::xml_node<> *child;
+	rapidxml::xml_attribute<> *attr;
 	if (strcmp(node->name(), "UIPanel") != 0) {
 		SetError("Parse error: UIPanel root element expected");
 		delete[] buffer;
 		return false;
 	}
-	child = node->first_node("name", 0, false);
-	if (child) {
+	attr = node->first_attribute("name", 0, false);;
+	if (attr) {
 		const char *name = node->value();
 		delete[] m_name;
 		m_name = new char[strlen(name)+1];
@@ -132,6 +133,7 @@ UIPanel::LoadElements(rapidxml::xml_node<> *node)
 		}
 		AddElement(element);
 	}
+	return true;
 }
 
 UIArea *
@@ -159,7 +161,7 @@ UIPanel::Draw()
 {
 	for (unsigned i = 0; i < m_elements.length(); ++i) {
 		if (m_elements[i]->IsShown()) {
-			m_elements[i]->Draw(m_screen);
+			m_elements[i]->Draw();
 		}
 	}
 }
diff --git a/screenlib/UIPanel.h b/screenlib/UIPanel.h
index 9624c22a..681f7893 100644
--- a/screenlib/UIPanel.h
+++ b/screenlib/UIPanel.h
@@ -28,7 +28,6 @@
 #include "../utils/rapidxml.h"
 #include "../utils/array.h"
 
-#include "ErrorBase.h"
 #include "UIArea.h"
 
 class FrameBuf;
@@ -48,6 +47,9 @@ class UIPanel : public UIArea
 	UIPanel(FrameBuf *screen, const char *name = "");
 	virtual ~UIPanel();
 
+	FrameBuf *GetScreen() const {
+		return m_screen;
+	}
 	const char *GetName() const {
 		return m_name;
 	}
diff --git a/splash.xml b/splash.xml
new file mode 100644
index 00000000..3da06b90
--- /dev/null
+++ b/splash.xml
@@ -0,0 +1,7 @@
+<UIPanel>
+	<Elements>
+		<Title id="999">
+			<Anchor anchorFrom="CENTER" anchorTo="CENTER"/>
+		</Title>
+	</Elements>
+</UIPanel>