diff --git a/CREDITS.md b/CREDITS.md
index 1e7f5c61f..841da4fc0 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -5,7 +5,7 @@ Programming
Resources
=========
-LinLibertine.ttf
+LinLibertine_R.ttf
The Libertine Font Project - http://www.linuxlibertine.org/
PugiXML
@@ -14,11 +14,8 @@ PugiXML
SDL 1.2
http://www.libsdl.org/
-SDL TTF
- http://www.libsdl.org/projects/SDL_ttf/
+FreeImage
+ http://www.freeimage.sourceforge.net
-SDL_image
- http://www.libsdl.org/projects/SDL_image/
-
-SDL_gfx
- http://sourceforge.net/projects/sdlgfx/
+FreeType
+ http://www.freetype.org
diff --git a/README.md b/README.md
index ca5212373..bfc0885d8 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,22 @@
EmulationStation
================
-A simple front-end for emulators made with SDL, designed for controller navigation. Developed for use with the Raspberry Pi and RetroArch, though it can easily be used for other things.
+A graphical front-end for emulators with controller navigation. Developed both on and for the Raspbery Pi. Intended for use with RetroArch, but it can easily be used with other emulators.
RetroArch for the Raspberry Pi can be found here: https://github.com/ToadKing/RetroArch-Rpi
I'm not associated with RetroArch in any way!
-If you're lazy, a cool guy named petrockblog made a script which automatically installs RetroArch, its cores, and ES: https://github.com/petrockblog/RetroPie-Setup
+A cool guy named petrockblog made a script which automatically installs RetroArch, its cores, and ES. It also includes options for configuring your RPi and setting it up to boot directly into ES. You can find it here: https://github.com/petrockblog/RetroPie-Setup
Building
========
-EmulationStation has quite a few dependencies. For building, you'll need SDL 1.2, the SDL TTF library, the SDL image library, the SDL_gfx library, and Boost.Filesystem, which can easily be obtained with apt-get:
+EmulationStation has a few dependencies. For building, you'll need SDL 1.2, FreeImage, FreeType, and Boost.Filesystem, which can easily be obtained with apt-get:
```
-sudo apt-get install libsdl1.2-dev libsdl-ttf2.0-dev libboost-filesystem-dev libsdl-image1.2-dev libsdl-gfx1.2-dev
+sudo apt-get install libsdl1.2-dev libboost-filesystem-dev libfreeimage-dev libfreetype6-dev
```
-You can build EmulationStation by simply running `make`.
+There are also a few libraries already on the RPi (located in /opt/vc/, like the Broadcom libraries, EGL, and GLES). You can build EmulationStation by simply running `make`.
Configuring
===========
@@ -53,12 +53,12 @@ The path element should be the absolute path of the ROM. Special characters SHOU
The switch `--gamelist-only` can be used to skip automatic searching, and only display games defined in the system's gamelist.xml.
-A cool guy named Pendor made a scraper which automatically generates a gamelist.xml for you, with boxart automatically downloaded: https://github.com/jpzapa/ES-thegamesdb-scraper
+**Making a gamelist.xml by hand sucks, so a cool guy named Pendor made a python script which automatically generates a gamelist.xml for you, with boxart automatically downloaded. I highly recommend it. It can be found here:** https://github.com/elpendor/ES-scraper
Themes
======
-If you want to know more about themes, read THEMES.md!
+By default, EmulationStation looks pretty ugly. You can fix that. If you want to know more, read THEMES.md!
-Aloshi
diff --git a/THEMES.md b/THEMES.md
index 0189cf2fb..5837ee1eb 100644
--- a/THEMES.md
+++ b/THEMES.md
@@ -50,8 +50,6 @@ Used to display an image.
`` - if present, the image is tiled instead of resized. Tiling isn't exact at the moment, but good enough for backgrounds.
-`` - if present, the image will not be stripped of its alpha channel. It will render much slower, but should have transparency.
-
Display tags
============
diff --git a/changelog.txt b/changelog.txt
index c0a9e16e9..265a33909 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,6 @@
+September 3
+-Everything is now rendered with OpenGL, leading to a (roughly) 600%+ speedup!
+
August 13
-Tons of new theming features!
-I've added a THEMES.md file for documentation on theming.
diff --git a/src/Font.cpp b/src/Font.cpp
index ff0ad3616..df0889cf7 100644
--- a/src/Font.cpp
+++ b/src/Font.cpp
@@ -13,7 +13,7 @@ void Font::initLibrary()
{
if(FT_Init_FreeType(&sLibrary))
{
- std::cout << "Error initializing FreeType!\n";
+ std::cerr << "Error initializing FreeType!\n";
}
}
@@ -23,7 +23,7 @@ Font::Font(std::string path, int size)
if(FT_New_Face(sLibrary, path.c_str(), 0, &face))
{
- std::cout << "Error creating font face! (path: " << path.c_str() << "\n";
+ std::cerr << "Error creating font face! (path: " << path.c_str() << "\n";
while(true);
}
@@ -100,9 +100,6 @@ void Font::buildAtlas()
{
x = 0;
y += maxHeight;
-
- std::cout << "looping to next row, maxHeight: " << maxHeight << std::endl;
-
maxHeight = 0;
}
@@ -128,8 +125,7 @@ void Font::buildAtlas()
glBindTexture(GL_TEXTURE_2D, 0);
- std::cout << "generated texture \"" << textureID << "\" (w: " << w << " h: " << h << ")" << std::endl;
- std::cout << "(final x: " << x << " y: " << y << ")" << std::endl;
+ //std::cout << "generated texture \"" << textureID << "\" (w: " << w << " h: " << h << ")" << std::endl;
}
Font::~Font()
@@ -174,7 +170,8 @@ void Font::drawText(std::string text, int startx, int starty, int color)
starty += mMaxGlyphHeight;
//padding (another 0.5% is added to the bottom through the sizeText function)
- starty += Renderer::getScreenHeight() * 0.005;
+ //starty += Renderer::getScreenHeight() * 0.01;
+ starty += mMaxGlyphHeight * 0.1;
int pointCount = text.length() * 2;
@@ -200,7 +197,7 @@ void Font::drawText(std::string text, int startx, int starty, int color)
float y = starty;
for(; p < pointCount; i++, p++)
{
- int letter = text[i];
+ unsigned char letter = text[i];
if(letter < 32 || letter >= 128)
continue;
@@ -257,7 +254,11 @@ void Font::sizeText(std::string text, int* w, int* h)
int cwidth = 0;
for(unsigned int i = 0; i < text.length(); i++)
{
- cwidth += charData[(int)text[i]].advX;
+ unsigned char letter = text[i];
+ if(letter < 32 || letter >= 128)
+ continue;
+
+ cwidth += charData[letter].advX;
}
@@ -265,5 +266,5 @@ void Font::sizeText(std::string text, int* w, int* h)
*w = cwidth;
if(h != NULL)
- *h = mMaxGlyphHeight + Renderer::getScreenWidth() * 0.01;
+ *h = mMaxGlyphHeight + mMaxGlyphHeight * 0.5;
}
diff --git a/src/GuiComponent.cpp b/src/GuiComponent.cpp
index 6cbfafa0a..4f805d6ac 100644
--- a/src/GuiComponent.cpp
+++ b/src/GuiComponent.cpp
@@ -78,3 +78,22 @@ void GuiComponent::resume()
mChildren.at(i)->resume();
}
+void GuiComponent::init()
+{
+ onInit();
+
+ for(unsigned int i = 0; i < mChildren.size(); i++)
+ {
+ mChildren.at(i)->init();
+ }
+}
+
+void GuiComponent::deinit()
+{
+ onDeinit();
+
+ for(unsigned int i = 0; i < mChildren.size(); i++)
+ {
+ mChildren.at(i)->deinit();
+ }
+}
diff --git a/src/GuiComponent.h b/src/GuiComponent.h
index 7bc38e575..9ae56960f 100644
--- a/src/GuiComponent.h
+++ b/src/GuiComponent.h
@@ -20,6 +20,11 @@ public:
virtual void onPause() { };
virtual void onResume() { };
+ void init();
+ void deinit();
+ virtual void onInit() { };
+ virtual void onDeinit() { };
+
virtual void onInput(InputManager::InputButton button, bool keyDown) { };
void addChild(GuiComponent* comp);
diff --git a/src/Renderer.cpp b/src/Renderer.cpp
index 14e0b8905..909f5ad4f 100644
--- a/src/Renderer.cpp
+++ b/src/Renderer.cpp
@@ -36,3 +36,19 @@ void Renderer::render()
renderVector.at(i)->render();
}
}
+
+void Renderer::onInit()
+{
+ for(unsigned int i = 0; i < renderVector.size(); i++)
+ {
+ renderVector.at(i)->init();
+ }
+}
+
+void Renderer::onDeinit()
+{
+ for(unsigned int i = 0; i < renderVector.size(); i++)
+ {
+ renderVector.at(i)->deinit();
+ }
+}
diff --git a/src/Renderer.h b/src/Renderer.h
index 7f5a2fa6c..ac90cd7d8 100644
--- a/src/Renderer.h
+++ b/src/Renderer.h
@@ -14,7 +14,9 @@ namespace Renderer
void deleteAll();
bool init(int w, int h);
+ void onInit();
void deinit();
+ void onDeinit();
void render();
diff --git a/src/Renderer_draw_gl.cpp b/src/Renderer_draw_gl.cpp
index 5ff23187f..de1012383 100644
--- a/src/Renderer_draw_gl.cpp
+++ b/src/Renderer_draw_gl.cpp
@@ -2,6 +2,7 @@
#include
#include
#include "Font.h"
+#include
namespace Renderer {
bool loadedFonts = false;
@@ -63,10 +64,23 @@ namespace Renderer {
{
std::cout << "loading fonts\n";
- unsigned int fontSizes[] = {10, 12, 22};
+ std::string fontPath = "LinLibertine_R.ttf";
+
+ //make sure our font exists
+ if(!boost::filesystem::exists(fontPath))
+ {
+ std::cout << "Default font \"" << fontPath << "\" does not exist! Attempting to default to a system font...\n";
+ fontPath = "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf";
+ if(!boost::filesystem::exists(fontPath))
+ {
+ std::cerr << "System font \"" << fontPath << "\" wasn't found either! Well, you're kind of screwed. Sorry.\n";
+ }
+ }
+
+ float fontSizes[] = {0.004, 0.006, 0.009};
for(unsigned int i = 0; i < 3; i++)
{
- fonts[i] = new Font("LinLibertine_R.ttf", fontSizes[i]);
+ fonts[i] = new Font(fontPath, (unsigned int)(fontSizes[i] * getScreenWidth()));
}
loadedFonts = true;
@@ -108,6 +122,9 @@ namespace Renderer {
if(!loadedFonts)
loadFonts();
+ if(x < 0)
+ std::cout << "drawing at " << x << std::endl;
+
getFont(font)->drawText(text, x, y, color);
}
diff --git a/src/Renderer_init_rpi.cpp b/src/Renderer_init_rpi.cpp
index 155c504e9..20df9ed37 100644
--- a/src/Renderer_init_rpi.cpp
+++ b/src/Renderer_init_rpi.cpp
@@ -1,3 +1,4 @@
+#include "Renderer.h"
#include
#include
#include
@@ -71,7 +72,6 @@ namespace Renderer
std::cerr << "Error choosing config!\n";
return false;
}
- std::cout << "numConfigs: " << numConfigs << "\n";
context = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);
@@ -97,7 +97,7 @@ namespace Renderer
}
}
- std::cout << "Display size is " << display_width << "x" << display_height << "\n";
+ std::cout << "Display size is " << display_width << "x" << display_height << ".\n";
dst_rect.x = 0; dst_rect.y = 0;
@@ -133,7 +133,7 @@ namespace Renderer
}
- std::cout << "success!\n";
+ std::cout << "Success!\n";
return true;
}
@@ -151,12 +151,14 @@ namespace Renderer
eglDestroySurface(display, surface);
eglDestroyContext(display, context);
eglTerminate(display);
+
+ display = EGL_NO_DISPLAY;
+ surface = EGL_NO_SURFACE;
+ context = EGL_NO_CONTEXT;
}
bool init(int w, int h)
{
- bcm_host_init();
-
if(w)
display_width = w;
if(h)
@@ -173,14 +175,17 @@ namespace Renderer
glOrthof(0, display_width, display_height, 0, -1.0, 1.0);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ onInit();
+
return true;
}
- void unloadFonts();
+ void unloadFonts(); //defined in Renderer_draw_gl.cpp
void deinit()
{
+ onDeinit();
+
unloadFonts();
destroySurface();
- bcm_host_deinit();
}
};
diff --git a/src/SystemData.cpp b/src/SystemData.cpp
index 54e0e1030..b199a90b3 100644
--- a/src/SystemData.cpp
+++ b/src/SystemData.cpp
@@ -167,7 +167,6 @@ void SystemData::loadConfig()
lineValid = true;
varName = line.substr(0, i);
varValue = line.substr(i + 1, line.length() - 1);
- std::cout << " " << varName << " = " << varValue << "\n";
break;
}
}
@@ -184,7 +183,7 @@ void SystemData::loadConfig()
else if(varName == "COMMAND")
sysCommand = varValue;
//else
- // std::cerr << "Error reading config file - unknown variable name \"" << varName << "\"!\n";
+ // std::cout << "Warning reading config file - unknown variable name \"" << varName << "\", ignoring.\n";
//we have all our variables - create the system object
if(!sysName.empty() && !sysPath.empty() &&!sysExtension.empty() && !sysCommand.empty())
diff --git a/src/components/GuiGameList.cpp b/src/components/GuiGameList.cpp
index dd2974aa2..f0daecd0b 100644
--- a/src/components/GuiGameList.cpp
+++ b/src/components/GuiGameList.cpp
@@ -95,7 +95,7 @@ void GuiGameList::onRender()
ss << FRAMERATE;
std::string fps;
ss >> fps;
- Renderer::drawText(fps, 100, 0, 0x00FF00);
+ Renderer::drawText(fps, 100, 50, 0x00FF00);
#endif
//header
@@ -235,3 +235,13 @@ void GuiGameList::onResume()
{
InputManager::registerComponent(this);
}
+
+void GuiGameList::onDeinit()
+{
+ mTheme->deinit();
+}
+
+void GuiGameList::onInit()
+{
+ mTheme->onInit();
+}
diff --git a/src/components/GuiGameList.h b/src/components/GuiGameList.h
index e2456b82c..88f9d4aa6 100644
--- a/src/components/GuiGameList.h
+++ b/src/components/GuiGameList.h
@@ -25,6 +25,8 @@ public:
void onInput(InputManager::InputButton button, bool keyDown);
void onPause();
void onResume();
+ void onInit();
+ void onDeinit();
static const float sInfoWidth;
private:
diff --git a/src/components/GuiImage.cpp b/src/components/GuiImage.cpp
index 2e344376d..ec07ef5f5 100644
--- a/src/components/GuiImage.cpp
+++ b/src/components/GuiImage.cpp
@@ -25,7 +25,6 @@ GuiImage::GuiImage(int offsetX, int offsetY, std::string path, unsigned int resi
mResizeHeight = resizeHeight;
mResizeExact = resizeExact;
- mUseAlpha = false;
if(!path.empty())
setImage(path);
@@ -45,6 +44,10 @@ void GuiImage::loadImage(std::string path)
return;
}
+ //make sure we don't already have an image
+ unloadImage();
+
+
FREE_IMAGE_FORMAT format = FIF_UNKNOWN;
FIBITMAP* image = NULL;
BYTE* imageData = NULL;
@@ -64,9 +67,7 @@ void GuiImage::loadImage(std::string path)
//make sure we can read this filetype first, then load it
if(FreeImage_FIFSupportsReading(format))
{
- std::cout << "Loading image...";
image = FreeImage_Load(format, path.c_str());
- std::cout << "success\n";
}else{
std::cerr << "Error - file format reading not supported for image \"" << path << "\"!\n";
return;
@@ -162,14 +163,13 @@ void GuiImage::loadImage(std::string path)
mHeight *= resizeScaleY;
}
- std::cout << "Image load successful, w: " << mWidth << " h: " << mHeight << " texID: " << mTextureID << "\n";
+ //std::cout << "Image load successful, w: " << mWidth << " h: " << mHeight << " texID: " << mTextureID << "\n";
}
void GuiImage::unloadImage()
{
if(mTextureID)
{
- std::cout << "deleting texture\n";
glDeleteTextures(1, &mTextureID);
mTextureID = 0;
@@ -203,11 +203,6 @@ void GuiImage::setTiling(bool tile)
mResizeExact = false;
}
-void GuiImage::setAlpha(bool useAlpha)
-{
- mUseAlpha = useAlpha;
-}
-
void GuiImage::onRender()
{
if(mTextureID)
@@ -232,6 +227,7 @@ void GuiImage::drawImage(int posX, int posY)
glBindTexture(GL_TEXTURE_2D, mTextureID);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GLfloat points[12];
points[0] = posX - (mWidth * mOriginX); points[1] = posY - (mHeight * mOriginY);
@@ -269,3 +265,16 @@ void GuiImage::drawImage(int posX, int posY)
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
}
+
+void GuiImage::onInit()
+{
+ if(!mPath.empty())
+ {
+ loadImage(mPath);
+ }
+}
+
+void GuiImage::onDeinit()
+{
+ unloadImage();
+}
diff --git a/src/components/GuiImage.h b/src/components/GuiImage.h
index feee6a0f5..81400b0ee 100644
--- a/src/components/GuiImage.h
+++ b/src/components/GuiImage.h
@@ -15,17 +15,19 @@ public:
void setImage(std::string path);
void setOrigin(float originX, float originY);
void setTiling(bool tile);
- void setAlpha(bool useAlpha);
int getWidth();
int getHeight();
void onRender();
+ void onInit();
+ void onDeinit();
+
private:
unsigned int mResizeWidth, mResizeHeight;
float mOriginX, mOriginY;
- bool mResizeExact, mTiled, mUseAlpha;
+ bool mResizeExact, mTiled;
void loadImage(std::string path);
void drawImage(int x, int y);
diff --git a/src/components/GuiTheme.cpp b/src/components/GuiTheme.cpp
index 0c5e29ebf..d4ebc0aa4 100644
--- a/src/components/GuiTheme.cpp
+++ b/src/components/GuiTheme.cpp
@@ -114,7 +114,6 @@ GuiComponent* GuiTheme::createElement(pugi::xml_node data, GuiComponent* parent)
std::string dim = data.child("dim").text().get();
std::string origin = data.child("origin").text().get();
- bool useAlpha = data.child("useAlpha");
bool tiled = data.child("tiled");
//split position and dimension information
@@ -127,7 +126,7 @@ GuiComponent* GuiTheme::createElement(pugi::xml_node data, GuiComponent* parent)
std::string originX, originY;
splitString(origin, ' ', &originX, &originY);
- std::cout << "image, x: " << posX << " y: " << posY << " w: " << dimW << " h: " << dimH << " ox: " << originX << " oy: " << originY << " alpha: " << useAlpha << " tiled: " << tiled << "\n";
+ std::cout << "image, x: " << posX << " y: " << posY << " w: " << dimW << " h: " << dimH << " ox: " << originX << " oy: " << originY << " tiled: " << tiled << "\n";
//resolve to pixels from percentages/variables
int x = resolveExp(posX) * Renderer::getScreenWidth();
@@ -142,7 +141,6 @@ GuiComponent* GuiTheme::createElement(pugi::xml_node data, GuiComponent* parent)
GuiImage* comp = new GuiImage(x, y, "", w, h, true);
comp->setOrigin(ox, oy);
- comp->setAlpha(useAlpha);
comp->setTiling(tiled);
comp->setImage(path);
diff --git a/src/main.cpp b/src/main.cpp
index 32522fb12..bbc651caf 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -5,6 +5,7 @@
#include
#include "components/GuiInputConfig.h"
#include
+#include
bool PARSEGAMELISTONLY = false;
bool IGNOREGAMELIST = false;
@@ -17,6 +18,8 @@ namespace fs = boost::filesystem;
int main(int argc, char* argv[])
{
+ bcm_host_init();
+
bool running = true;
//by the way, if anyone ever tries to port this to a different renderer but leave SDL as input -
@@ -187,5 +190,8 @@ int main(int argc, char* argv[])
std::cout << "EmulationStation cleanly shutting down...\n";
SDL_Quit();
+
+ bcm_host_deinit();
+
return 0;
}