mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 06:05:38 +00:00
Fixed reinitialization problems with the renderer.
This commit is contained in:
parent
07d8046a3e
commit
cac43474aa
13
CREDITS.md
13
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
|
||||
|
|
14
README.md
14
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
|
||||
|
|
|
@ -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
|
||||
============
|
||||
|
|
|
@ -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.
|
||||
|
|
23
src/Font.cpp
23
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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,9 @@ namespace Renderer
|
|||
void deleteAll();
|
||||
|
||||
bool init(int w, int h);
|
||||
void onInit();
|
||||
void deinit();
|
||||
void onDeinit();
|
||||
|
||||
void render();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue