Fixed reinitialization problems with the renderer.

This commit is contained in:
Aloshi 2012-09-04 11:45:16 -05:00
parent 07d8046a3e
commit cac43474aa
18 changed files with 144 additions and 55 deletions

View file

@ -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

View file

@ -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

View file

@ -50,8 +50,6 @@ Used to display an image.
`<tiled />` - if present, the image is tiled instead of resized. Tiling isn't exact at the moment, but good enough for backgrounds.
`<useAlpha />` - if present, the image will not be stripped of its alpha channel. It will render much slower, but should have transparency.
Display tags
============

View file

@ -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.

View file

@ -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;
}

View file

@ -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();
}
}

View file

@ -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);

View file

@ -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();
}
}

View file

@ -14,7 +14,9 @@ namespace Renderer
void deleteAll();
bool init(int w, int h);
void onInit();
void deinit();
void onDeinit();
void render();

View file

@ -2,6 +2,7 @@
#include <GLES/gl.h>
#include <iostream>
#include "Font.h"
#include <boost/filesystem.hpp>
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);
}

View file

@ -1,3 +1,4 @@
#include "Renderer.h"
#include <bcm_host.h>
#include <iostream>
#include <bcm_host.h>
@ -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();
}
};

View file

@ -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())

View file

@ -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();
}

View file

@ -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:

View file

@ -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();
}

View file

@ -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);

View file

@ -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);

View file

@ -5,6 +5,7 @@
#include <boost/filesystem.hpp>
#include "components/GuiInputConfig.h"
#include <SDL.h>
#include <bcm_host.h>
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;
}